PID anti-windup: conditional integration (back-calculation lite)

This commit is contained in:
2026-10-10 10:12:42 +08:00
parent 30540d884d
commit 5b24b956d2
2 changed files with 92 additions and 13 deletions
+16 -13
View File
@@ -91,21 +91,24 @@ static void pid_compute(void) {
return;
}
/* 位置式 PID */
/* 位置式 PID(带抗积分饱和):输出饱和时积分仅沿退饱和方向更新,
防止升温段积分顶满后长时间维持 100% 输出(此前实测目标 50℃ 冲到 59℃) */
float err = s_target - t;
s_integral += err;
{
/* 积分限幅(抗饱和):积分项贡献不超过满量程 */
float imax = 100.0f / HEATER_PID_KI;
if (s_integral > imax) s_integral = imax;
if (s_integral < -imax) s_integral = -imax;
}
float deriv = err - s_prev_err;
s_prev_err = err;
float u_noi = HEATER_PID_KP * err
+ HEATER_PID_KD * (err - s_prev_err); /* 比例 + 微分 */
float integ_new = s_integral + err;
float u = u_noi + HEATER_PID_KI * integ_new;
float u = HEATER_PID_KP * err + HEATER_PID_KI * s_integral + HEATER_PID_KD * deriv;
if (u < 0.0f) u = 0.0f; /* 降温靠自然散热,输出不为负 */
if (u > 100.0f) u = 100.0f;
if (u > 100.0f) {
u = 100.0f;
if (err < 0.0f) s_integral = integ_new; /* 超上限:仅误差为负(降温方向)才吸收 */
} else if (u < 0.0f) {
u = 0.0f;
if (err > 0.0f) s_integral = integ_new; /* 超下限:仅误差为正(升温方向)才吸收 */
} else {
s_integral = integ_new; /* 未饱和:正常积分 */
}
s_prev_err = err;
/* 输出量化到 10% 档位(四舍五入) */
s_duty10 = (uint8_t)((u + (float)HEATER_PWM_STEP_PCT / 2.0f) / (float)HEATER_PWM_STEP_PCT);