Skip to content

Commit 0b8b37f

Browse files
author
rob
committed
wip for today.
1 parent ca91d45 commit 0b8b37f

File tree

22 files changed

+263
-153
lines changed

22 files changed

+263
-153
lines changed

src/main/build/version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#define FC_FIRMWARE_NAME "ButterFlight"
2626
#define FC_VERSION_MAJOR 3 // increment when a major release is made (big new feature, etc)
2727
#define FC_VERSION_MINOR 6 // increment when a minor release is made (small new feature, change etc)
28-
#define FC_VERSION_PATCH_LEVEL 6 // increment when a bug is fixed
28+
#define FC_VERSION_PATCH_LEVEL 7 // increment when a bug is fixed
2929

3030

3131
#define FC_VERSION_STRING STR(FC_VERSION_MAJOR) "." STR(FC_VERSION_MINOR) "." STR(FC_VERSION_PATCH_LEVEL)

src/main/cms/cms_menu_imu.c

+18-5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ static uint8_t tmpPidProfileIndex;
5858
static uint8_t pidProfileIndex;
5959
static char pidProfileIndexString[] = " p";
6060
static uint8_t buttered_pids;
61+
static uint8_t i_decay;
62+
static uint8_t r_weight;
6163
static uint8_t tempPid[3][3];
6264
static uint16_t tempPidF[3];
6365

@@ -119,6 +121,8 @@ static long cmsx_PidRead(void)
119121

120122
const pidProfile_t *pidProfile = pidProfiles(pidProfileIndex);
121123
buttered_pids = pidProfile->buttered_pids;
124+
i_decay = pidProfile->i_decay;
125+
r_weight = pidProfile->r_weight;
122126
for (uint8_t i = 0; i < 3; i++) {
123127
tempPid[i][0] = pidProfile->pid[i].P;
124128
tempPid[i][1] = pidProfile->pid[i].I;
@@ -149,6 +153,8 @@ static long cmsx_PidWriteback(const OSD_Entry *self)
149153
pidProfile->pid[i].D = tempPid[i][2];
150154
pidProfile->pid[i].F = tempPidF[i];
151155
}
156+
pidProfile->i_decay = i_decay;
157+
pidProfile->r_weight = r_weight;
152158
pidInitConfig(currentPidProfile);
153159

154160
return 0;
@@ -174,6 +180,9 @@ static OSD_Entry cmsx_menuPidEntries[] =
174180
{ "YAW D", OME_UINT8, NULL, &(OSD_UINT8_t){ &tempPid[PID_YAW][2], 0, 200, 1 }, 0 },
175181
{ "YAW F", OME_UINT16, NULL, &(OSD_UINT16_t){ &tempPidF[PID_YAW], 0, 2000, 1 }, 0 },
176182

183+
{ "I_DECAY", OME_UINT8, NULL, &(OSD_UINT8_t){ &i_decay, 1, 10, 1 }, 0 },
184+
{ "R_WEIGHT", OME_UINT8, NULL, &(OSD_UINT8_t){ &r_weight, 1, 200, 1 }, 0 },
185+
177186
{ "BACK", OME_Back, NULL, NULL, 0 },
178187
{ "SAVE&EXIT", OME_OSD_Exit, cmsMenuExit, (void *)CMS_EXIT_SAVE, 0},
179188
{ NULL, OME_END, NULL, NULL, 0 }
@@ -337,7 +346,7 @@ static uint16_t gyroConfig_gyro_soft_notch_hz_2;
337346
static uint16_t gyroConfig_gyro_soft_notch_cutoff_2;
338347
#ifndef USE_GYRO_IMUF9001
339348
static uint16_t gyroConfig_gyro_filter_q;
340-
static uint16_t gyroConfig_gyro_filter_r;
349+
static uint16_t gyroConfig_gyro_filter_w;
341350
#endif
342351

343352
static long cmsx_menuGyro_onEnter(void)
@@ -351,7 +360,7 @@ static long cmsx_menuGyro_onEnter(void)
351360

352361
#ifndef USE_GYRO_IMUF9001
353362
gyroConfig_gyro_filter_q = gyroConfig()->gyro_filter_q;
354-
gyroConfig_gyro_filter_r = gyroConfig()->gyro_filter_r;
363+
gyroConfig_gyro_filter_w = gyroConfig()->gyro_filter_w;
355364
#endif
356365
return 0;
357366
}
@@ -369,7 +378,7 @@ static long cmsx_menuGyro_onExit(const OSD_Entry *self)
369378

370379
#ifndef USE_GYRO_IMUF9001
371380
gyroConfigMutable()->gyro_filter_q = gyroConfig_gyro_filter_q;
372-
gyroConfigMutable()->gyro_filter_r = gyroConfig_gyro_filter_r;
381+
gyroConfigMutable()->gyro_filter_w = gyroConfig_gyro_filter_w;
373382
#endif
374383
return 0;
375384
}
@@ -388,7 +397,7 @@ static OSD_Entry cmsx_menuFilterGlobalEntries[] =
388397
{ "GYRO NF2C", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_gyro_soft_notch_cutoff_2, 0, 500, 1 }, 0 },
389398
#ifndef USE_GYRO_IMUF9001
390399
{ "KALMAN Q", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_gyro_filter_q, 0, 16000, 1 }, 0 },
391-
{ "KALMAN R", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_gyro_filter_r, 0, 16000, 1 }, 0 },
400+
{ "KALMAN W", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_gyro_filter_w, 3, 64, 1 }, 0 },
392401
#endif
393402
{ "BACK", OME_Back, NULL, NULL, 0 },
394403
{ NULL, OME_END, NULL, NULL, 0 }
@@ -418,6 +427,7 @@ static uint16_t gyroConfig_imuf_w;
418427
static uint16_t gyroConfig_imuf_pitch_lpf_cutoff_hz;
419428
static uint16_t gyroConfig_imuf_roll_lpf_cutoff_hz;
420429
static uint16_t gyroConfig_imuf_yaw_lpf_cutoff_hz;
430+
static uint16_t gyroConfig_imuf_acc_lpf_cutoff_hz;
421431
#endif
422432

423433
#if defined(USE_GYRO_IMUF9001)
@@ -430,6 +440,7 @@ static long cmsx_menuImuf_onEnter(void)
430440
gyroConfig_imuf_pitch_lpf_cutoff_hz = gyroConfig()->imuf_pitch_lpf_cutoff_hz;
431441
gyroConfig_imuf_roll_lpf_cutoff_hz = gyroConfig()->imuf_roll_lpf_cutoff_hz;
432442
gyroConfig_imuf_yaw_lpf_cutoff_hz = gyroConfig()->imuf_yaw_lpf_cutoff_hz;
443+
gyroConfig_imuf_acc_lpf_cutoff_hz = gyroConfig()->imuf_acc_lpf_cutoff_hz;
433444

434445
return 0;
435446
}
@@ -447,6 +458,7 @@ static long cmsx_menuImuf_onExit(const OSD_Entry *self)
447458
gyroConfigMutable()->imuf_roll_lpf_cutoff_hz = gyroConfig_imuf_roll_lpf_cutoff_hz;
448459
gyroConfigMutable()->imuf_pitch_lpf_cutoff_hz = gyroConfig_imuf_pitch_lpf_cutoff_hz;
449460
gyroConfigMutable()->imuf_yaw_lpf_cutoff_hz = gyroConfig_imuf_yaw_lpf_cutoff_hz;
461+
gyroConfigMutable()->imuf_acc_lpf_cutoff_hz = gyroConfig_imuf_acc_lpf_cutoff_hz;
450462
return 0;
451463
}
452464
#endif
@@ -463,8 +475,9 @@ static OSD_Entry cmsx_menuImufEntries[] =
463475
{ "ROLL LPF", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_imuf_roll_lpf_cutoff_hz, 0, 450, 1 }, 0 },
464476
{ "PITCH LPF", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_imuf_pitch_lpf_cutoff_hz, 0, 450, 1 }, 0 },
465477
{ "YAW LPF", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_imuf_yaw_lpf_cutoff_hz, 0, 450, 1 }, 0 },
478+
{ "IMUF ACC", OME_UINT16, NULL, &(OSD_UINT16_t) { &gyroConfig_imuf_acc_lpf_cutoff_hz, 0, 450, 1 }, 0 },
466479

467-
{ "BACK", OME_Back, NULL, NULL, 0},
480+
{ "BACK", OME_Back, NULL, NULL, 0},
468481
{ "SAVE&REBOOT", OME_OSD_Exit, cmsMenuExit, (void *)CMS_EXIT_SAVEREBOOT, 0},
469482
{ NULL, OME_END, NULL, NULL, 0 }
470483
};

src/main/common/filter.c

100644100755
+88-29
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,15 @@
2929
#include "common/maths.h"
3030
#include "common/utils.h"
3131

32-
#define M_LN2_FLOAT 0.69314718055994530942f
33-
#define M_PI_FLOAT 3.14159265358979323846f
34-
#define BIQUAD_Q 1.0f / sqrtf(2.0f) /* quality factor - 2nd order butterworth*/
32+
#include "fc/fc_rc.h"
33+
34+
#define M_LN2_FLOAT 0.69314718055994530942f
35+
#define M_PI_FLOAT 3.14159265358979323846f
36+
#define BIQUAD_Q (1.0f / sqrtf(2.0f)) /* quality factor - 2nd order butterworth*/
37+
38+
#define BASE_LPF_HZ 70.0f
39+
40+
float r_weight = 0.67f;
3541

3642
// NULL filter
3743

@@ -46,7 +52,7 @@ FAST_CODE float nullFilterApply(filter_t *filter, float input)
4652

4753
float pt1FilterGain(uint16_t f_cut, float dT)
4854
{
49-
float RC = 1 / ( 2 * M_PI_FLOAT * f_cut);
55+
const float RC = 0.5f / (M_PI_FLOAT * f_cut);
5056
return dT / (RC + dT);
5157
}
5258

@@ -215,48 +221,101 @@ void laggedMovingAverageInit(laggedMovingAverage_t *filter, uint16_t windowSize,
215221
}
216222

217223
// Proper fast two-state Kalman
218-
void fastKalmanInit(fastKalman_t *filter, float q, float r)
224+
void fastKalmanInit(fastKalman_t *filter, float q, uint32_t w, int axis, float updateRate)
219225
{
226+
if ( w > 64)
227+
{
228+
w = 64;
229+
}
230+
231+
memset(filter, 0, sizeof(fastKalman_t));
220232
filter->q = q * 0.000001f; // add multiplier to make tuning easier
221-
filter->r = r * 0.001f; // add multiplier to make tuning easier
222233
filter->p = q * 0.001f; // add multiplier to make tuning easier
223-
filter->x = 0.0f; // set initial value, can be zero if unknown
224-
filter->lastX = 0.0f; // set initial value, can be zero if unknown
225-
filter->k = 0.0f; // kalman gain
234+
filter->w = w;
235+
filter->windowSizeInverse = 1.0f/(w - 1);
236+
filter->axis = axis;
237+
238+
// set cutoff frequency
239+
const float k = pt1FilterGain(BASE_LPF_HZ, updateRate);
240+
pt1FilterInit(&filter->lp_filter, k);
241+
filter->lp_filter.state = 1.0f; // e's default value
242+
filter->updateRate = updateRate;
226243
}
227244

228-
#ifndef STM32F7
229-
FAST_CODE float laggedMovingAverageUpdate(laggedMovingAverage_t *filter, float input)
230-
{
231-
filter->movingSum -= filter->buf[filter->movingWindowIndex];
232-
filter->buf[filter->movingWindowIndex] = input;
233-
filter->movingSum += input;
234-
235-
if (++filter->movingWindowIndex == filter->windowSize) {
236-
filter->movingWindowIndex = 0;
237-
filter->primed = true;
238-
}
239-
240-
const uint16_t denom = filter->primed ? filter->windowSize : filter->movingWindowIndex;
241-
return filter->movingSum / denom;
242-
}
243-
#endif
245+
#pragma GCC push_options
246+
#pragma GCC optimize("O3")
244247

245248
FAST_CODE float fastKalmanUpdate(fastKalman_t *filter, float input)
246249
{
250+
static float e;
251+
252+
const float setPoint = getSetpointRate(filter->axis);
253+
const float filteredValue = filter->x;
254+
247255
// project the state ahead using acceleration
248256
filter->x += (filter->x - filter->lastX);
249257

250258
// update last state
251259
filter->lastX = filter->x;
252260

261+
// figure out how much to boost or reduce our error in the estimate based on setPoint target.
262+
// this should be close to 0 as we approach the setPoint and really high the further away we are from the setPoint.
263+
if (setPoint != 0.0f && filteredValue != 0.0f)
264+
{
265+
e = ABS(1.0f - (setPoint/filteredValue));
266+
}
267+
else
268+
{
269+
e = 1.0f;
270+
}
271+
//e = pt1FilterApply(&filter->lp_filter, e);
272+
253273
// prediction update
254-
filter->p = filter->p + filter->q;
274+
filter->p = filter->p + filter->q * e;
255275

256276
// measurement update
257-
filter->k = filter->p / (filter->p + filter->r);
258-
filter->x += filter->k * (input - filter->x);
259-
filter->p = (1.0f - filter->k) * filter->p;
277+
const float k = filter->p / (filter->p + filter->r);
278+
filter->x += k * (input - filter->x);
279+
filter->p = (1.0f - k) * filter->p;
280+
281+
filter->x = pt1FilterApply(&filter->lp_filter, filter->x);
282+
283+
// update variance
284+
filter->window[filter->windowIndex] = input;
285+
286+
filter->meanSum += filter->window[filter->windowIndex];
287+
filter->varianceSum = filter->varianceSum + (filter->window[filter->windowIndex] * filter->window[filter->windowIndex]);
288+
289+
filter->windowIndex++;
290+
if (filter->windowIndex >= filter->w)
291+
{
292+
filter->windowIndex = 0;
293+
}
294+
295+
filter->meanSum -= filter->window[filter->windowIndex];
296+
filter->varianceSum = filter->varianceSum - (filter->window[filter->windowIndex] * filter->window[filter->windowIndex]);
297+
298+
filter->mean = filter->meanSum * filter->windowSizeInverse;
299+
filter->variance = ABS(filter->varianceSum * filter->windowSizeInverse - (filter->mean * filter->mean));
300+
filter->r = sqrtf(filter->variance) * r_weight;
301+
302+
303+
if (isSetpointNew)
304+
{
305+
if (setPoint != 0.0f && filter->oldSetPoint != setPoint)
306+
{
307+
const float cutoff_frequency = constrain(BASE_LPF_HZ * e, 10.0f, 500.0f);
308+
const float k = pt1FilterGain(cutoff_frequency, filter->updateRate);
309+
pt1FilterUpdateCutoff(&filter->lp_filter, k);
310+
filter->oldSetPoint = setPoint;
311+
}
312+
if (filter->axis == 2)
313+
{
314+
isSetpointNew = false;
315+
}
316+
}
260317

261318
return filter->x;
262319
}
320+
321+
#pragma GCC pop_options

src/main/common/filter.h

+21-7
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,31 @@ typedef enum {
6161
FILTER_BPF,
6262
} biquadFilterType_e;
6363

64-
typedef struct fastKalman_s {
64+
#if (defined(STM32F7) || defined(STM32F4))
65+
#define MAX_WINDOW_SIZE 256
66+
#else
67+
#define MAX_WINDOW_SIZE 64
68+
#endif
69+
70+
typedef struct kalman_s {
71+
uint32_t w; // window size
6572
float q; // process noise covariance
6673
float r; // measurement noise covariance
6774
float p; // estimation error covariance matrix
68-
float k; // kalman gain
6975
float x; // state
7076
float lastX; // previous state
77+
78+
float window[MAX_WINDOW_SIZE];
79+
float variance;
80+
float varianceSum;
81+
float mean;
82+
float meanSum;
83+
float windowSizeInverse;
84+
uint32_t windowIndex;
85+
int axis; // for setPoint not being passed during call time
86+
pt1Filter_t lp_filter;
87+
float oldSetPoint;
88+
float updateRate;
7189
} fastKalman_t;
7290

7391
typedef float (*filterApplyFnPtr)(filter_t *filter, float input);
@@ -82,10 +100,6 @@ void biquadFilterUpdateLPF(biquadFilter_t *filter, float filterFreq, uint32_t re
82100
float biquadFilterApplyDF1(biquadFilter_t *filter, float input);
83101
float biquadFilterApply(biquadFilter_t *filter, float input);
84102
float filterGetNotchQ(float centerFreq, float cutoffFreq);
85-
#ifndef STM32F7
86-
void laggedMovingAverageInit(laggedMovingAverage_t *filter, uint16_t windowSize, float *buf);
87-
float laggedMovingAverageUpdate(laggedMovingAverage_t *filter, float input);
88-
#endif
89103
float pt1FilterGain(uint16_t f_cut, float dT);
90104
void pt1FilterInit(pt1Filter_t *filter, float k);
91105
void pt1FilterUpdateCutoff(pt1Filter_t *filter, float k);
@@ -94,5 +108,5 @@ float pt1FilterApply(pt1Filter_t *filter, float input);
94108
void slewFilterInit(slewFilter_t *filter, float slewLimit, float threshold);
95109
float slewFilterApply(slewFilter_t *filter, float input);
96110

97-
void fastKalmanInit(fastKalman_t *filter, float q, float r);
111+
void fastKalmanInit(fastKalman_t *filter, float q, uint32_t w, int axis, float updateRate);
98112
float fastKalmanUpdate(fastKalman_t *filter, float input);

src/main/config/config_eeprom.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <stdint.h>
2424
#include <stdbool.h>
2525

26-
#define EEPROM_CONF_VERSION 171
26+
#define EEPROM_CONF_VERSION 173
2727

2828
bool isEEPROMVersionValid(void);
2929
bool isEEPROMStructureValid(void);

src/main/drivers/accgyro/accgyro_imuf9001.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ void setupImufParams(imufCommand_t * data)
577577
data->param7 = ( (uint16_t)0 << 16) | (uint16_t)0;
578578
data->param8 = ( (int16_t)boardAlignment()->rollDegrees << 16 ) | imufGyroAlignment();
579579
data->param9 = ( (int16_t)boardAlignment()->yawDegrees << 16 ) | (int16_t)boardAlignment()->pitchDegrees;
580+
data->param10 = ( (uint16_t)gyroConfig()->r_weight << 16) | ( (int16_t)gyroConfig()->imuf_acc_lpf_cutoff_hz );
580581
}
581582
}
582583

@@ -647,4 +648,4 @@ FAST_CODE void imufEndCalibration(void)
647648
isImufCalibrating = IMUF_NOT_CALIBRATING; //reset by EXTI
648649
}
649650

650-
#endif
651+
#endif

src/main/fc/config.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ int getImufRateFromGyroSyncDenom(int gyroSyncDenom){
422422
return IMUF_RATE_32K;
423423
break;
424424
case 2:
425-
default:
426425
return IMUF_RATE_16K;
427426
break;
428427
case 4:
429428
return IMUF_RATE_8K;
430429
break;
431430
case 8:
431+
default:
432432
return IMUF_RATE_4K;
433433
break;
434434
case 16:

src/main/fc/fc_rc.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ enum {
6060
THROTTLE_FLAG = 1 << THROTTLE,
6161
};
6262

63-
#ifdef USE_GYRO_IMUF9001
64-
volatile bool isSetpointNew;
65-
#endif
63+
volatile bool isSetpointNew;
6664

6765
typedef float (applyRatesFn)(const int axis, float rcCommandf, const float rcCommandfAbs);
6866

@@ -651,9 +649,7 @@ FAST_CODE void processRcCommand(void)
651649
}
652650

653651
DEBUG_SET(DEBUG_RC_INTERPOLATION, 3, setpointRate[0]);
654-
#ifdef USE_GYRO_IMUF9001
655652
isSetpointNew = 1;
656-
#endif
657653
if (debugMode == DEBUG_RC_INTERPOLATION) {
658654
debug[2] = rcInterpolationStepCount;
659655
debug[3] = setpointRate[0];

src/main/fc/fc_rc.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,8 @@ typedef enum {
2828
INTERPOLATION_CHANNELS_RPT,
2929
} interpolationChannels_e;
3030

31-
#ifdef USE_GYRO_IMUF9001
32-
extern volatile bool isSetpointNew;
33-
#endif
34-
extern volatile uint16_t currentRxRefreshRate;
31+
extern volatile bool isSetpointNew;
32+
extern volatile uint16_t currentRxRefreshRate;
3533

3634
void processRcCommand(void);
3735
float getSetpointRate(int axis);

0 commit comments

Comments
 (0)