2. PI控制器基础:比例环节、积分环节与数字实现

各位工程师朋友,咱们今天聊聊PI控制器。这东西在电流环里太常见了,但很多人调了一辈子参数,其实没搞明白它到底在干什么。我刚开始做电机驱动那会儿,也是照着公式抄代码,直到有一次项目死活调不稳,才逼着自己把PI的底裤扒了个干净。

说白了,PI控制器就是两个东西的组合:一个比例,一个积分。它们各自干各自的活,配合好了,电流环就听话;配合不好,振荡就来了。

2.1 比例环节:当下误差的“即时反应”

比例环节,就是P。它的公式很简单:

u_p(t) = Kp * e(t)

其中e(t)是当前误差,Kp是比例增益。你想想看,误差越大,输出越大;误差为零,输出为零。这就是个放大器。

比例环节的核心作用:

  • 快速响应:误差一出现,立刻有输出。这是PI控制器里反应最快的部分。
  • 减小稳态误差:但注意,是“减小”,不是“消除”。纯比例控制一定有静差。
  • 影响系统刚度:Kp越大,系统对误差的“敏感度”越高,抗扰动能力越强。

关键认知:比例环节只关心“现在”。它不看过去,也不预测未来。误差大就猛推,误差小就轻推。这就是为什么纯P控制会有稳态误差——当误差小到一定程度,输出不足以克服摩擦力或负载时,系统就停在那里了。

我在项目中遇到过一件事:有个同事把Kp调得特别大,觉得这样响应快。结果电机一启动就尖叫,电流波形像锯齿。为什么?因为比例增益太大,系统进入了临界振荡。你想想看,P控制本质上就是个增益,增益太大,负反馈就变成了正反馈——这就是振荡的根源之一。

个人经验:我一般先给一个保守的Kp值,比如理论计算值的30%,然后慢慢往上加。加到电流波形开始出现轻微振荡时,退回来20%。这个点,就是比例增益的“甜区”。

2.2 积分环节:历史误差的“长期记忆”

积分环节,就是I。它的公式:

u_i(t) = Ki * ∫ e(τ) dτ

积分,说白了就是把过去所有的误差都加起来。只要过去有误差,积分项就不为零。这个特性太重要了——它让系统有了“记忆”。

积分环节的核心作用:

  • 消除稳态误差:这是积分存在的唯一理由。只要误差还在,积分项就会一直增长,直到输出把误差压到零。
  • 提供低频增益:积分在低频段增益无穷大,所以能抑制低频扰动。
  • 带来相位滞后:这是代价。积分环节会给系统引入-90度的相位滞后,容易引发振荡。

注意:积分环节是把双刃剑。它能消除静差,但也会让系统变“懒”。积分时间常数Ti(Ti = Kp/Ki)越大,积分作用越弱,消除静差越慢;Ti越小,积分作用越强,但越容易引起超调和振荡。

我曾经踩过一个坑:有个项目要求电流稳态误差必须小于0.5%,我为了达到指标,把Ki调得很大。结果呢?电流响应像过山车,超调30%,振荡了七八个周期才稳定下来。后来我才明白,积分环节的响应速度天生就慢——它需要时间累积误差。你逼它太快,它就给你振荡。

2.3 PI控制器的数学模型

把比例和积分加起来,就是标准的PI控制器:

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

或者写成更常用的形式:

u(t) = Kp * [ e(t) + (1/Ti) * ∫ e(τ) dτ ]

其中Ti = Kp/Ki,称为积分时间常数。这个形式更直观:比例决定“力度”,积分决定“持续时间”。

传递函数形式(拉普拉斯域):

G(s) = Kp + Ki/s = Kp * (1 + 1/(Ti * s))

你看这个式子,在s = 0处有一个极点(分母有s),这就是积分环节带来的。这个极点让系统在低频段有高增益,但也在相位上付出了代价。

数学本质:PI控制器在频域上相当于一个滞后校正器。它在低频段提供高增益(积分作用),在高频段保持恒定增益(比例作用)。转折频率在ω = Ki/Kp = 1/Ti处。这个转折频率的选择,直接决定了电流环的带宽和稳定性。

2.4 数字实现方式

好了,理论说完了,咱们看看代码怎么写。数字系统里,积分不能真的积分,得用累加来近似。

位置式PI算法:

// 位置式PI,直接计算输出
float PI_Controller(float error, float Kp, float Ki) {
    static float integral = 0.0f;
    float output;
    
    integral += error;           // 累加误差
    output = Kp * error + Ki * integral;  // 比例+积分
    
    return output;
}

这个写法最直观,但有个大问题:积分饱和。如果执行器饱和了(比如PWM占空比到100%),误差还在,积分项会一直累加。等误差反向时,积分项需要很长时间才能退回来——这就是“积分饱和”现象,会导致很大的超调。

抗积分饱和的改进写法:

// 带抗积分饱和的PI
float PI_Controller_AntiWindup(float error, float Kp, float Ki, float limit) {
    static float integral = 0.0f;
    float output, pre_sat_output;
    
    integral += error;
    pre_sat_output = Kp * error + Ki * integral;
    
    // 限幅
    if (pre_sat_output > limit) {
        output = limit;
        // 积分退绕:只累加未被限幅的部分
        integral -= error;  // 或者用更复杂的退绕算法
    } else if (pre_sat_output < -limit) {
        output = -limit;
        integral -= error;
    } else {
        output = pre_sat_output;
    }
    
    return output;
}

我个人习惯用增量式PI,尤其是在电流环这种需要快速响应的场合:

// 增量式PI,只计算变化量
float PI_Controller_Incremental(float error, float Kp, float Ki) {
    static float last_error = 0.0f;
    static float last_output = 0.0f;
    float delta_output;
    
    // 计算输出变化量
    delta_output = Kp * (error - last_error) + Ki * error;
    
    last_error = error;
    last_output += delta_output;
    
    return last_output;
}

三种实现方式的对比:

实现方式 优点 缺点 适用场景
位置式PI 直观,容易理解 积分饱和严重,需要额外处理 慢速系统,如温度控制
抗积分饱和PI 抑制饱和,响应快 实现稍复杂 大多数工业控制
增量式PI 无积分饱和,输出平滑 需要保存历史值 电流环、伺服控制

我的建议:电流环里,我几乎只用增量式PI。原因很简单——电流环的采样频率高(10kHz以上),积分饱和一旦发生,恢复时间可能长达几十个采样周期,这在电流环里是致命的。增量式天然没有积分饱和问题,而且输出变化平滑,对PWM调制更友好。

嗯,这里要注意一个细节:数字PI的采样时间Ts。所有公式里的积分累加,其实都隐含乘了Ts。如果你把Ki写成Ki = Kp * Ts / Ti,那代码里的integral += error * Ts才对。很多工程师在这里栽跟头——换了采样频率,参数就得重新调。

下面这张图,是我总结的PI控制器知识框架,帮你理清思路:

PI控制器知识框架 PI控制器知识框架 PI控制器 比例环节 (P) u = Kp * e 积分环节 (I) u = Ki * ∫e dt 比例特性 • 快速响应 • 减小稳态误差 • 影响系统刚度 积分特性 • 消除稳态误差 • 低频高增益 • 相位滞后 数字实现方式 位置式PI 直观,易积分饱和 抗积分饱和PI 抑制饱和,响应快 增量式PI 无饱和,输出平滑

这张图把PI控制器的核心要素都串起来了。左边是比例环节,右边是积分环节,下面是三种数字实现方式。你调参的时候,脑子里要有这张图——你调的是Kp和Ki,但影响的是响应速度、稳态精度和稳定性这三个维度。