卡尔曼滤波是工业场景中经典的数据去噪 / 状态估计算法,PLC 实现卡尔曼滤波的核心是:简化单变量卡尔曼公式(适配 PLC 算力)+ 用结构化文本(ST)编写迭代逻辑(梯形图 LD 适合逻辑控制,数值计算优先 ST)。以下是从原理简化、变量定义到主流 PLC(西门子 / 三菱)的完整实现方案,以「PLC 采集模拟量(如温度 / 位移)去噪」为例。
一、先明确:PLC 适配的卡尔曼滤波简化版(单变量)
工业现场 PLC 采集的传感器数据(如 4-20mA 电流、0-10V 电压)多为单变量时序数据,无需复杂的矩阵运算,简化后核心公式如下(A=1,B=0,无控制输入 U):
| 阶段 | 公式 | 说明 | |||
|---|---|---|---|---|---|
| 预测 | 状态预测:$\hat {X}_{k | k-1} = \hat{X}_{k-1 | k-1}$ | 假设当前状态 = 上一时刻最优状态(无系统变化) | |
| 协方差预测:$P_{k | k-1} = P_{k-1 | k-1} + Q$ | = 过程噪声协方差(表征系统模型误差,如机械振动、电路漂移) | ||
| 更新 | 卡尔曼增益:$K_k = \frac {P_{k | k-1}}{P_{k | k-1} + R}$ | = 测量噪声协方差(表征传感器误差,如温漂、电磁干扰) | |
| 状态更新:$\hat {X}_{k | k} = \hat{X}_{k | k-1} + K_k \times (Z_k - \hat{X}_{k | k-1})$ | = 当前传感器测量值,修正预测值得到最优估计 | |
| 协方差更新:$P_{k | k} = (1 - K_k) \times P_{k | k-1}$ | 更新协方差,为下一周期预测做准备 |
二、PLC 实现核心规则(避坑)
三、西门子 S7-1200/1500(TIA Portal)实现示例
步骤 1:变量定义(PLC 变量表)
| 变量名 | 数据类型 | 地址 | 说明 | 初始值 |
|---|---|---|---|---|
| Z_k | REAL | PIW256 | 传感器测量值(如 4-20mA 转 REAL 后的值) | 0.0 |
| X_hat_k | REAL | DB1.DBD0 | 第 k 次滤波后最优估计值(输出) | 0.0 |
| X_hat_k_1 | REAL | DB1.DBD4 | 上一周期最优估计值(缓存) | 0.0 |
| P_k | REAL | DB1.DBD8 | 第 k 次协方差 | 1.0 |
| P_k_1 | REAL | DB1.DBD12 | 上一周期协方差(缓存) | 1.0 |
| K_k | REAL | DB1.DBD16 | 卡尔曼增益 | 0.0 |
| Q | REAL | DB1.DBD20 | 过程噪声协方差(可调) | 0.01 |
| R | REAL | DB1.DBD24 | 测量噪声协方差(可调) | 0.1 |
| Init_Flag | BOOL | DB1.DBX28.0 | 初始化标志 | FALSE |
步骤 2:ST 代码(定时中断 OB35,周期 100ms)
st
// 卡尔曼滤波核心逻辑(西门子S7-1200/1500 ST代码) PROGRAM OB35 VAR // 临时变量(无需定义到DB,仅中断内使用) P_k_predict: REAL; // 协方差预测值 END_VAR // 第一步:初始化(首次运行时执行) IF NOT Init_Flag THEN X_hat_k := Z_k; // 初始最优值=第一个测量值 X_hat_k_1 := X_hat_k; // 缓存初始值 P_k := 1.0; // 初始协方差 P_k_1 := P_k; // 缓存初始协方差 Init_Flag := TRUE; // 置位初始化完成标志 RETURN; // 初始化后退出本次中断 END_IF; // 第二步:预测阶段 P_k_predict := P_k_1 + Q; // 协方差预测 // 状态预测:X_hat_k_predict = X_hat_k_1(无需赋值,直接复用) // 第三步:更新阶段 K_k := P_k_predict / (P_k_predict + R); // 计算卡尔曼增益 X_hat_k := X_hat_k_1 + K_k * (Z_k - X_hat_k_1); // 状态更新 P_k := (1.0 - K_k) * P_k_predict; // 协方差更新 // 第四步:缓存当前值,为下一周期准备 X_hat_k_1 := X_hat_k; P_k_1 := P_k;
四、三菱 FX5U/Q(GX Works3)实现示例
三菱 FX5U/Q 支持 ST 语言,逻辑与西门子一致,仅变量定义和语法略有差异。
步骤 1:变量定义(软元件 / 标签)
| 标签名 | 数据类型 | 软元件 | 说明 | 初始值 |
|---|---|---|---|---|
| Z_k | REAL | D100 | 传感器测量值(AD 转换后的值,如温度) | 0.0 |
| X_hat_k | REAL | D200 | 滤波后输出值 | 0.0 |
| X_hat_k_1 | REAL | D204 | 上一周期最优值 | 0.0 |
| P_k | REAL | D208 | 当前协方差 | 1.0 |
| P_k_1 | REAL | D212 | 上一周期协方差 | 1.0 |
| K_k | REAL | D216 | 卡尔曼增益 | 0.0 |
| Q | REAL | D220 | 过程噪声 | 0.01 |
| R | REAL | D224 | 测量噪声 | 0.1 |
| Init_Flag | BOOL | M100 | 初始化标志 | FALSE |
步骤 2:ST 代码(定时中断程序,如 100ms)
st
// 三菱FX5U/Q 卡尔曼滤波ST代码 // 定时中断程序(设置为100ms执行一次) IF Init_Flag = FALSE THEN // 初始化 X_hat_k := Z_k; X_hat_k_1 := X_hat_k; P_k := 1.0; P_k_1 := P_k; Init_Flag := TRUE; RETURN; END_IF; // 预测阶段 VAR_TEMP P_k_predict: REAL; // 临时变量 END_VAR; P_k_predict := P_k_1 + Q; // 更新阶段 K_k := P_k_predict / (P_k_predict + R); X_hat_k := X_hat_k_1 + K_k * (Z_k - X_hat_k_1); P_k := (1.0 - K_k) * P_k_predict; // 缓存值 X_hat_k_1 := X_hat_k; P_k_1 := P_k;
五、关键调参技巧(PLC 场景适配)
卡尔曼滤波的核心是调Q和R,需根据现场传感器特性调整:
| 参数 | 取值原则 | 示例场景 |
|---|---|---|
| Q | 系统越稳定(如静态温度采集),Q 越小(0.001~0.01);系统动态变化大(如位移),Q 越大(0.01~0.1) | 温度采集:Q=0.01;电机转速:Q=0.05 |
| R | 传感器精度越高(如进口温变),R 越小(0.05~0.1);传感器噪声大(如普通电位器),R 越大(0.1~0.5) | 4-20mA 高精度传感器:R=0.1;电位器:R=0.3 |
六、PLC 实现注意事项
七、扩展:梯形图触发滤波(适配新手)
若习惯用梯形图,可将 ST 滤波逻辑封装为功能块(FB),梯形图仅做:
比如西门子梯形图触发 FB:
plaintext
// 梯形图逻辑 LD SM0.0 // 始终ON CALL FB_KalmanFilter // 调用卡尔曼滤波FB Z_k := PIW256, X_hat_k := DB1.DBD0, Q := 0.01, R := 0.1
如果需要针对具体场景(如 PLC 采集电机转速、液压压力滤波)调整代码,或补充欧姆龙 / 罗克韦尔 PLC 的实现版本,可告知具体 PLC 型号和采集参数,我会细化到可直接下载使用的程度。

