4. 电流环设计(上):PI控制器原理、数字实现与抗积分饱和

电流环,是电机控制三环中最内层的一环。说白了,它直接决定了力矩响应的快慢和精度。我见过不少新手,位置环和速度环调得挺顺,但电机一加载就抖,或者高速时电流失控——十有八九是电流环没打好基础。

这一章,我们就从最经典的PI控制器讲起。我会把原理、离散化方法、还有那个让人头疼的积分饱和问题,一次性说清楚。

4.1 PI控制器:为什么是它?

先问个问题:电机控制里,为什么PI是绝对主力?

你看,电流环的目标是让实际电流快速、无静差地跟踪给定值。P(比例)负责“快”,I(积分)负责“准”。

  • 比例项:误差一来,立刻输出。增益越大,响应越快,但太大就会振荡。
  • 积分项:把过去的误差累积起来。只要还有静差,积分就一直增长,直到误差为零。

我个人的习惯是,先把P调到一个不振荡的临界值,再慢慢加I。有一次在调试一个伺服驱动器时,P给大了,电流波形像锯齿一样,电机嗡嗡响。后来把P降了30%,再补上合适的I,波形一下就干净了。

核心公式(连续域):

u(t) = Kp * e(t) + Ki * ∫ e(τ) dτ

其中 e(t) = i_ref - i_fb,Kp是比例增益,Ki是积分增益。

4.2 从模拟到数字:离散化方法

MCU没法处理连续的积分,必须把公式离散化。常用的方法有两种:前向欧拉和后向欧拉。我推荐你用后向欧拉,原因后面说。

方法 积分近似 离散公式 特点
前向欧拉 用当前误差乘Ts u[k] = Kp*e[k] + Ki*Ts*Σe[k-1] 实现简单,但存在代数环风险
后向欧拉 用当前误差乘Ts u[k] = Kp*e[k] + Ki*Ts*Σe[k] 更稳定,无代数环,推荐使用

你想想看,前向欧拉用的是上一拍的积分和,如果这一拍误差突变,输出会滞后。后向欧拉直接用当前误差更新积分,响应更直接。我在项目里一直用后向欧拉,没出过问题。

代码实现(后向欧拉,C语言):

typedef struct {
    float Kp;
    float Ki;
    float integral;
    float out_max;  // 输出限幅
    float out_min;
} PI_Controller;

float PI_Update(PI_Controller *pi, float ref, float fb) {
    float err = ref - fb;
    pi->integral += pi->Ki * err;  // 注意:Ki已经包含了Ts
    float out = pi->Kp * err + pi->integral;
    // 限幅
    if (out > pi->out_max) out = pi->out_max;
    if (out < pi->out_min) out = pi->out_min;
    return out;
}

注意:这里的Ki是已经乘过采样周期Ts的,即 Ki_discrete = Ki_continuous * Ts。这样写效率更高。

4.3 积分饱和:隐藏的杀手

嗯,这里要注意。积分饱和是数字PI最容易踩的坑。

什么是积分饱和?当输出达到限幅值(比如PWM占空比100%)时,误差还在,积分项继续累积。等误差反向时,积分已经积了一大堆,需要很长时间才能退出来。这段时间里,控制器是失灵的。

我曾经在一个风机项目上吃过这个亏。启动时电流给定很大,积分迅速饱和。等电流降下来时,积分退得慢,导致电流过冲,差点烧了MOS管。从那以后,我每次写PI都会加上抗积分饱和。

4.4 抗积分饱和的三种主流方法

方法不少,我挑三种最实用的讲。

  1. 积分限幅法:给积分项单独设一个限幅值。简单粗暴,但有效。
  2. 积分冻结法:输出饱和时,停止积分更新。等退出饱和再恢复。
  3. 反向积分法(back-calculation):饱和时,把超出部分反馈回积分输入端,强制退饱和。效果最好,但多一个系数。
方法 实现难度 效果 适用场景
积分限幅 低 一般 对动态要求不高的场合
积分冻结 低 较好 大多数通用场合
反向积分 中 优秀 高性能伺服、快速起停

避坑指南: 我曾经在积分冻结法上犯过一个错——只冻结了积分累加,但忘了在饱和时把输出钳位。结果输出还是超了。记住:限幅一定要在积分冻结之后做,顺序不能乱。

4.5 带抗积分饱和的完整代码

下面是我个人最常用的实现,积分冻结法,简单可靠。

typedef struct {
    float Kp;
    float Ki;
    float integral;
    float out_max;
    float out_min;
} PI_Controller;

float PI_Update_AntiWindup(PI_Controller *pi, float ref, float fb) {
    float err = ref - fb;
    float out = pi->Kp * err + pi->integral;

    // 先限幅
    if (out > pi->out_max) {
        out = pi->out_max;
    } else if (out < pi->out_min) {
        out = pi->out_min;
    } else {
        // 只有输出在限幅范围内,才更新积分
        pi->integral += pi->Ki * err;
    }

    return out;
}

你看,逻辑很简单:输出没饱和,正常积分;饱和了,积分停。这样既保证了稳态精度,又避免了积分堆积。

4.6 本章知识结构图

下面这张图,把电流环PI设计的核心脉络串起来了。你可以把它当作一个检查清单。

电流环PI设计核心脉络 PI控制器 比例项 P 积分项 I 离散化(后向欧拉) 积分饱和 抗积分饱和 积分限幅 积分冻结 反向积分 推荐:积分冻结法 简单可靠,通用性强

4.7 小结

这一章我们干了三件事:

  • 理解了PI为什么是电流环的标配
  • 学会了用后向欧拉法把PI搬到MCU里
  • 掌握了积分饱和的成因和三种抗饱和方法