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

Small modification to ff boost spike suppression

The feed forward boost concept improves stick response by adding a stick acceleration factor to feed forward. Generating spikes when there are steps in the RC signal is the main problem.
This PR makes one small change to how the spike suppression method is determined.
It no longer uses the 'jerk' signal to generate the spike suppression 'clip' value.  Instead it just uses the magnitude of the boost signal itself.
We originally used jerk because it is more sensitive to spikes. Detailed testing shows that jerk is that it has an unwanted impact one full RC step after the spike.
If we use the boost (acceleration) signal as the attenuator, that delayed impact does not occur, making the boost component more precise.
The threshold value for suppression needs to be a bit higher to achieve equivalence.
I've re-named the function to reflect it being related to spike suppression and removed 'jerk' since we aren't using that any more.
This commit is contained in:
ctzsnooze 2019-09-07 11:22:06 +10:00
parent ab4328f293
commit e381b27b9c
5 changed files with 16 additions and 17 deletions

View file

@ -1343,7 +1343,7 @@ static bool blackboxWriteSysinfo(void)
currentPidProfile->pid[PID_YAW].F);
#ifdef USE_INTERPOLATED_SP
BLACKBOX_PRINT_HEADER_LINE("ff_interpolate_sp", "%d", currentPidProfile->ff_interpolate_sp);
BLACKBOX_PRINT_HEADER_LINE("ff_jerk_limit", "%d", currentPidProfile->ff_jerk_limit);
BLACKBOX_PRINT_HEADER_LINE("ff_spike_limit", "%d", currentPidProfile->ff_spike_limit);
BLACKBOX_PRINT_HEADER_LINE("ff_max_rate_limit", "%d", currentPidProfile->ff_max_rate_limit);
#endif
BLACKBOX_PRINT_HEADER_LINE("ff_boost", "%d", currentPidProfile->ff_boost);

View file

@ -1080,7 +1080,7 @@ const clivalue_t valueTable[] = {
#endif
#ifdef USE_INTERPOLATED_SP
{ "ff_interpolate_sp", VAR_UINT8 | PROFILE_VALUE | MODE_LOOKUP, .config.lookup = {TABLE_INTERPOLATED_SP}, PG_PID_PROFILE, offsetof(pidProfile_t, ff_interpolate_sp) },
{ "ff_jerk_limit", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = {0, 255}, PG_PID_PROFILE, offsetof(pidProfile_t, ff_jerk_limit) },
{ "ff_spike_limit", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = {0, 255}, PG_PID_PROFILE, offsetof(pidProfile_t, ff_spike_limit) },
{ "ff_max_rate_limit", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = {0, 150}, PG_PID_PROFILE, offsetof(pidProfile_t, ff_max_rate_limit) },
#endif
{ "ff_boost", VAR_UINT8 | PROFILE_VALUE, .config.minmaxUnsigned = { 0, 50 }, PG_PID_PROFILE, offsetof(pidProfile_t, ff_boost) },

View file

@ -60,7 +60,6 @@ FAST_CODE_NOINLINE float interpolatedSpApply(int axis, bool newRcFrame, ffInterp
const float setpointSpeed = (rawSetpoint - prevRawSetpoint[axis]) * rxRate;
const float setpointAcceleration = (setpointSpeed - prevSetpointSpeed[axis]) * pidGetDT();
const float setpointJerk = setpointAcceleration - prevSetpointAcceleration[axis];
setpointDeltaImpl[axis] = setpointSpeed * pidGetDT();
@ -68,8 +67,8 @@ FAST_CODE_NOINLINE float interpolatedSpApply(int axis, bool newRcFrame, ffInterp
float clip = 1.0f;
float boostAmount = 0.0f;
if (ffBoostFactor != 0.0f) {
if (pidGetJerkLimitInverse()) {
clip = 1 / (1 + fabsf(setpointJerk * pidGetJerkLimitInverse()));
if (pidGetSpikeLimitInverse()) {
clip = 1 / (1 + fabsf(setpointAcceleration * pidGetSpikeLimitInverse()));
clip *= clip;
}
@ -83,10 +82,10 @@ FAST_CODE_NOINLINE float interpolatedSpApply(int axis, bool newRcFrame, ffInterp
prevRawSetpoint[axis] = rawSetpoint;
if (axis == FD_ROLL) {
DEBUG_SET(DEBUG_FF_INTERPOLATED, 0, setpointDeltaImpl[axis] * 1000);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 1, boostAmount * 1000);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 2, boostAmount * clip * 1000);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 3, setpointJerk * 1000);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 0, setpointDeltaImpl[axis] * 100);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 1, boostAmount * 100);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 2, boostAmount * clip * 100);
DEBUG_SET(DEBUG_FF_INTERPOLATED, 3, clip * 100);
}
setpointDeltaImpl[axis] += boostAmount * clip;
if (type == FF_INTERPOLATE_ON) {

View file

@ -213,7 +213,7 @@ void resetPidProfile(pidProfile_t *pidProfile)
.idle_pid_limit = 200,
.idle_max_increase = 150,
.ff_interpolate_sp = FF_INTERPOLATE_AVG,
.ff_jerk_limit = 25,
.ff_spike_limit = 40,
.ff_max_rate_limit = 100,
.ff_boost = 15,
);
@ -314,11 +314,11 @@ static FAST_RAM_ZERO_INIT pt1Filter_t airmodeThrottleLpf2;
static FAST_RAM_ZERO_INIT pt1Filter_t antiGravityThrottleLpf;
static FAST_RAM_ZERO_INIT float ffBoostFactor;
static FAST_RAM_ZERO_INIT float ffJerkLimitInverse;
static FAST_RAM_ZERO_INIT float ffSpikeLimitInverse;
float pidGetJerkLimitInverse()
float pidGetSpikeLimitInverse()
{
return ffJerkLimitInverse;
return ffSpikeLimitInverse;
}
@ -466,7 +466,7 @@ void pidInitFilters(const pidProfile_t *pidProfile)
pt1FilterInit(&antiGravityThrottleLpf, pt1FilterGain(ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF, dT));
ffBoostFactor = (float)pidProfile->ff_boost / 10.0f;
ffJerkLimitInverse = pidProfile->ff_jerk_limit ? 1.0f / ((float)pidProfile->ff_jerk_limit / 10.0f) : 0.0f;
ffSpikeLimitInverse = pidProfile->ff_spike_limit ? 1.0f / ((float)pidProfile->ff_spike_limit / 10.0f) : 0.0f;
}
#ifdef USE_RC_SMOOTHING_FILTER

View file

@ -183,7 +183,7 @@ typedef struct pidProfile_s {
uint8_t ff_interpolate_sp; // Calculate FF from interpolated setpoint
uint8_t ff_max_rate_limit; // Maximum setpoint rate percentage for FF
uint8_t ff_jerk_limit; // FF stick extrapolation lookahead period in ms
uint8_t ff_spike_limit; // FF stick extrapolation lookahead period in ms
} pidProfile_t;
PG_DECLARE_ARRAY(pidProfile_t, PID_PROFILE_COUNT, pidProfiles);
@ -261,4 +261,4 @@ float pidGetPreviousSetpoint(int axis);
float pidGetDT();
float pidGetPidFrequency();
float pidGetFfBoostFactor();
float pidGetJerkLimitInverse();
float pidGetSpikeLimitInverse();