2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
24 #include "common/time.h"
25 #include "common/filter.h"
26 #include "common/axis.h"
30 #define MAX_PID_PROCESS_DENOM 16
31 #define PID_CONTROLLER_BETAFLIGHT 1
32 #define PID_MIXER_SCALING 1000.0f
33 #define PID_SERVO_MIXER_SCALING 0.7f
34 #define PIDSUM_LIMIT 500
35 #define PIDSUM_LIMIT_YAW 400
36 #define PIDSUM_LIMIT_MIN 100
37 #define PIDSUM_LIMIT_MAX 1000
39 #define PID_GAIN_MAX 250
40 #define F_GAIN_MAX 1000
41 #define D_MIN_GAIN_MAX 250
43 // Scaling factors for Pids for better tunable range in configurator for betaflight pid controller. The scaling is based on legacy pid controller or previous float
44 #define PTERM_SCALE 0.032029f
45 #define ITERM_SCALE 0.244381f
46 #define DTERM_SCALE 0.000529f
48 // The constant scale factor to replace the Kd component of the feedforward calculation.
49 // This value gives the same "feel" as the previous Kd default of 26 (26 * DTERM_SCALE)
50 #define FEEDFORWARD_SCALE 0.013754f
52 // Full iterm suppression in setpoint mode at high-passed setpoint rate > 40deg/sec
53 #define ITERM_RELAX_SETPOINT_THRESHOLD 40.0f
54 #define ITERM_RELAX_CUTOFF_DEFAULT 15
56 // Anti gravity I constant
57 #define ANTIGRAVITY_KI 0.34f; // if AG gain is 6, about 6 times iTerm will be added
58 #define ANTIGRAVITY_KP 0.0034f; // one fifth of the I gain on P by default
59 #define ITERM_ACCELERATOR_GAIN_OFF 0
60 #define ITERM_ACCELERATOR_GAIN_MAX 250
62 #define PID_ROLL_DEFAULT { 45, 80, 40, 120 }
63 #define PID_PITCH_DEFAULT { 47, 84, 46, 125 }
64 #define PID_YAW_DEFAULT { 45, 80, 0, 120 }
65 #define D_MIN_DEFAULT { 30, 34, 0 }
67 #define DTERM_LPF1_DYN_MIN_HZ_DEFAULT 75
68 #define DTERM_LPF1_DYN_MAX_HZ_DEFAULT 150
69 #define DTERM_LPF2_HZ_DEFAULT 150
88 SUPEREXPO_YAW_OFF
= 0,
94 PID_STABILISATION_OFF
= 0,
96 } pidStabilisationState_e
;
99 PID_CRASH_RECOVERY_OFF
= 0,
100 PID_CRASH_RECOVERY_ON
,
101 PID_CRASH_RECOVERY_BEEP
,
102 PID_CRASH_RECOVERY_DISARM
,
103 } pidCrashRecovery_e
;
105 typedef struct pidf_s
{
123 ITERM_RELAX_SETPOINT
,
124 ITERM_RELAX_TYPE_COUNT
,
127 typedef enum feedforwardAveraging_e
{
128 FEEDFORWARD_AVERAGING_OFF
,
129 FEEDFORWARD_AVERAGING_2_POINT
,
130 FEEDFORWARD_AVERAGING_3_POINT
,
131 FEEDFORWARD_AVERAGING_4_POINT
,
132 } feedforwardAveraging_t
;
134 #define MAX_PROFILE_NAME_LENGTH 8u
136 typedef struct pidProfile_s
{
137 uint16_t yaw_lowpass_hz
; // Additional yaw filter when yaw axis too noisy
138 uint16_t dterm_lpf1_static_hz
; // Static Dterm lowpass 1 filter cutoff value in hz
139 uint16_t dterm_notch_hz
; // Biquad dterm notch hz
140 uint16_t dterm_notch_cutoff
; // Biquad dterm notch low cutoff
142 pidf_t pid
[PID_ITEM_COUNT
];
144 uint8_t dterm_lpf1_type
; // Filter type for dterm lowpass 1
145 uint8_t itermWindupPointPercent
; // iterm windup threshold, percent motor saturation
146 uint16_t pidSumLimit
;
147 uint16_t pidSumLimitYaw
;
148 uint8_t pidAtMinThrottle
; // Disable/Enable pids on zero throttle. Normally even without airmode P and D would be active.
149 uint8_t levelAngleLimit
; // Max angle in degrees in level mode
151 uint8_t horizon_tilt_effect
; // inclination factor for Horizon mode
152 uint8_t horizon_tilt_expert_mode
; // OFF or ON
154 // Betaflight PID controller parameters
155 uint8_t anti_gravity_gain
; // AntiGravity Gain (was itermAcceleratorGain)
156 uint16_t yawRateAccelLimit
; // yaw accel limiter for deg/sec/ms
157 uint16_t rateAccelLimit
; // accel limiter roll/pitch deg/sec/ms
158 uint16_t crash_dthreshold
; // dterm crash value
159 uint16_t crash_gthreshold
; // gyro crash value
160 uint16_t crash_setpoint_threshold
; // setpoint must be below this value to detect crash, so flips and rolls are not interpreted as crashes
161 uint16_t crash_time
; // ms
162 uint16_t crash_delay
; // ms
163 uint8_t crash_recovery_angle
; // degrees
164 uint8_t crash_recovery_rate
; // degree/second
165 uint16_t crash_limit_yaw
; // limits yaw errorRate, so crashes don't cause huge throttle increase
167 uint16_t dterm_lpf2_static_hz
; // Static Dterm lowpass 2 filter cutoff value in hz
168 uint8_t crash_recovery
; // off, on, on and beeps when it is in crash recovery mode
169 uint8_t throttle_boost
; // how much should throttle be boosted during transient changes 0-100, 100 adds 10x hpf filtered throttle
170 uint8_t throttle_boost_cutoff
; // Which cutoff frequency to use for throttle boost. higher cutoffs keep the boost on for shorter. Specified in hz.
171 uint8_t iterm_rotation
; // rotates iterm to translate world errors to local coordinate system
172 uint8_t iterm_relax_type
; // Specifies type of relax algorithm
173 uint8_t iterm_relax_cutoff
; // This cutoff frequency specifies a low pass filter which predicts average response of the quad to setpoint
174 uint8_t iterm_relax
; // Enable iterm suppression during stick input
175 uint8_t acro_trainer_angle_limit
; // Acro trainer roll/pitch angle limit in degrees
176 uint8_t acro_trainer_debug_axis
; // The axis for which record debugging values are captured 0=roll, 1=pitch
177 uint8_t acro_trainer_gain
; // The strength of the limiting. Raising may reduce overshoot but also lead to oscillation around the angle limit
178 uint16_t acro_trainer_lookahead_ms
; // The lookahead window in milliseconds used to reduce overshoot
179 uint8_t abs_control_gain
; // How strongly should the absolute accumulated error be corrected for
180 uint8_t abs_control_limit
; // Limit to the correction
181 uint8_t abs_control_error_limit
; // Limit to the accumulated error
182 uint8_t abs_control_cutoff
; // Cutoff frequency for path estimation in abs control
183 uint8_t dterm_lpf2_type
; // Filter type for 2nd dterm lowpass
184 uint16_t dterm_lpf1_dyn_min_hz
; // Dterm lowpass filter 1 min hz when in dynamic mode
185 uint16_t dterm_lpf1_dyn_max_hz
; // Dterm lowpass filter 1 max hz when in dynamic mode
186 uint8_t launchControlMode
; // Whether launch control is limited to pitch only (launch stand or top-mount) or all axes (on battery)
187 uint8_t launchControlThrottlePercent
; // Throttle percentage to trigger launch for launch control
188 uint8_t launchControlAngleLimit
; // Optional launch control angle limit (requires ACC)
189 uint8_t launchControlGain
; // Iterm gain used while launch control is active
190 uint8_t launchControlAllowTriggerReset
; // Controls trigger behavior and whether the trigger can be reset
191 uint8_t use_integrated_yaw
; // Selects whether the yaw pidsum should integrated
192 uint8_t integrated_yaw_relax
; // Specifies how much integrated yaw should be reduced to offset the drag based yaw component
193 uint8_t thrustLinearization
; // Compensation factor for pid linearization
194 uint8_t d_min
[XYZ_AXIS_COUNT
]; // Minimum D value on each axis
195 uint8_t d_min_gain
; // Gain factor for amount of gyro / setpoint activity required to boost D
196 uint8_t d_min_advance
; // Percentage multiplier for setpoint input to boost algorithm
197 uint8_t motor_output_limit
; // Upper limit of the motor output (percent)
198 int8_t auto_profile_cell_count
; // Cell count for this profile to be used with if auto PID profile switching is used
199 uint8_t transient_throttle_limit
; // Maximum DC component of throttle change to mix into throttle to prevent airmode mirroring noise
200 char profileName
[MAX_PROFILE_NAME_LENGTH
+ 1]; // Descriptive name for profile
202 uint8_t dyn_idle_min_rpm
; // minimum motor speed enforced by the dynamic idle controller
203 uint8_t dyn_idle_p_gain
; // P gain during active control of rpm
204 uint8_t dyn_idle_i_gain
; // I gain during active control of rpm
205 uint8_t dyn_idle_d_gain
; // D gain for corrections around rapid changes in rpm
206 uint8_t dyn_idle_max_increase
; // limit on maximum possible increase in motor idle drive during active control
208 uint8_t feedforward_transition
; // Feedforward attenuation around centre sticks
209 uint8_t feedforward_averaging
; // Number of packets to average when averaging is on
210 uint8_t feedforward_smooth_factor
; // Amount of lowpass type smoothing for feedforward steps
211 uint8_t feedforward_jitter_factor
; // Number of RC steps below which to attenuate feedforward
212 uint8_t feedforward_boost
; // amount of setpoint acceleration to add to feedforward, 10 means 100% added
213 uint8_t feedforward_max_rate_limit
; // Maximum setpoint rate percentage for feedforward
215 uint8_t dterm_lpf1_dyn_expo
; // set the curve for dynamic dterm lowpass filter
216 uint8_t level_race_mode
; // NFE race mode - when true pitch setpoint calculation is gyro based in level mode
217 uint8_t vbat_sag_compensation
; // Reduce motor output by this percentage of the maximum compensation amount
219 uint8_t simplified_pids_mode
;
220 uint8_t simplified_master_multiplier
;
221 uint8_t simplified_roll_pitch_ratio
;
222 uint8_t simplified_i_gain
;
223 uint8_t simplified_d_gain
;
224 uint8_t simplified_pi_gain
;
225 uint8_t simplified_dmin_ratio
;
226 uint8_t simplified_feedforward_gain
;
227 uint8_t simplified_dterm_filter
;
228 uint8_t simplified_dterm_filter_multiplier
;
229 uint8_t simplified_pitch_pi_gain
;
231 uint8_t anti_gravity_cutoff_hz
;
232 uint8_t anti_gravity_p_gain
;
233 uint8_t tpa_mode
; // Controls which PID terms TPA effects
234 uint8_t tpa_rate
; // Percent reduction in P or D at full throttle
235 uint16_t tpa_breakpoint
; // Breakpoint where TPA is activated
238 PG_DECLARE_ARRAY(pidProfile_t
, PID_PROFILE_COUNT
, pidProfiles
);
240 typedef struct pidConfig_s
{
241 uint8_t pid_process_denom
; // Processing denominator for PID controller vs gyro sampling rate
242 uint8_t runaway_takeoff_prevention
; // off, on - enables pidsum runaway disarm logic
243 uint16_t runaway_takeoff_deactivate_delay
; // delay in ms for "in-flight" conditions before deactivation (successful flight)
244 uint8_t runaway_takeoff_deactivate_throttle
; // minimum throttle percent required during deactivation phase
247 PG_DECLARE(pidConfig_t
, pidConfig
);
249 union rollAndPitchTrims_u
;
250 void pidController(const pidProfile_t
*pidProfile
, timeUs_t currentTimeUs
);
252 typedef struct pidAxisData_s
{
261 typedef union dtermLowpass_u
{
262 pt1Filter_t pt1Filter
;
263 biquadFilter_t biquadFilter
;
264 pt2Filter_t pt2Filter
;
265 pt3Filter_t pt3Filter
;
268 typedef struct pidCoefficient_s
{
275 typedef struct pidRuntime_s
{
278 bool pidStabilisationEnabled
;
279 float previousPidSetpoint
[XYZ_AXIS_COUNT
];
280 filterApplyFnPtr dtermNotchApplyFn
;
281 biquadFilter_t dtermNotch
[XYZ_AXIS_COUNT
];
282 filterApplyFnPtr dtermLowpassApplyFn
;
283 dtermLowpass_t dtermLowpass
[XYZ_AXIS_COUNT
];
284 filterApplyFnPtr dtermLowpass2ApplyFn
;
285 dtermLowpass_t dtermLowpass2
[XYZ_AXIS_COUNT
];
286 filterApplyFnPtr ptermYawLowpassApplyFn
;
287 pt1Filter_t ptermYawLowpass
;
288 bool antiGravityEnabled
;
289 pt2Filter_t antiGravityLpf
;
290 float antiGravityOsdCutoff
;
291 float antiGravityThrottleD
;
292 float itermAccelerator
;
293 uint8_t antiGravityGain
;
294 float antiGravityPGain
;
295 pidCoefficient_t pidCoefficient
[XYZ_AXIS_COUNT
];
298 float horizonTransition
;
299 float horizonCutoffDegrees
;
300 float horizonFactorRatio
;
301 uint8_t horizonTiltExpertMode
;
302 float maxVelocity
[XYZ_AXIS_COUNT
];
303 float itermWindupPointInv
;
304 bool inCrashRecoveryMode
;
305 timeUs_t crashDetectedAtUs
;
306 timeDelta_t crashTimeLimitUs
;
307 timeDelta_t crashTimeDelayUs
;
308 int32_t crashRecoveryAngleDeciDegrees
;
309 float crashRecoveryRate
;
310 float crashGyroThreshold
;
311 float crashDtermThreshold
;
312 float crashSetpointThreshold
;
316 bool zeroThrottleItermReset
;
320 #ifdef USE_ITERM_RELAX
321 pt1Filter_t windupLpf
[XYZ_AXIS_COUNT
];
323 uint8_t itermRelaxType
;
324 uint8_t itermRelaxCutoff
;
327 #ifdef USE_ABSOLUTE_CONTROL
332 pt1Filter_t acLpf
[XYZ_AXIS_COUNT
];
333 float oldSetpointCorrection
[XYZ_AXIS_COUNT
];
337 pt2Filter_t dMinRange
[XYZ_AXIS_COUNT
];
338 pt2Filter_t dMinLowpass
[XYZ_AXIS_COUNT
];
339 float dMinPercent
[XYZ_AXIS_COUNT
];
341 float dMinSetpointGain
;
344 #ifdef USE_AIRMODE_LPF
345 pt1Filter_t airmodeThrottleLpf1
;
346 pt1Filter_t airmodeThrottleLpf2
;
349 #ifdef USE_RC_SMOOTHING_FILTER
350 pt3Filter_t feedforwardPt3
[XYZ_AXIS_COUNT
];
351 bool feedforwardLpfInitialized
;
352 uint8_t rcSmoothingDebugAxis
;
353 uint8_t rcSmoothingFilterType
;
354 #endif // USE_RC_SMOOTHING_FILTER
356 #ifdef USE_ACRO_TRAINER
357 float acroTrainerAngleLimit
;
358 float acroTrainerLookaheadTime
;
359 uint8_t acroTrainerDebugAxis
;
360 float acroTrainerGain
;
361 bool acroTrainerActive
;
362 int acroTrainerAxisState
[2]; // only need roll and pitch
366 uint8_t dynLpfFilter
;
369 uint8_t dynLpfCurveExpo
;
372 #ifdef USE_LAUNCH_CONTROL
373 uint8_t launchControlMode
;
374 uint8_t launchControlAngleLimit
;
375 float launchControlKi
;
378 #ifdef USE_INTEGRATED_YAW_CONTROL
379 bool useIntegratedYaw
;
380 uint8_t integratedYawRelax
;
383 #ifdef USE_THRUST_LINEARIZATION
384 float thrustLinearization
;
385 float throttleCompensateAmount
;
388 #ifdef USE_AIRMODE_LPF
389 float airmodeThrottleOffsetLimit
;
392 #ifdef USE_FEEDFORWARD
393 float feedforwardTransitionFactor
;
394 feedforwardAveraging_t feedforwardAveraging
;
395 float feedforwardSmoothFactor
;
396 float feedforwardJitterFactor
;
397 float feedforwardBoostFactor
;
401 pt3Filter_t attitudeFilter
[2]; // Only for ROLL and PITCH
405 extern pidRuntime_t pidRuntime
;
407 extern const char pidNames
[];
409 extern pidAxisData_t pidData
[3];
411 extern uint32_t targetPidLooptime
;
413 extern float throttleBoost
;
414 extern pt1Filter_t throttleLpf
;
416 void resetPidProfile(pidProfile_t
*profile
);
418 void pidResetIterm(void);
419 void pidStabilisationState(pidStabilisationState_e pidControllerState
);
420 void pidSetItermAccelerator(float newItermAccelerator
);
421 bool crashRecoveryModeActive(void);
422 void pidAcroTrainerInit(void);
423 void pidSetAcroTrainerState(bool newState
);
424 void pidUpdateTpaFactor(float throttle
);
425 void pidUpdateAntiGravityThrottleFilter(float throttle
);
426 bool pidOsdAntiGravityActive(void);
427 void pidSetAntiGravityState(bool newState
);
428 bool pidAntiGravityEnabled(void);
430 #ifdef USE_THRUST_LINEARIZATION
431 float pidApplyThrustLinearization(float motorValue
);
432 float pidCompensateThrustLinearization(float throttle
);
435 #ifdef USE_AIRMODE_LPF
436 void pidUpdateAirmodeLpf(float currentOffset
);
437 float pidGetAirmodeThrottleOffset();
441 #include "sensors/acceleration.h"
442 extern float axisError
[XYZ_AXIS_COUNT
];
443 void applyItermRelax(const int axis
, const float iterm
,
444 const float gyroRate
, float *itermErrorRate
, float *currentPidSetpoint
);
445 void applyAbsoluteControl(const int axis
, const float gyroRate
, float *currentPidSetpoint
, float *itermErrorRate
);
446 void rotateItermAndAxisError();
447 float pidLevel(int axis
, const pidProfile_t
*pidProfile
,
448 const rollAndPitchTrims_t
*angleTrim
, float currentPidSetpoint
, float horizonLevelStrength
);
449 float calcHorizonLevelStrength(void);
451 void dynLpfDTermUpdate(float throttle
);
452 void pidSetItermReset(bool enabled
);
453 float pidGetPreviousSetpoint(int axis
);
455 float pidGetPidFrequency();
456 float pidGetFeedforwardBoostFactor();
457 float pidGetFeedforwardSmoothFactor();
458 float pidGetFeedforwardJitterFactor();
459 float pidGetFeedforwardTransitionFactor();
460 float dynLpfCutoffFreq(float throttle
, uint16_t dynLpfMin
, uint16_t dynLpfMax
, uint8_t expo
);