引言:当经典算法遇上现代需求
在工业自动化领域,PID 控制器如同老练的舵手,驾驭着无数复杂的控制过程。然而,面对快速变化的生产环境和越来越高的精度要求,传统的 PID 算法有时显得力不从心。特别是当系统出现大偏差时,积分项的"执着累加"往往成为双刃剑——既能消除稳态误差,又可能引发超调震荡。
今天,我们将深入探讨如何用结构化文本(ST)语言,实现一种更加智能的控制算法——变速积分 PID。这种算法如同给控制器装上了"智慧眼睛",能够根据偏差大小自动调整积分强度,在快速响应与平稳控制之间找到完美平衡。不同于简单的积分分离,变速积分实现了平滑过渡,避免了硬切换带来的冲击,特别适合需要高精度、高稳定性的工业场景。
1
下面是用 ST 语言实现的一个完整的变速积分 PID 功能块。代码采用模块化设计,包含完整的错误处理和抗饱和机制,可直接集成到 PLC 或 DCS 系统中使用。
FUNCTION_BLOCK FB_VariableRatePID
VAR_INPUT
// 输入参数
Setpoint: REAL; // 设定值
ProcessValue: REAL; // 过程值
Enable: BOOL := TRUE; // 功能块使能
// PID基本参数
Kp: REAL := 1.0; // 比例增益
Ti: REAL := 10.0; // 积分时间(秒)
Td: REAL := 0.0; // 微分时间(秒)
Ts: REAL := 0.1; // 采样时间(秒)
// 变速积分参数
ViThreshold: REAL := 10.0; // 变速积分阈值
ViMinFactor: REAL := 0.0; // 最小积分系数(通常为0)
// 输出限制
OutMin: REAL := 0.0; // 输出下限
OutMax: REAL := 100.0; // 输出上限
// 手动模式参数
ManualMode: BOOL := FALSE; // 手动模式
ManualValue: REAL := 0.0; // 手动输出值
// 跟踪模式(用于无扰切换)
TrackMode: BOOL := FALSE; // 跟踪模式
TrackValue: REAL := 0.0; // 跟踪值
END_VAR
VAR_OUTPUT
Output: REAL; // 控制输出
Error: REAL; // 当前误差
P_Term: REAL; // 比例项(调试用)
I_Term: REAL; // 积分项(调试用)
D_Term: REAL; // 微分项(调试用)
ViFactor: REAL; // 当前积分系数(监视用)
Status: DINT; // 状态码:0-正常,1-参数错误,2-饱和警告
END_VAR
VAR
// 内部状态变量
PrevError: REAL; // 上一次误差
PrevProcessValue: REAL; // 上一次过程值
Integral: REAL; // 积分累积值
PrevOutput: REAL; // 上一次输出值
// 时间管理
LastExecuteTime: DT; // 上次执行时间
FirstScan: BOOL := TRUE; // 首次扫描标志
// 微分计算选项
UsePVForDerivative: BOOL := TRUE; // TRUE:对PV微分,FALSE:对误差微分
END_VAR
VAR CONSTANT
EPSILON: REAL := 1E-6; // 防止除零的小常数
END_VAR
METHOD Execute: BOOL
VAR_INPUT
CurrentTime: DT; // 当前时间
END_VAR
VAR
DeltaTime: REAL; // 实际时间间隔
Ki: REAL; // 积分增益
Kd: REAL; // 微分增益
TempOutput: REAL; // 临时输出值
Beta: REAL; // 积分变速系数
DerivativeInput: REAL; // 微分输入
END_VAR
// 1. 初始化检查
IF FirstScan THEN
FirstScan := FALSE;
PrevError := 0.0;
Integral := 0.0;
PrevOutput := 0.0;
LastExecuteTime := CurrentTime;
Status := 0;
RETURN TRUE;
END_IF;
// 2. 参数有效性检查
IF NOT Enable THEN
Output := 0.0;
Status := 0;
RETURN FALSE;
END_IF;
IF (Ti < EPSILON) OR (Ts < EPSILON) OR (Kp < 0) THEN
Status := 1; // 参数错误
Output := PrevOutput;
RETURN FALSE;
END_IF;
// 3. 时间间隔计算
DeltaTime := REAL_TO_TIME(CurrentTime - LastExecuteTime) / 1000000.0; // 转换为秒
IF DeltaTime < 0.01 THEN // 最小执行间隔10ms
RETURN FALSE;
END_IF;
LastExecuteTime := CurrentTime;
// 4. 计算当前误差
Error := Setpoint - ProcessValue;
// 5. 计算变速积分系数(核心算法)
IF ViThreshold > EPSILON THEN
// 线性变速:偏差越大,积分作用越弱
Beta := 1.0 - MIN(ABS(Error) / ViThreshold, 1.0);
Beta := MAX(Beta, ViMinFactor);
ELSE
// 阈值为0或负值,退化为普通积分
Beta := 1.0;
END_IF;
ViFactor := Beta; // 输出供监视
// 6. 计算比例项
P_Term := Kp * Error;
// 7. 计算积分项(带变速系数)
Ki := Kp * (Ts / MAX(Ti, EPSILON));
Integral := Integral + Ki * Beta * Error;
I_Term := Integral;
// 8. 计算微分项
IF UsePVForDerivative THEN
// 对过程值微分,避免设定值变化带来的冲击
DerivativeInput := ProcessValue;
ELSE
DerivativeInput := Error;
END_IF;
Kd := Kp * (MAX(Td, 0.0) / Ts);
D_Term := Kd * (PrevProcessValue - ProcessValue); // 注意符号
PrevProcessValue := ProcessValue;
// 9. 计算初步输出
TempOutput := P_Term + I_Term + D_Term;
// 10. 抗积分饱和处理(Clamping法)
IF TempOutput > OutMax THEN
TempOutput := OutMax;
// 如果积分项仍在增大输出,则冻结积分
IF (Ki * Beta * Error) > 0 THEN
Integral := Integral - Ki * Beta * Error;
END_IF;
ELSIF TempOutput < OutMin THEN
TempOutput := OutMin;
// 如果积分项仍在减小输出,则冻结积分
IF (Ki * Beta * Error) < 0 THEN
Integral := Integral - Ki * Beta * Error;
END_IF;
END_IF;
// 11. 输出限幅
Output := LIMIT(OutMin, OutMax, TempOutput);
// 12. 手动/自动/跟踪模式处理
IF TrackMode THEN
Output := TrackValue;
Integral := TrackValue - P_Term - D_Term; // 无扰切换准备
ELSIF ManualMode THEN
Output := ManualValue;
Integral := ManualValue - P_Term - D_Term; // 无扰切换准备
END_IF;
// 13. 更新状态
PrevError := Error;
PrevOutput := Output;
// 14. 饱和状态检测
IF (Output >= OutMax - 0.1) OR (Output <= OutMin + 0.1) THEN
Status := 2; // 饱和警告
ELSE
Status := 0; // 正常
END_IF;
RETURN TRUE;
END_METHOD
// 复位方法
METHOD Reset: BOOL
FirstScan := TRUE;
Integral := 0.0;
PrevError := 0.0;
PrevOutput := 0.0;
Status := 0;
RETURN TRUE;
END_METHOD
2
变速积分核心算法(第 5、7 部分)
Beta := 1.0 - MIN(ABS(Error) / ViThreshold, 1.0);
Integral := Integral + Ki * Beta * Error;
这是整个功能块的灵魂。Beta系数在 0 到 1 之间连续变化,实现了积分强度的平滑调节。当误差超过阈值时,Beta降为 0,积分暂停;当误差很小时,Beta接近 1,积分全力作用。
抗饱和双重保护(第 10 部分)
程序结合了两种抗饱和策略:变速积分减少饱和风险,Clamping 法在输出饱和时冻结积分。这种双重保护大大增强了系统的鲁棒性。
无扰切换机制(第 12 部分)
通过调整积分项实现手动/自动/跟踪模式间的平滑切换,避免了模式切换时的输出跳变。
微分计算选项
提供了对误差微分或对过程值微分的选项。对过程值微分可以有效抑制设定值变化带来的冲击,这是工业实践中的常用技巧。
3
温度控制系统在化工反应釜温度控制中,设定值经常大幅变化。传统 PID 在升温阶段容易饱和,导致超调严重。使用变速积分 PID:
-
升温初期大偏差:积分作用弱,防止加热器长时间全功率运行
-
接近目标温度:积分作用增强,精准消除稳态误差
-
结果:升温速度快,超调小,稳态精度高
压力与流量控制液压系统、压缩机出口压力控制:
-
压力设定值变化时:防止积分项累积导致阀门动作过冲
-
负载突变时:自适应调整积分速度,快速恢复稳定
-
效果:压力波动小,系统响应平稳
张力控制系统薄膜生产、印刷机、卷绕设备:
-
启动阶段:大偏差时弱积分,避免张力冲击
-
稳态运行:小偏差时强积分,维持恒定张力
-
优势:材料拉伸均匀,减少断料风险
4
4.1
自适应变速积分
当前的变速积分阈值是固定的,可以考虑根据系统运行状态自适应调整:
// 伪代码:自适应阈值
IF SystemInSteadyState THEN
ViThreshold := ViThreshold * 0.8; // 稳态时减小阈值,提高精度
ELSE
ViThreshold := ViThreshold * 1.2; // 瞬态时增大阈值,增强鲁棒性
END_IF;
4.2
非线性变速函数
除了线性变化,可以尝试其他函数形式:
-
指数函数:Beta := EXP(-ABS(Error)/ViThreshold)
-
S 型函数:更平滑的过渡
-
分段函数:针对不同偏差区间采用不同策略
4.3
与先进算法结合
-
模糊 PID:用模糊规则动态调整变速积分参数
-
神经网络:训练网络预测最佳积分系数
-
模型预测控制(MPC):作为底层控制器,上层进行优化
4.4
多变量协调控制
对于多回路耦合系统,协调各回路的变速积分参数,避免相互干扰。
总结:智慧控制的新篇章
变速积分 PID 不是对传统 PID 的颠覆,而是一次优雅的进化。它保留了 PID 结构简单、易于理解的优点,同时通过巧妙的机制解决了长期困扰工程师的积分饱和问题。
在工业 4.0 和智能制造的大背景下,类似变速积分 PID 这样的"智慧微创新"具有特殊价值。它们不需要昂贵的硬件升级,不增加系统的复杂性,却能显著提升控制品质和能源效率。
最后,记住控制工程的核心哲学:最好的控制算法不是最复杂的,而是最适合被控对象特性和工艺需求的。变速积分 PID 正是这一理念的完美体现——用简单的智慧,解决复杂的问题。
作者注:本文提供的代码应用于具体系统时,请务必根据实际情况进行充分的测试和参数整定。控制系统的安全性和可靠性始终是第一位的。
2026年8月