diff --git a/src/main/common/maths.h b/src/main/common/maths.h index cc3d1bc517..fc8dbe3329 100644 --- a/src/main/common/maths.h +++ b/src/main/common/maths.h @@ -91,6 +91,7 @@ ) #define MIN(a, b) _CHOOSE(<, a, b) #define MAX(a, b) _CHOOSE(>, a, b) +#define SIGN(a) ((a >= 0) ? 1 : -1) #define _ABS_II(x, var) \ ( __extension__ ({ \ diff --git a/src/main/flight/pid.c b/src/main/flight/pid.c index 76784a1460..639b1e838c 100644 --- a/src/main/flight/pid.c +++ b/src/main/flight/pid.c @@ -816,6 +816,11 @@ static void FAST_CODE NOINLINE pidApplyMulticopterRateController(pidState_t *pid const float newOutput = newPTerm + newDTerm + pidState->errorGyroIf + newCDTerm; const float newOutputLimited = constrainf(newOutput, -pidState->pidSumLimit, +pidState->pidSumLimit); + float backCalc = newOutputLimited - newOutput;//back-calculation anti-windup + if (SIGN(backCalc) == SIGN(pidState->errorGyroIf)) { + //back calculation anti-windup can only shrink integrator, will not push it to the opposite direction + backCalc = 0.0f; + } float itermErrorRate = applyItermRelax(axis, rateTarget, rateError); #ifdef USE_ANTIGRAVITY @@ -824,7 +829,7 @@ static void FAST_CODE NOINLINE pidApplyMulticopterRateController(pidState_t *pid if (!pidState->itermFreezeActive) { pidState->errorGyroIf += (itermErrorRate * pidState->kI * antiWindupScaler * dT) - + ((newOutputLimited - newOutput) * pidState->kT * antiWindupScaler * dT); + + (backCalc * pidState->kT * antiWindupScaler * dT); } if (pidProfile()->pidItermLimitPercent != 0){