1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-17 05:15:25 +03:00

Rework Acc filtering

This commit is contained in:
borisbstyle 2016-02-17 17:37:01 +01:00
parent 974274b748
commit 57a3e59a38
8 changed files with 48 additions and 46 deletions

View file

@ -492,8 +492,7 @@ static void resetConf(void)
resetRollAndPitchTrims(&masterConfig.accelerometerTrims); resetRollAndPitchTrims(&masterConfig.accelerometerTrims);
masterConfig.mag_declination = 0; masterConfig.mag_declination = 0;
masterConfig.acc_lpf_hz = 20; masterConfig.acc_lpf_hz = 10.0f;
masterConfig.accz_lpf_cutoff = 5.0f;
masterConfig.accDeadband.xy = 40; masterConfig.accDeadband.xy = 40;
masterConfig.accDeadband.z = 40; masterConfig.accDeadband.z = 40;
masterConfig.acc_unarmedcal = 1; masterConfig.acc_unarmedcal = 1;
@ -730,6 +729,7 @@ void activateConfig(void)
useFailsafeConfig(&masterConfig.failsafeConfig); useFailsafeConfig(&masterConfig.failsafeConfig);
setAccelerationTrims(&masterConfig.accZero); setAccelerationTrims(&masterConfig.accZero);
setAccelerationFilter(masterConfig.acc_lpf_hz);
mixerUseConfigs( mixerUseConfigs(
#ifdef USE_SERVOS #ifdef USE_SERVOS
@ -745,7 +745,6 @@ void activateConfig(void)
imuRuntimeConfig.dcm_kp = masterConfig.dcm_kp / 10000.0f; imuRuntimeConfig.dcm_kp = masterConfig.dcm_kp / 10000.0f;
imuRuntimeConfig.dcm_ki = masterConfig.dcm_ki / 10000.0f; imuRuntimeConfig.dcm_ki = masterConfig.dcm_ki / 10000.0f;
imuRuntimeConfig.acc_cut_hz = masterConfig.acc_lpf_hz;
imuRuntimeConfig.acc_unarmedcal = masterConfig.acc_unarmedcal; imuRuntimeConfig.acc_unarmedcal = masterConfig.acc_unarmedcal;
imuRuntimeConfig.small_angle = masterConfig.small_angle; imuRuntimeConfig.small_angle = masterConfig.small_angle;
@ -753,7 +752,6 @@ void activateConfig(void)
&imuRuntimeConfig, &imuRuntimeConfig,
&currentProfile->pidProfile, &currentProfile->pidProfile,
&masterConfig.accDeadband, &masterConfig.accDeadband,
masterConfig.accz_lpf_cutoff,
masterConfig.throttle_correction_angle masterConfig.throttle_correction_angle
); );

View file

@ -72,8 +72,7 @@ typedef struct master_t {
rollAndPitchTrims_t accelerometerTrims; // accelerometer trim rollAndPitchTrims_t accelerometerTrims; // accelerometer trim
uint8_t acc_lpf_hz; // Set the Low Pass Filter factor for ACC. Reducing this value would reduce ACC noise (visible in GUI), but would increase ACC lag time. Zero = no filter float acc_lpf_hz; // cutoff frequency for the low pass filter used on the acc z-axis for althold in Hz
float accz_lpf_cutoff; // cutoff frequency for the low pass filter used on the acc z-axis for althold in Hz
accDeadband_t accDeadband; accDeadband_t accDeadband;
barometerConfig_t barometerConfig; barometerConfig_t barometerConfig;
uint8_t acc_unarmedcal; // turn automatic acc compensation on/off uint8_t acc_unarmedcal; // turn automatic acc compensation on/off

View file

@ -56,7 +56,6 @@
// http://gentlenav.googlecode.com/files/fastRotations.pdf // http://gentlenav.googlecode.com/files/fastRotations.pdf
#define SPIN_RATE_LIMIT 20 #define SPIN_RATE_LIMIT 20
int16_t accSmooth[XYZ_AXIS_COUNT];
int32_t accSum[XYZ_AXIS_COUNT]; int32_t accSum[XYZ_AXIS_COUNT];
uint32_t accTimeSum = 0; // keep track for integration of acc uint32_t accTimeSum = 0; // keep track for integration of acc
@ -111,14 +110,13 @@ void imuConfigure(
imuRuntimeConfig_t *initialImuRuntimeConfig, imuRuntimeConfig_t *initialImuRuntimeConfig,
pidProfile_t *initialPidProfile, pidProfile_t *initialPidProfile,
accDeadband_t *initialAccDeadband, accDeadband_t *initialAccDeadband,
float accz_lpf_cutoff,
uint16_t throttle_correction_angle uint16_t throttle_correction_angle
) )
{ {
imuRuntimeConfig = initialImuRuntimeConfig; imuRuntimeConfig = initialImuRuntimeConfig;
pidProfile = initialPidProfile; pidProfile = initialPidProfile;
accDeadband = initialAccDeadband; accDeadband = initialAccDeadband;
fc_acc = calculateAccZLowPassFilterRCTimeConstant(accz_lpf_cutoff); fc_acc = calculateAccZLowPassFilterRCTimeConstant(5.0f); // Set to fix value
throttleAngleScale = calculateThrottleAngleScale(throttle_correction_angle); throttleAngleScale = calculateThrottleAngleScale(throttle_correction_angle);
} }
@ -377,11 +375,8 @@ static bool isMagnetometerHealthy(void)
static void imuCalculateEstimatedAttitude(void) static void imuCalculateEstimatedAttitude(void)
{ {
static biquad_t accLPFState[3];
static bool accStateIsSet;
static uint32_t previousIMUUpdateTime; static uint32_t previousIMUUpdateTime;
float rawYawError = 0; float rawYawError = 0;
int32_t axis;
bool useAcc = false; bool useAcc = false;
bool useMag = false; bool useMag = false;
bool useYaw = false; bool useYaw = false;
@ -390,20 +385,6 @@ static void imuCalculateEstimatedAttitude(void)
uint32_t deltaT = currentTime - previousIMUUpdateTime; uint32_t deltaT = currentTime - previousIMUUpdateTime;
previousIMUUpdateTime = currentTime; previousIMUUpdateTime = currentTime;
// Smooth and use only valid accelerometer readings
for (axis = 0; axis < 3; axis++) {
if (imuRuntimeConfig->acc_cut_hz) {
if (accStateIsSet) {
accSmooth[axis] = lrintf(applyBiQuadFilter((float) accADC[axis], &accLPFState[axis]));
} else {
for (axis = 0; axis < 3; axis++) BiQuadNewLpf(imuRuntimeConfig->acc_cut_hz, &accLPFState[axis], 1000);
accStateIsSet = true;
}
} else {
accSmooth[axis] = accADC[axis];
}
}
if (imuIsAccelerometerHealthy()) { if (imuIsAccelerometerHealthy()) {
useAcc = true; useAcc = true;
} }
@ -445,9 +426,9 @@ void imuUpdateGyroAndAttitude(void)
if (sensors(SENSOR_ACC) && isAccelUpdatedAtLeastOnce) { if (sensors(SENSOR_ACC) && isAccelUpdatedAtLeastOnce) {
imuCalculateEstimatedAttitude(); imuCalculateEstimatedAttitude();
} else { } else {
accADC[X] = 0; accSmooth[X] = 0;
accADC[Y] = 0; accSmooth[Y] = 0;
accADC[Z] = 0; accSmooth[Z] = 0;
} }
} }

View file

@ -21,7 +21,6 @@ extern int16_t throttleAngleCorrection;
extern uint32_t accTimeSum; extern uint32_t accTimeSum;
extern int accSumCount; extern int accSumCount;
extern float accVelScale; extern float accVelScale;
extern int16_t accSmooth[XYZ_AXIS_COUNT];
extern int32_t accSum[XYZ_AXIS_COUNT]; extern int32_t accSum[XYZ_AXIS_COUNT];
#define DEGREES_TO_DECIDEGREES(angle) (angle * 10) #define DEGREES_TO_DECIDEGREES(angle) (angle * 10)
@ -74,7 +73,6 @@ void imuConfigure(
imuRuntimeConfig_t *initialImuRuntimeConfig, imuRuntimeConfig_t *initialImuRuntimeConfig,
pidProfile_t *initialPidProfile, pidProfile_t *initialPidProfile,
accDeadband_t *initialAccDeadband, accDeadband_t *initialAccDeadband,
float accz_lpf_cutoff,
uint16_t throttle_correction_angle uint16_t throttle_correction_angle
); );
@ -84,7 +82,7 @@ void imuUpdateAccelerometer(rollAndPitchTrims_t *accelerometerTrims);
void imuUpdateGyroAndAttitude(void); void imuUpdateGyroAndAttitude(void);
float calculateThrottleAngleScale(uint16_t throttle_correction_angle); float calculateThrottleAngleScale(uint16_t throttle_correction_angle);
int16_t calculateThrottleAngleCorrection(uint8_t throttle_correction_value); int16_t calculateThrottleAngleCorrection(uint8_t throttle_correction_value);
float calculateAccZLowPassFilterRCTimeConstant(float accz_lpf_cutoff); float calculateAccZLowPassFilterRCTimeConstant(float accz_lpf_hz);
int16_t imuCalculateHeading(t_fp_vector *vec); int16_t imuCalculateHeading(t_fp_vector *vec);

View file

@ -658,10 +658,9 @@ const clivalue_t valueTable[] = {
#endif #endif
{ "acc_hardware", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.acc_hardware, .config.lookup = { TABLE_ACC_HARDWARE } }, { "acc_hardware", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.acc_hardware, .config.lookup = { TABLE_ACC_HARDWARE } },
{ "acc_lpf_hz", VAR_UINT8 | MASTER_VALUE, &masterConfig.acc_lpf_hz, .config.minmax = { 0, 200 } }, { "acc_lpf_hz", VAR_FLOAT | MASTER_VALUE, &masterConfig.acc_lpf_hz, .config.minmax = { 0, 400 } },
{ "accxy_deadband", VAR_UINT8 | MASTER_VALUE, &masterConfig.accDeadband.xy, .config.minmax = { 0, 100 } }, { "accxy_deadband", VAR_UINT8 | MASTER_VALUE, &masterConfig.accDeadband.xy, .config.minmax = { 0, 100 } },
{ "accz_deadband", VAR_UINT8 | MASTER_VALUE, &masterConfig.accDeadband.z, .config.minmax = { 0, 100 } }, { "accz_deadband", VAR_UINT8 | MASTER_VALUE, &masterConfig.accDeadband.z, .config.minmax = { 0, 100 } },
{ "accz_lpf_cutoff", VAR_FLOAT | MASTER_VALUE, &masterConfig.accz_lpf_cutoff, .config.minmax = { 1, 20 } },
{ "acc_unarmedcal", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.acc_unarmedcal, .config.lookup = { TABLE_OFF_ON } }, { "acc_unarmedcal", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.acc_unarmedcal, .config.lookup = { TABLE_OFF_ON } },
{ "acc_trim_pitch", VAR_INT16 | MASTER_VALUE, &masterConfig.accelerometerTrims.values.pitch, .config.minmax = { -300, 300 } }, { "acc_trim_pitch", VAR_INT16 | MASTER_VALUE, &masterConfig.accelerometerTrims.values.pitch, .config.minmax = { -300, 300 } },
{ "acc_trim_roll", VAR_INT16 | MASTER_VALUE, &masterConfig.accelerometerTrims.values.roll, .config.minmax = { -300, 300 } }, { "acc_trim_roll", VAR_INT16 | MASTER_VALUE, &masterConfig.accelerometerTrims.values.roll, .config.minmax = { -300, 300 } },

View file

@ -651,7 +651,6 @@ int main(void) {
setTaskEnabled(TASK_GYROPID, true); setTaskEnabled(TASK_GYROPID, true);
if(sensors(SENSOR_ACC)) { if(sensors(SENSOR_ACC)) {
uint32_t accTargetLooptime = 0;
setTaskEnabled(TASK_ACCEL, true); setTaskEnabled(TASK_ACCEL, true);
switch(targetLooptime) { switch(targetLooptime) {
case(500): case(500):

View file

@ -17,14 +17,17 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <math.h>
#include "platform.h" #include "platform.h"
#include "common/axis.h" #include "common/axis.h"
#include "common/filter.h"
#include "drivers/sensor.h" #include "drivers/sensor.h"
#include "drivers/accgyro.h" #include "drivers/accgyro.h"
#include "drivers/system.h" #include "drivers/system.h"
#include "drivers/gyro_sync.h"
#include "sensors/battery.h" #include "sensors/battery.h"
#include "sensors/sensors.h" #include "sensors/sensors.h"
@ -35,11 +38,12 @@
#include "sensors/acceleration.h" #include "sensors/acceleration.h"
int32_t accADC[XYZ_AXIS_COUNT]; int32_t accSmooth[XYZ_AXIS_COUNT];
acc_t acc; // acc access functions acc_t acc; // acc access functions
sensor_align_e accAlign = 0; sensor_align_e accAlign = 0;
uint16_t acc_1G = 256; // this is the 1G measured acceleration. uint16_t acc_1G = 256; // this is the 1G measured acceleration.
uint32_t accTargetLooptime;
uint16_t calibratingA = 0; // the calibration is done is the main loop. Calibrating decreases at each cycle down to 0, then we enter in a normal mode. uint16_t calibratingA = 0; // the calibration is done is the main loop. Calibrating decreases at each cycle down to 0, then we enter in a normal mode.
@ -51,6 +55,10 @@ extern bool AccInflightCalibrationActive;
static flightDynamicsTrims_t *accelerationTrims; static flightDynamicsTrims_t *accelerationTrims;
static float accLpfCutHz = 0;
static biquad_t accFilterState[XYZ_AXIS_COUNT];
static bool accFilterInitialised = false;
void accSetCalibrationCycles(uint16_t calibrationCyclesRequired) void accSetCalibrationCycles(uint16_t calibrationCyclesRequired)
{ {
calibratingA = calibrationCyclesRequired; calibratingA = calibrationCyclesRequired;
@ -89,10 +97,10 @@ void performAcclerationCalibration(rollAndPitchTrims_t *rollAndPitchTrims)
a[axis] = 0; a[axis] = 0;
// Sum up CALIBRATING_ACC_CYCLES readings // Sum up CALIBRATING_ACC_CYCLES readings
a[axis] += accADC[axis]; a[axis] += accSmooth[axis];
// Reset global variables to prevent other code from using un-calibrated data // Reset global variables to prevent other code from using un-calibrated data
accADC[axis] = 0; accSmooth[axis] = 0;
accelerationTrims->raw[axis] = 0; accelerationTrims->raw[axis] = 0;
} }
@ -131,9 +139,9 @@ void performInflightAccelerationCalibration(rollAndPitchTrims_t *rollAndPitchTri
if (InflightcalibratingA == 50) if (InflightcalibratingA == 50)
b[axis] = 0; b[axis] = 0;
// Sum up 50 readings // Sum up 50 readings
b[axis] += accADC[axis]; b[axis] += accSmooth[axis];
// Clear global variables for next reading // Clear global variables for next reading
accADC[axis] = 0; accSmooth[axis] = 0;
accelerationTrims->raw[axis] = 0; accelerationTrims->raw[axis] = 0;
} }
// all values are measured // all values are measured
@ -165,9 +173,9 @@ void performInflightAccelerationCalibration(rollAndPitchTrims_t *rollAndPitchTri
void applyAccelerationTrims(flightDynamicsTrims_t *accelerationTrims) void applyAccelerationTrims(flightDynamicsTrims_t *accelerationTrims)
{ {
accADC[X] -= accelerationTrims->raw[X]; accSmooth[X] -= accelerationTrims->raw[X];
accADC[Y] -= accelerationTrims->raw[Y]; accSmooth[Y] -= accelerationTrims->raw[Y];
accADC[Z] -= accelerationTrims->raw[Z]; accSmooth[Z] -= accelerationTrims->raw[Z];
} }
void updateAccelerationReadings(rollAndPitchTrims_t *rollAndPitchTrims) void updateAccelerationReadings(rollAndPitchTrims_t *rollAndPitchTrims)
@ -179,9 +187,22 @@ void updateAccelerationReadings(rollAndPitchTrims_t *rollAndPitchTrims)
return; return;
} }
for (axis = 0; axis < XYZ_AXIS_COUNT; axis++) accADC[axis] = accADCRaw[axis]; for (axis = 0; axis < XYZ_AXIS_COUNT; axis++) accSmooth[axis] = accADCRaw[axis];
alignSensors(accADC, accADC, accAlign); if (accLpfCutHz) {
if (!accFilterInitialised) {
if (accTargetLooptime) { /* Initialisation needs to happen once sample rate is known */
for (axis = 0; axis < 3; axis++) BiQuadNewLpf(accLpfCutHz, &accFilterState[axis], accTargetLooptime);
accFilterInitialised = true;
}
}
if (accFilterInitialised) {
for (axis = 0; axis < XYZ_AXIS_COUNT; axis++) accSmooth[axis] = lrintf(applyBiQuadFilter((float) accSmooth[axis], &accFilterState[axis]));
}
}
alignSensors(accSmooth, accSmooth, accAlign);
if (!isAccelerationCalibrationComplete()) { if (!isAccelerationCalibrationComplete()) {
performAcclerationCalibration(rollAndPitchTrims); performAcclerationCalibration(rollAndPitchTrims);
@ -198,3 +219,8 @@ void setAccelerationTrims(flightDynamicsTrims_t *accelerationTrimsToUse)
{ {
accelerationTrims = accelerationTrimsToUse; accelerationTrims = accelerationTrimsToUse;
} }
void setAccelerationFilter(float initialAccLpfCutHz)
{
accLpfCutHz = initialAccLpfCutHz;
}

View file

@ -36,8 +36,9 @@ typedef enum {
extern sensor_align_e accAlign; extern sensor_align_e accAlign;
extern acc_t acc; extern acc_t acc;
extern uint16_t acc_1G; extern uint16_t acc_1G;
extern uint32_t accTargetLooptime;
extern int32_t accADC[XYZ_AXIS_COUNT]; extern int32_t accSmooth[XYZ_AXIS_COUNT];
typedef struct rollAndPitchTrims_s { typedef struct rollAndPitchTrims_s {
int16_t roll; int16_t roll;
@ -54,3 +55,4 @@ void accSetCalibrationCycles(uint16_t calibrationCyclesRequired);
void resetRollAndPitchTrims(rollAndPitchTrims_t *rollAndPitchTrims); void resetRollAndPitchTrims(rollAndPitchTrims_t *rollAndPitchTrims);
void updateAccelerationReadings(rollAndPitchTrims_t *rollAndPitchTrims); void updateAccelerationReadings(rollAndPitchTrims_t *rollAndPitchTrims);
void setAccelerationTrims(flightDynamicsTrims_t *accelerationTrimsToUse); void setAccelerationTrims(flightDynamicsTrims_t *accelerationTrimsToUse);
void setAccelerationFilter(float initialAccLpfCutHz);