@@ -110,7 +110,12 @@ int32_t axisPID_P[FLIGHT_DYNAMICS_INDEX_COUNT], axisPID_I[FLIGHT_DYNAMICS_INDEX_
110
110
111
111
STATIC_FASTRAM pidState_t pidState [FLIGHT_DYNAMICS_INDEX_COUNT ];
112
112
113
- PG_REGISTER_PROFILE_WITH_RESET_TEMPLATE (pidProfile_t , pidProfile , PG_PID_PROFILE , 7 );
113
+ static EXTENDED_FASTRAM pt1Filter_t windupLpf [XYZ_AXIS_COUNT ];
114
+ static EXTENDED_FASTRAM uint8_t itermRelax ;
115
+ static EXTENDED_FASTRAM uint8_t itermRelaxType ;
116
+ static EXTENDED_FASTRAM float itermRelaxSetpointThreshold ;
117
+
118
+ PG_REGISTER_PROFILE_WITH_RESET_TEMPLATE (pidProfile_t , pidProfile , PG_PID_PROFILE , 8 );
114
119
115
120
PG_RESET_TEMPLATE (pidProfile_t , pidProfile ,
116
121
.bank_mc = {
@@ -206,6 +211,9 @@ PG_RESET_TEMPLATE(pidProfile_t, pidProfile,
206
211
207
212
.loiter_direction = NAV_LOITER_RIGHT ,
208
213
.navVelXyDTermLpfHz = NAV_ACCEL_CUTOFF_FREQUENCY_HZ ,
214
+ .iterm_relax_type = ITERM_RELAX_SETPOINT ,
215
+ .iterm_relax_cutoff = MC_ITERM_RELAX_CUTOFF_DEFAULT ,
216
+ .iterm_relax = ITERM_RELAX_OFF ,
209
217
);
210
218
211
219
void pidInit (void )
@@ -217,6 +225,10 @@ void pidInit(void)
217
225
cos_approx (DECIDEGREES_TO_RADIANS (pidProfile ()-> max_angle_inclination [FD_PITCH ]));
218
226
219
227
pidGainsUpdateRequired = false;
228
+
229
+ itermRelax = pidProfile ()-> iterm_relax ;
230
+ itermRelaxType = pidProfile ()-> iterm_relax_type ;
231
+ itermRelaxSetpointThreshold = MC_ITERM_RELAX_SETPOINT_THRESHOLD * MC_ITERM_RELAX_CUTOFF_DEFAULT / pidProfile ()-> iterm_relax_cutoff ;
220
232
}
221
233
222
234
bool pidInitFilters (void )
@@ -266,6 +278,10 @@ bool pidInitFilters(void)
266
278
biquadFilterInitLPF (& pidState [axis ].deltaLpfState , pidProfile ()-> dterm_lpf_hz , refreshRate );
267
279
}
268
280
281
+ for (int i = 0 ; i < XYZ_AXIS_COUNT ; i ++ ) {
282
+ pt1FilterInit (& windupLpf [i ], pidProfile ()-> iterm_relax_cutoff , refreshRate * 1e-6f );
283
+ }
284
+
269
285
pidFiltersConfigured = true;
270
286
271
287
return true;
@@ -552,6 +568,33 @@ static void FAST_CODE pidApplyFixedWingRateController(pidState_t *pidState, flig
552
568
#endif
553
569
}
554
570
571
+ static void FAST_CODE applyItermRelax (const int axis , const float gyroRate , float currentPidSetpoint , float * itermErrorRate )
572
+ {
573
+ const float setpointLpf = pt1FilterApply (& windupLpf [axis ], currentPidSetpoint );
574
+ const float setpointHpf = fabsf (currentPidSetpoint - setpointLpf );
575
+
576
+ if (itermRelax ) {
577
+ if (axis < FD_YAW || itermRelax == ITERM_RELAX_RPY ) {
578
+
579
+ const float itermRelaxFactor = MAX (0 , 1 - setpointHpf / itermRelaxSetpointThreshold );
580
+
581
+ if (itermRelaxType == ITERM_RELAX_SETPOINT ) {
582
+ * itermErrorRate *= itermRelaxFactor ;
583
+ } else if (itermRelaxType == ITERM_RELAX_GYRO ) {
584
+ * itermErrorRate = fapplyDeadbandf (setpointLpf - gyroRate , setpointHpf );
585
+ } else {
586
+ * itermErrorRate = 0.0f ;
587
+ }
588
+
589
+ if (axis == FD_ROLL ) {
590
+ DEBUG_SET (DEBUG_ITERM_RELAX , 0 , lrintf (setpointHpf ));
591
+ DEBUG_SET (DEBUG_ITERM_RELAX , 1 , lrintf (itermRelaxFactor * 100.0f ));
592
+ DEBUG_SET (DEBUG_ITERM_RELAX , 2 , lrintf (* itermErrorRate ));
593
+ }
594
+ }
595
+ }
596
+ }
597
+
555
598
static void FAST_CODE pidApplyMulticopterRateController (pidState_t * pidState , flight_dynamics_index_t axis )
556
599
{
557
600
const float rateError = pidState -> rateTarget - pidState -> gyroRate ;
@@ -605,7 +648,10 @@ static void FAST_CODE pidApplyMulticopterRateController(pidState_t *pidState, fl
605
648
const float motorItermWindupPoint = 1.0f - (pidProfile ()-> itermWindupPointPercent / 100.0f );
606
649
const float antiWindupScaler = constrainf ((1.0f - getMotorMixRange ()) / motorItermWindupPoint , 0.0f , 1.0f );
607
650
608
- pidState -> errorGyroIf += (rateError * pidState -> kI * antiWindupScaler * dT )
651
+ float itermErrorRate = rateError ;
652
+ applyItermRelax (axis , pidState -> gyroRate , pidState -> rateTarget , & itermErrorRate );
653
+
654
+ pidState -> errorGyroIf += (itermErrorRate * pidState -> kI * antiWindupScaler * dT )
609
655
+ ((newOutputLimited - newOutput ) * pidState -> kT * antiWindupScaler * dT );
610
656
611
657
// Don't grow I-term if motors are at their limit
0 commit comments