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。它的框图长这样:

速度环串联型PID结构图 目标速度 Σ + − 比例 P 积分 I 微分 D Σ 限幅 (0~100%) PWM输出 速度反馈 三个分量并行计算后求和,经过限幅输出到PWM模块 反馈回路将实际速度与目标速度比较,形成闭环控制

这个结构里,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控制器开始调起