mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-14 20:10:18 +03:00
Add late P boost to antigravity
This commit is contained in:
parent
de35df8e07
commit
d1bf5d0d11
3 changed files with 51 additions and 5 deletions
|
@ -270,7 +270,24 @@ void pidResetIterm(void)
|
||||||
void pidUpdateAntiGravityThrottleFilter(float throttle)
|
void pidUpdateAntiGravityThrottleFilter(float throttle)
|
||||||
{
|
{
|
||||||
if (pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) {
|
if (pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) {
|
||||||
pidRuntime.antiGravityThrottleHpf = throttle - pt1FilterApply(&pidRuntime.antiGravityThrottleLpf, throttle);
|
// calculate a boost factor for P in the same way as for I when throttle changes quickly
|
||||||
|
// at this point the variable antiGravityThrottleHpf is the lowpass of throttle
|
||||||
|
pidRuntime.antiGravityThrottleHpf = pt1FilterApply(&pidRuntime.antiGravityThrottleLpf, throttle);
|
||||||
|
// focus P boost on low throttle range only
|
||||||
|
if (throttle < 0.5f) {
|
||||||
|
pidRuntime.antiGravityPBoost = 0.5f - throttle;
|
||||||
|
} else {
|
||||||
|
pidRuntime.antiGravityPBoost = 0.0f;
|
||||||
|
}
|
||||||
|
// use lowpass to identify start of a throttle up, use this to reduce boost at start by half
|
||||||
|
if (pidRuntime.antiGravityThrottleHpf < throttle) {
|
||||||
|
pidRuntime.antiGravityPBoost *= 0.5f;
|
||||||
|
}
|
||||||
|
// high-passed throttle focuses boost on faster throttle changes
|
||||||
|
pidRuntime.antiGravityThrottleHpf = fabsf(throttle - pidRuntime.antiGravityThrottleHpf);
|
||||||
|
pidRuntime.antiGravityPBoost = pidRuntime.antiGravityPBoost * pidRuntime.antiGravityThrottleHpf;
|
||||||
|
// smooth the P boost at 3hz to remove the jagged edges and prolong the effect after throttle stops
|
||||||
|
pidRuntime.antiGravityPBoost = pt1FilterApply(&pidRuntime.antiGravitySmoothLpf, pidRuntime.antiGravityPBoost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,10 +840,19 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
||||||
|
|
||||||
// Dynamic i component,
|
// Dynamic i component,
|
||||||
if ((pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) && pidRuntime.antiGravityEnabled) {
|
if ((pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) && pidRuntime.antiGravityEnabled) {
|
||||||
pidRuntime.itermAccelerator = fabsf(pidRuntime.antiGravityThrottleHpf) * 0.01f * (pidRuntime.itermAcceleratorGain - 1000);
|
// traditional itermAccelerator factor for iTerm
|
||||||
DEBUG_SET(DEBUG_ANTI_GRAVITY, 1, lrintf(pidRuntime.antiGravityThrottleHpf * 1000));
|
pidRuntime.itermAccelerator = pidRuntime.antiGravityThrottleHpf * 0.01f * pidRuntime.itermAcceleratorGain;
|
||||||
}
|
|
||||||
DEBUG_SET(DEBUG_ANTI_GRAVITY, 0, lrintf(pidRuntime.itermAccelerator * 1000));
|
DEBUG_SET(DEBUG_ANTI_GRAVITY, 0, lrintf(pidRuntime.itermAccelerator * 1000));
|
||||||
|
// users AG Gain changes P boost
|
||||||
|
pidRuntime.antiGravityPBoost *= pidRuntime.itermAcceleratorGain;
|
||||||
|
// add some percentage of that slower, longer acting P boost factor to prolong AG effect on iTerm
|
||||||
|
pidRuntime.itermAccelerator += pidRuntime.antiGravityPBoost * 0.05f;
|
||||||
|
// set the final P boost amount
|
||||||
|
pidRuntime.antiGravityPBoost *= 0.02f;
|
||||||
|
} else {
|
||||||
|
pidRuntime.antiGravityPBoost = 0.0f;
|
||||||
|
}
|
||||||
|
DEBUG_SET(DEBUG_ANTI_GRAVITY, 1, lrintf(pidRuntime.itermAccelerator * 1000));
|
||||||
|
|
||||||
float agGain = pidRuntime.dT * pidRuntime.itermAccelerator * AG_KI;
|
float agGain = pidRuntime.dT * pidRuntime.itermAccelerator * AG_KI;
|
||||||
|
|
||||||
|
@ -1117,6 +1143,22 @@ void FAST_CODE pidController(const pidProfile_t *pidProfile, timeUs_t currentTim
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// calculating the PID sum
|
// calculating the PID sum
|
||||||
|
|
||||||
|
// P boost at the end of throttle chop
|
||||||
|
// attenuate effect if turning more than 50 deg/s, half at 100 deg/s
|
||||||
|
float agBoostAttenuator = fabsf(currentPidSetpoint) / 50.0f;
|
||||||
|
if (agBoostAttenuator < 1.0f) {
|
||||||
|
agBoostAttenuator = 1.0f;
|
||||||
|
}
|
||||||
|
const float agBoost = 1.0f + (pidRuntime.antiGravityPBoost / agBoostAttenuator);
|
||||||
|
pidData[axis].P *= agBoost;
|
||||||
|
if (axis == FD_ROLL){
|
||||||
|
DEBUG_SET(DEBUG_ANTI_GRAVITY, 2, lrintf(agBoost * 1000));
|
||||||
|
}
|
||||||
|
if (axis == FD_PITCH){
|
||||||
|
DEBUG_SET(DEBUG_ANTI_GRAVITY, 3, lrintf(agBoost * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
const float pidSum = pidData[axis].P + pidData[axis].I + pidData[axis].D + pidData[axis].F;
|
const float pidSum = pidData[axis].P + pidData[axis].I + pidData[axis].D + pidData[axis].F;
|
||||||
#ifdef USE_INTEGRATED_YAW_CONTROL
|
#ifdef USE_INTEGRATED_YAW_CONTROL
|
||||||
if (axis == FD_YAW && pidRuntime.useIntegratedYaw) {
|
if (axis == FD_YAW && pidRuntime.useIntegratedYaw) {
|
||||||
|
|
|
@ -253,8 +253,10 @@ typedef struct pidRuntime_s {
|
||||||
bool antiGravityEnabled;
|
bool antiGravityEnabled;
|
||||||
uint8_t antiGravityMode;
|
uint8_t antiGravityMode;
|
||||||
pt1Filter_t antiGravityThrottleLpf;
|
pt1Filter_t antiGravityThrottleLpf;
|
||||||
|
pt1Filter_t antiGravitySmoothLpf;
|
||||||
float antiGravityOsdCutoff;
|
float antiGravityOsdCutoff;
|
||||||
float antiGravityThrottleHpf;
|
float antiGravityThrottleHpf;
|
||||||
|
float antiGravityPBoost;
|
||||||
float ffBoostFactor;
|
float ffBoostFactor;
|
||||||
float itermAccelerator;
|
float itermAccelerator;
|
||||||
uint16_t itermAcceleratorGain;
|
uint16_t itermAcceleratorGain;
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF 15 // The anti gravity throttle highpass filter cutoff
|
#define ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF 15 // The anti gravity throttle highpass filter cutoff
|
||||||
|
#define ANTI_GRAVITY_SMOOTH_FILTER_CUTOFF 3 // The anti gravity P smoothing filter cutoff
|
||||||
|
|
||||||
static void pidSetTargetLooptime(uint32_t pidLooptime)
|
static void pidSetTargetLooptime(uint32_t pidLooptime)
|
||||||
{
|
{
|
||||||
|
@ -202,6 +203,7 @@ void pidInitFilters(const pidProfile_t *pidProfile)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pt1FilterInit(&pidRuntime.antiGravityThrottleLpf, pt1FilterGain(ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF, pidRuntime.dT));
|
pt1FilterInit(&pidRuntime.antiGravityThrottleLpf, pt1FilterGain(ANTI_GRAVITY_THROTTLE_FILTER_CUTOFF, pidRuntime.dT));
|
||||||
|
pt1FilterInit(&pidRuntime.antiGravitySmoothLpf, pt1FilterGain(ANTI_GRAVITY_SMOOTH_FILTER_CUTOFF, pidRuntime.dT));
|
||||||
|
|
||||||
pidRuntime.ffBoostFactor = (float)pidProfile->ff_boost / 10.0f;
|
pidRuntime.ffBoostFactor = (float)pidProfile->ff_boost / 10.0f;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +311,7 @@ void pidInitConfig(const pidProfile_t *pidProfile)
|
||||||
// of AG activity without excessive display.
|
// of AG activity without excessive display.
|
||||||
pidRuntime.antiGravityOsdCutoff = 0.0f;
|
pidRuntime.antiGravityOsdCutoff = 0.0f;
|
||||||
if (pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) {
|
if (pidRuntime.antiGravityMode == ANTI_GRAVITY_SMOOTH) {
|
||||||
pidRuntime.antiGravityOsdCutoff += ((pidRuntime.itermAcceleratorGain - 1000) / 1000.0f) * 0.25f;
|
pidRuntime.antiGravityOsdCutoff += (pidRuntime.itermAcceleratorGain / 1000.0f) * 0.25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_ITERM_RELAX)
|
#if defined(USE_ITERM_RELAX)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue