try to fix submodule

This commit is contained in:
2023-11-09 19:02:15 -05:00
parent c1d45aa443
commit deea94b076
366 changed files with 40228 additions and 2 deletions

View File

@@ -0,0 +1,69 @@
# Smoothing Sensor
by [@dekutree64](https://github.com/dekutree64)
A SimpleFOC Sensor wrapper implementation which adds angle extrapolation
Please also see our [forum thread](https://community.simplefoc.com/t/smoothingsensor-experimental-sensor-angle-extrapoltion/3105) on this topic.
SmoothingSensor is a wrapper class which is inserted inbetween a sensor and motor to provide better quality angle readings from sensors that are low resolution or are slow to communicate. It provides no improvement for sensors that are high resolution and quick to update. It uses the timestamp of the last angle reading from the sensor and the low-pass filtered velocity from the motor to predict what the angle should be at the current time.
## Hardware setup
Connect your sensor as usual. Make sure the sensor is working 'normally' i.e. without smoothing first. Once things are working and tuned without smoothing, you can add the SmoothingSensor to see if you get an improvement.
## Softwate setup
The SmoothingSensor acts as a wrapper to the actual sensor class. When creating the SmoothingSensor object, provide the real sensor to the constructor of SmoothingSensor. Initialize the real sensor instance as normal. Then link the SmoothingSensor to the motor and call motor.initFOC().
```c++
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(11);
BLDCDriver3PWM driver = BLDCDriver3PWM(PB4,PC7,PB10,PA9);
// real sensor instance
MagneticSensorPWM sensor = MagneticSensorPWM(2, 4, 904);
// instantiate the smoothing sensor, providing the real sensor as a constructor argument
SmoothingSensor smooth = SmoothingSensor(sensor, motor);
void doPWM(){sensor.handlePWM();}
void setup() {
sensor.init();
sensor.enableInterrupt(doPWM);
// Link motor to sensor
motor.linkSensor(&smooth);
// power supply voltage
driver.voltage_power_supply = 20;
driver.init();
motor.linkDriver(&driver);
// aligning voltage
motor.voltage_sensor_align = 8;
motor.voltage_limit = 20;
// set motion control loop to be used
motor.controller = MotionControlType::torque;
// use monitoring with serial
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);
motor.monitor_variables = _MON_VEL;
motor.monitor_downsample = 10; // default 10
// initialize motor
motor.init();
motor.initFOC();
}
```
## Roadmap
Possible future improvements we've thought about:
- Add extrapolation of acceleration as well
- Switch to open loop control at very low speed with hall sensors, which otherwise move in steps even with smoothing.

View File

@@ -0,0 +1,57 @@
#include "SmoothingSensor.h"
#include "common/foc_utils.h"
#include "common/time_utils.h"
SmoothingSensor::SmoothingSensor(Sensor& s, const FOCMotor& m) : _wrapped(s), _motor(m)
{
}
void SmoothingSensor::update() {
// Update sensor, with optional downsampling of update rate
if(sensor_cnt++ >= sensor_downsample) {
sensor_cnt = 0;
_wrapped.update();
}
// Copy state variables from the sensor
angle_prev = _wrapped.angle_prev;
angle_prev_ts = _wrapped.angle_prev_ts;
full_rotations = _wrapped.full_rotations;
// Perform angle prediction, using low-pass filtered velocity. But don't advance more than
// pi/3 (equivalent to one step of block commutation) from the last true angle reading.
float dt = (_micros() - angle_prev_ts) * 1e-6f;
angle_prev += _motor.sensor_direction * _constrain(_motor.shaft_velocity * dt, -_PI_3 / _motor.pole_pairs, _PI_3 / _motor.pole_pairs);
// Apply phase correction if needed
if (phase_correction != 0) {
if (_motor.shaft_velocity < -0) angle_prev -= _motor.sensor_direction * phase_correction / _motor.pole_pairs;
else if (_motor.shaft_velocity > 0) angle_prev += _motor.sensor_direction * phase_correction / _motor.pole_pairs;
}
// Handle wraparound of the projected angle
if (angle_prev < 0) full_rotations -= 1, angle_prev += _2PI;
else if (angle_prev >= _2PI) full_rotations += 1, angle_prev -= _2PI;
}
float SmoothingSensor::getVelocity() {
return _wrapped.getVelocity();
}
int SmoothingSensor::needsSearch() {
return _wrapped.needsSearch();
}
float SmoothingSensor::getSensorAngle() {
return _wrapped.getSensorAngle();
}
void SmoothingSensor::init() {
_wrapped.init();
}

View File

@@ -0,0 +1,46 @@
#ifndef SMOOTHING_SENSOR_H
#define SMOOTHING_SENSOR_H
#include "Arduino.h"
#include "common/base_classes/FOCMotor.h"
#include "common/base_classes/Sensor.h"
/**
SmoothingSensor is a wrapper class which is inserted inbetween a sensor and motor to provide better
quality angle readings from sensors that are low resolution or are slow to communicate. It provides
no improvement for sensors that are high resolution and quick to update.
It uses the timestamp of the last angle reading from the sensor and the low-pass filtered velocity
from the motor to predict what the angle should be at the current time.
*/
class SmoothingSensor : public Sensor
{
public:
/**
SmoothingSensor class constructor
@param s Wrapped sensor
@param m Motor that the SmoothingSensor will be linked to
*/
SmoothingSensor(Sensor& s, const FOCMotor& m);
void update() override;
float getVelocity() override;
int needsSearch() override;
// For sensors with slow communication, use these to poll less often
unsigned int sensor_downsample = 0; // parameter defining the ratio of downsampling for sensor update
unsigned int sensor_cnt = 0; // counting variable for downsampling
// For hall sensors, the predicted angle is always 0 to 60 electrical degrees ahead of where it would be without
// smoothing, so offset it backward by 30 degrees (set this to -PI_6) to get the average in phase with the rotor
float phase_correction = 0;
protected:
float getSensorAngle() override;
void init() override;
Sensor& _wrapped;
const FOCMotor& _motor;
};
#endif