Skip to content

Commit 10cdc90

Browse files
Quick-FlashnerdCopter
authored andcommitted
allow choosing your own q for dterm biquad
1 parent 3aab740 commit 10cdc90

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

src/main/cli/settings.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,8 +1072,10 @@ const clivalue_t valueTable[] = {
10721072
{ "dterm_lpf1_dyn_expo", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 10 }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf1_dyn_expo) },
10731073
#endif
10741074
{ PARAM_NAME_DTERM_LPF1_TYPE, VAR_UINT8 | PROFILE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_DTERM_LPF_TYPE }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf1_type) },
1075+
{ "dterm_lpf1_biquad_q", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 10 }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf1_biquad_q) },
10751076
{ PARAM_NAME_DTERM_LPF1_STATIC_HZ, VAR_INT16 | PROFILE_VALUE, .config.minmax = { 0, LPF_MAX_HZ }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf1_static_hz) },
10761077
{ PARAM_NAME_DTERM_LPF2_TYPE, VAR_UINT8 | PROFILE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_DTERM_LPF_TYPE }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf2_type) },
1078+
{ "dterm_lpf2_biquad_q", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 10 }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf2_biquad_q) },
10771079
{ PARAM_NAME_DTERM_LPF2_STATIC_HZ, VAR_INT16 | PROFILE_VALUE, .config.minmax = { 0, LPF_MAX_HZ }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_lpf2_static_hz) },
10781080
{ PARAM_NAME_DTERM_NOTCH_HZ, VAR_UINT16 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, LPF_MAX_HZ }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_notch_hz) },
10791081
{ PARAM_NAME_DTERM_NOTCH_CUTOFF, VAR_UINT16 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, LPF_MAX_HZ }, PG_PID_PROFILE, offsetof(pidProfile_t, dterm_notch_cutoff) },
@@ -1698,9 +1700,10 @@ const clivalue_t valueTable[] = {
16981700
#endif
16991701

17001702
#ifdef USE_RPM_FILTER
1701-
{ PARAM_NAME_RPM_FILTER_HARMONICS, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 3 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_harmonics) },
1703+
{ PARAM_NAME_RPM_FILTER_HARMONICS, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 3 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_harmonics) },
17021704
{ PARAM_NAME_RPM_FILTER_Q, VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 250, 3000 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_q) },
1703-
{ PARAM_NAME_RPM_FILTER_MIN_HZ, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 30, 200 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_min_hz) },
1705+
{ PARAM_NAME_RPM_FILTER_Q, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 255 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, noise_limit) },
1706+
{ PARAM_NAME_RPM_FILTER_MIN_HZ, VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 30, 200 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_min_hz) },
17041707
{ PARAM_NAME_RPM_FILTER_FADE_RANGE_HZ, VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 1000 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_fade_range_hz) },
17051708
{ PARAM_NAME_RPM_FILTER_LPF_HZ, VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 100, 500 }, PG_RPM_FILTER_CONFIG, offsetof(rpmFilterConfig_t, rpm_filter_lpf_hz) },
17061709
#endif

src/main/common/filter.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ FAST_CODE void biquadFilterUpdate(biquadFilter_t *filter, float filterFreq, uint
185185
const float cs = cos_approx(omega);
186186
const float alpha = sn / (2.0f * Q);
187187

188+
// shift filterFreq of the biquad to satisfy -3dB cutoff condition for all Q values
189+
if (filterType == FILTER_LPF) {
190+
const float q = 2 * Q * Q;
191+
filterFreq *= sqrtf((1 - q + sqrtf(2 * q * (q - 1) + 1)) / q);
192+
}
193+
188194
switch (filterType) {
189195
case FILTER_LPF:
190196
// 2nd order Butterworth (with Q=1/sqrt(2)) / Butterworth biquad section with Q

src/main/flight/pid.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ void resetPidProfile(pidProfile_t *pidProfile)
180180
// reset the lowpass filter type to PT1 overriding the desired BIQUAD setting.
181181
.dterm_lpf2_static_hz = DTERM_LPF2_HZ_DEFAULT, // second Dterm LPF ON by default
182182
.dterm_lpf1_type = FILTER_PT1,
183+
.dterm_lpf1_biquad_q = 141,
183184
.dterm_lpf2_type = FILTER_PT1,
185+
.dterm_lpf2_biquad_q = 141,
184186
.dterm_lpf1_dyn_min_hz = DTERM_LPF1_DYN_MIN_HZ_DEFAULT,
185187
.dterm_lpf1_dyn_max_hz = DTERM_LPF1_DYN_MAX_HZ_DEFAULT,
186188
.launchControlMode = LAUNCH_CONTROL_MODE_NORMAL,
@@ -1261,7 +1263,7 @@ void dynLpfDTermUpdate(float throttle)
12611263
break;
12621264
case DYN_LPF_BIQUAD:
12631265
for (int axis = 0; axis < XYZ_AXIS_COUNT; axis++) {
1264-
biquadFilterUpdateLPF(&pidRuntime.dtermLowpass[axis].biquadFilter, cutoffFreq, targetPidLooptime);
1266+
biquadFilterUpdate(&pidRuntime.dtermLowpass[axis].biquadFilter, cutoffFreq, targetPidLooptime, pidRuntime.dtermLowpassBiquadQ, FILTER_LPF, 1.0f);
12651267
}
12661268
break;
12671269
case DYN_LPF_PT2:

src/main/flight/pid.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ typedef struct pidProfile_s {
139139
pidf_t pid[PID_ITEM_COUNT];
140140

141141
uint8_t dterm_lpf1_type; // Filter type for dterm lowpass 1
142+
uint8_t dterm_lpf1_biquad_q; // q value for the dterm lowpass 1 biquad
142143
uint8_t itermWindupPointPercent; // iterm windup threshold, percent motor saturation
143144
uint16_t pidSumLimit;
144145
uint16_t pidSumLimitYaw;
@@ -180,6 +181,7 @@ typedef struct pidProfile_s {
180181
uint8_t abs_control_error_limit; // Limit to the accumulated error
181182
uint8_t abs_control_cutoff; // Cutoff frequency for path estimation in abs control
182183
uint8_t dterm_lpf2_type; // Filter type for 2nd dterm lowpass
184+
uint8_t dterm_lpf2_biquad_q; // q value for the dterm lowpass 1 biquad
183185
uint16_t dterm_lpf1_dyn_min_hz; // Dterm lowpass filter 1 min hz when in dynamic mode
184186
uint16_t dterm_lpf1_dyn_max_hz; // Dterm lowpass filter 1 max hz when in dynamic mode
185187
uint8_t launchControlMode; // Whether launch control is limited to pitch only (launch stand or top-mount) or all axes (on battery)
@@ -364,6 +366,8 @@ typedef struct pidRuntime_s {
364366
uint8_t dynLpfCurveExpo;
365367
#endif
366368

369+
float dtermLowpassBiquadQ;
370+
367371
#ifdef USE_LAUNCH_CONTROL
368372
uint8_t launchControlMode;
369373
uint8_t launchControlAngleLimit;

src/main/flight/pid_init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ void pidInitFilters(const pidProfile_t *pidProfile)
103103

104104
//1st Dterm Lowpass Filter
105105
uint16_t dterm_lpf1_init_hz = pidProfile->dterm_lpf1_static_hz;
106+
pidRuntime.dtermLowpassBiquadQ = pidProfile->dterm_lpf1_biquad_q / 100.0f;
106107

107108
#ifdef USE_DYN_LPF
108109
if (pidProfile->dterm_lpf1_dyn_min_hz) {
@@ -126,7 +127,7 @@ void pidInitFilters(const pidProfile_t *pidProfile)
126127
pidRuntime.dtermLowpassApplyFn = (filterApplyFnPtr)biquadFilterApply;
127128
#endif
128129
for (int axis = FD_ROLL; axis <= FD_YAW; axis++) {
129-
biquadFilterInitLPF(&pidRuntime.dtermLowpass[axis].biquadFilter, dterm_lpf1_init_hz, targetPidLooptime);
130+
biquadFilterInit(&pidRuntime.dtermLowpass[axis].biquadFilter, dterm_lpf1_init_hz, targetPidLooptime, pidRuntime.dtermLowpassBiquadQ, FILTER_LPF, 1.0f);
130131
}
131132
} else {
132133
pidRuntime.dtermLowpassApplyFn = nullFilterApply;
@@ -165,7 +166,7 @@ void pidInitFilters(const pidProfile_t *pidProfile)
165166
if (pidProfile->dterm_lpf2_static_hz < pidFrequencyNyquist) {
166167
pidRuntime.dtermLowpass2ApplyFn = (filterApplyFnPtr)biquadFilterApply;
167168
for (int axis = FD_ROLL; axis <= FD_YAW; axis++) {
168-
biquadFilterInitLPF(&pidRuntime.dtermLowpass2[axis].biquadFilter, pidProfile->dterm_lpf2_static_hz, targetPidLooptime);
169+
biquadFilterInit(&pidRuntime.dtermLowpass2[axis].biquadFilter, pidProfile->dterm_lpf2_static_hz, targetPidLooptime, pidProfile->dterm_lpf2_biquad_q / 100.0f, FILTER_LPF, 1.0f);
169170
}
170171
} else {
171172
pidRuntime.dtermLowpassApplyFn = nullFilterApply;
@@ -440,4 +441,3 @@ void pidCopyProfile(uint8_t dstPidProfileIndex, uint8_t srcPidProfileIndex)
440441
memcpy(pidProfilesMutable(dstPidProfileIndex), pidProfilesMutable(srcPidProfileIndex), sizeof(pidProfile_t));
441442
}
442443
}
443-

0 commit comments

Comments
 (0)