4. PID控制器入门:比例(P)、积分(I)、微分(D)的作用,速度环中PID的典型结构
好,咱们进入正题。PID控制器,说白了就是三个字——比例、积分、微分。很多初学者一上来就被公式吓住了,其实没那么玄乎。我当年刚接触电机控制时,也觉得这东西高深莫测,后来在项目里调了几个月,才真正理解它到底在干什么。
你想想看,速度环要解决的问题是什么?就是让电机的实际转速,紧紧跟着你给的目标转速跑。但现实很骨感——有摩擦、有负载变化、有惯性。PID就是用来对付这些“捣乱分子”的。
4.1 比例控制(P)——最直接的响应
比例控制,说白了就是“看偏差,给力度”。
公式很简单:P_out = Kp × e(t),其中 e(t) 是目标速度减去当前速度的偏差。
偏差大,输出就大;偏差小,输出就小。这很符合直觉,对吧?
核心特点:
- 响应快,能迅速对偏差做出反应
- 但纯比例控制一定会留下稳态误差——也就是永远差那么一点点追不上目标
我在一个风机项目里遇到过这种情况:只加P,转速到90%目标值就上不去了,怎么调Kp都没用。这就是典型的稳态误差。为什么?因为当偏差很小时,比例输出也变小,刚好被摩擦力抵消了。
我的经验:Kp不是越大越好。调太大,系统会震荡,电机嗡嗡响,甚至过冲烧管子。我建议你先从一个小值开始,慢慢往上加,直到听到电机开始“抖”了,再往回退20%。
4.2 积分控制(I)——消除稳态误差的利器
积分控制,就是专门对付稳态误差的。
公式:I_out = Ki × ∫e(t) dt。它把过去所有的偏差都累加起来。只要偏差还在,积分项就会一直增长,直到把偏差彻底消除。
你可以把它想象成一个“记仇”的账本——你欠我一分,我就记着,直到你还清为止。
注意!积分也有副作用:
- 积分饱和(Integral Windup):当电机被卡住或启动时,偏差长时间很大,积分项会积累到非常高的值。等障碍消除后,这个巨大的积分值会让电机猛地冲出去,造成严重过冲。
- 我曾经在调试一个AGV小车的速度环时,忘了加积分限幅,结果电机启动时直接冲过了目标转速50%,差点把货物甩出去。
避坑指南:一定要给积分项加限幅,或者用积分分离(偏差大时停止积分)的方法。我个人的习惯是:积分限幅设为PWM最大值的10%~20%,够用就好。
4.3 微分控制(D)——提前预判的“刹车”
微分控制,看的是偏差的变化趋势。
公式:D_out = Kd × de(t)/dt。如果偏差正在快速减小(比如转速正在逼近目标),微分项会输出一个负值,相当于提前“刹车”,抑制过冲。
你想想看,比例和积分都是“事后”反应——偏差已经产生了才去纠正。微分则是“事前”预判——看到偏差要变大了,先拉一把。
微分的作用:
- 增加系统阻尼,抑制震荡
- 改善动态响应,减少超调量
- 但对噪声非常敏感——速度信号稍微抖一下,微分项就会放大这个抖动
我记得有一次在高速主轴电机上调试,速度反馈信号有轻微的编码器量化噪声。D项一加上去,PWM输出就开始高频抖动,电机发热严重。后来加了低通滤波才解决。
实战建议:在速度环中,D项通常用得比较保守,甚至很多场合只用PI。如果你要用D,务必先对速度反馈做滤波处理,否则噪声会让你怀疑人生。
4.4 速度环中PID的典型结构
好了,三个分量都讲完了。那在速度环里,它们是怎么组合的呢?
最常见的结构是串联型PID,也叫位置式PID。它的框图长这样:
这个结构里,P、I、D三个分量是并行计算的。偏差信号同时进入三条路径,各自算完后加起来,再经过限幅,最终输出到PWM模块。
为什么要有限幅?因为PWM占空比只能是0%~100%,你不能输出一个200%的占空比。限幅就是防止PID输出超出这个范围。
4.5 速度环PID的离散化实现
在实际的MCU里,我们没法做连续的积分和微分,只能每隔一个固定时间(比如1ms)算一次。这就是离散化。
最常见的实现方式是位置式PID:
// 位置式PID,速度环示例
typedef struct {
float Kp;
float Ki;
float Kd;
float integral; // 积分累加值
float prev_error; // 上一次的偏差
float integral_limit;// 积分限幅
float output_limit; // 输出限幅
} PID_Controller;
float PID_Update(PID_Controller *pid, float target, float current) {
float error = target - current;
// 比例项
float p_out = pid->Kp * error;
// 积分项(带限幅)
pid->integral += error;
if (pid->integral > pid->integral_limit) pid->integral = pid->integral_limit;
if (pid->integral < -pid->integral_limit) pid->integral = -pid->integral_limit;
float i_out = pid->Ki * pid->integral;
// 微分项
float d_out = pid->Kd * (error - pid->prev_error);
pid->prev_error = error;
// 求和
float output = p_out + i_out + d_out;
// 输出限幅
if (output > pid->output_limit) output = pid->output_limit;
if (output < -pid->output_limit) output = -pid->output_limit;
return output;
}
代码说明:
- 积分项加了限幅,防止积分饱和
- 微分项用的是“偏差变化量”,而不是“速度变化量”——两种都可以,但前者更常见
- 输出限幅要匹配PWM的物理范围,比如0~1000对应0%~100%占空比
4.6 三种PID变体,你该用哪种?
实际项目中,很少有人直接用完整的PID。根据应用场景,我们通常会做减法:
| 变体 | 适用场景 | 我的经验 |
|---|---|---|
| P控制器 | 对精度要求不高,但需要极快响应的场合 | 基本不用,稳态误差太大 |
| PI控制器 | 速度环的首选,90%的场景够用 | 我80%的项目都用PI,简单可靠 |
| PID控制器 | 需要快速响应且抑制过冲的场合 | 高速主轴、伺服系统会用,但调试麻烦 |
| PD控制器 | 积分作用不必要,但需要阻尼的场合 | 很少单独用,通常配合前馈 |
我的建议:如果你刚开始调速度环,先从PI开始。把P和I调顺了,如果发现过冲太大且响应不够快,再考虑加一点点D。别一上来就三个参数一起调,你会疯掉的。
4.7 本章小结
好,咱们捋一捋今天的内容:
- P——看偏差给力度,响应快但有稳态误差
- I——消除稳态误差,但要注意积分饱和
- D——预判趋势抑制过冲,但对噪声敏感
- 速度环典型结构是串联型PID,三个分量并行计算后限幅输出
- 实际代码中要加积分限幅和输出限幅
- 新手建议从PI控制器开始调起