3. PI控制器原理:比例(P)与积分(I)的作用、PI控制器的数字实现、积分饱和与抗饱和策略
好,咱们进入速度环最核心的部分——PI控制器。说实话,很多工程师调了半天参数,其实对PI到底在干什么并不清楚。今天我就把这块掰开揉碎了讲清楚。
3.1 比例(P)与积分(I)的作用
先问个问题:为什么速度环非要用PI,光用P行不行?
比例控制(P),说白了就是「看现在」。当前速度偏差有多大,我就给多大的力。你想想看,如果目标转速1000rpm,实际只有800rpm,偏差200rpm,P项就会输出一个正比于200rpm的控制量。
但P有个硬伤——静差。我在项目中遇到过一台伺服,纯P控制下,空载时精度还行,一加载转速就掉下来20rpm,怎么调P都拉不回来。为什么?因为P的输出必须依赖偏差存在,偏差越小输出越小,最后系统会在某个非零偏差处「妥协」。
核心结论:比例控制响应快,但无法消除稳态误差。
积分控制(I),则是「算旧账」。它把过去所有的偏差累加起来,只要偏差存在,积分项就会一直增长。哪怕偏差只有1rpm,积分项也会随时间慢慢变大,直到把偏差彻底吃掉。
嗯,这里要注意:积分是把双刃剑。我见过有人把积分时间设得太小,结果系统一启动就超调30%,来回震荡好几秒才稳住。积分太强,系统会「过冲」;积分太弱,又消除不了静差。
| 参数 | 作用 | 调大效果 | 调小效果 |
|---|---|---|---|
| 比例增益 Kp | 快速响应偏差 | 响应变快,可能震荡 | 响应变慢,静差增大 |
| 积分时间 Ti | 消除稳态误差 | 积分作用减弱,消除慢 | 积分作用增强,易超调 |
我的经验:调参时先调P,让系统不震荡,再慢慢加I。加I时从大到小调(比如Ti从100ms往下减),看到超调就停手,往回退一点。
3.2 PI控制器的数字实现
模拟时代用运放搭PI,现在都是单片机里算。数字PI的实现方式有两种:位置式和增量式。
位置式PI,直接算当前时刻的控制量:
u(k) = Kp * e(k) + Ki * sum(e(i)) // i从0到k
其中Ki = Kp * T / Ti,T是采样周期。这个公式很直观,但有个问题——每次都要累加所有历史偏差,万一溢出就麻烦了。
增量式PI,只算当前时刻相比上一时刻的变化量:
Δu(k) = Kp * [e(k) - e(k-1)] + Ki * e(k)
u(k) = u(k-1) + Δu(k)
我个人习惯用增量式。为什么?因为增量式天然带限幅保护,而且不会出现积分项溢出后输出跳变的情况。我在做一款低压伺服时,位置式PI在长时间运行后积分项累加到了10万,一断电重启输出直接飞了——换成增量式就再没出过这问题。
实际代码片段(增量式PI,C语言):
typedef struct {
float Kp;
float Ki;
float Kd; // 微分项,速度环一般不用
float out_max; // 输出限幅
float out_min;
float integral; // 积分累加值
float last_err; // 上次偏差
} PI_Controller;
float PI_Update(PI_Controller *pi, float target, float actual) {
float err = target - actual;
float delta_u = pi->Kp * (err - pi->last_err) + pi->Ki * err;
pi->last_err = err;
float out = pi->integral + delta_u;
// 限幅
if (out > pi->out_max) out = pi->out_max;
if (out < pi->out_min) out = pi->out_min;
pi->integral = out; // 关键:用限幅后的值更新积分
return out;
}
注意:增量式PI中,积分项是用输出值来更新的。如果输出被限幅了,积分项也会被限住——这其实就是一种抗饱和策略。
3.3 积分饱和与抗饱和策略
积分饱和,是PI控制器最头疼的问题之一。我曾经调试一台大惯量转台,启动时目标转速1000rpm,实际转速从0开始爬。偏差一直很大,积分项疯狂累加,等实际转速到达目标时,积分项已经累到了输出限幅值的3倍!结果转速直接冲过目标,超调了40%。
为什么会这样?因为积分项在偏差大时「积」得太多了,等偏差变小甚至反向时,积分项还很大,需要很长时间才能「消化」掉。
常见的抗饱和策略有几种:
- 积分限幅法:给积分项单独设一个上限,比如输出限幅的80%。简单粗暴,但有效。
- 积分分离法:偏差大于某个阈值时,停止积分。偏差小回来再恢复。我常用这个方法,阈值一般设为额定转速的5%。
- 反计算法(Back-calculation):当输出饱和时,把超出部分反馈回积分项,让它「退」回来。算法稍复杂,但效果最好。
避坑指南:我曾经在量产项目里只用积分限幅,结果某批次电机惯量偏大,积分限幅设得太死,导致稳态精度不够。后来改成积分分离+限幅双重保护,才彻底解决。所以抗饱和策略最好组合使用,别指望一招鲜。
最后说一句,PI参数不是调一次就完事的。负载变化、温度变化、甚至电源电压波动,都会影响PI的表现。我习惯在调试时留一组「保守参数」和一组「激进参数」,现场根据实际情况切换。嗯,这就是经验了。