第四章 预测模型:状态空间模型、传递函数模型、阶跃响应模型
说到MPC的预测模型,我琢磨了很久该怎么讲清楚。说白了,预测模型就是MPC的"水晶球"——你得靠它看到未来。没有这个水晶球,后面的优化控制全是空谈。
我个人习惯把预测模型分成三类来理解:状态空间模型、传递函数模型、阶跃响应模型。这三种模型各有各的脾气,也各有各的用武之地。今天咱们就一个一个把它们掰开揉碎了讲。
4.1 状态空间模型——我最常用的"老伙计"
状态空间模型,说白了就是用一组一阶微分方程来描述系统。你想想看,一个复杂的工业过程,可能涉及温度、压力、流量好多个变量,状态空间模型就能把这些变量之间的关系理得清清楚楚。
标准形式长这样:
x(k+1) = A·x(k) + B·u(k)
y(k) = C·x(k) + D·u(k)
其中 x 是状态向量,u 是输入,y 是输出。A、B、C、D 就是系统矩阵。
我在项目中遇到过一件事:有个化工反应器的温度控制,用传递函数怎么调都不对劲。后来换成状态空间模型,把反应器内部的温度分布作为状态变量,一下子就搞定了。为什么?因为状态空间模型能捕捉系统内部的动态特性,而不仅仅是输入输出关系。
4.2 传递函数模型——经典控制的老本行
传递函数模型,搞控制的人应该都不陌生。它用拉普拉斯变换把微分方程变成了代数方程,用起来特别方便。
嗯,这里要注意:传递函数模型只适用于线性时不变系统。如果你遇到的是非线性系统,或者参数随时间变化,那传递函数就不太够用了。
一个小技巧:从传递函数转到状态空间模型,可以用可控标准型或可观标准型。我建议你记住这个转换方法,因为很多实际工程中,我们拿到的是传递函数,但MPC需要的是状态空间模型。
% 从传递函数转到状态空间
G = tf([1 2], [1 3 2]); % 传递函数
sys = ss(G); % 转成状态空间
4.3 阶跃响应模型——工业现场的最爱
阶跃响应模型,这个我得好好说说。你想想看,在工业现场,你给系统一个阶跃输入,然后记录输出响应,这不就是最直观的建模方式吗?
阶跃响应模型的数学表达是这样的:
y(k) = y(0) + Σ S(i)·Δu(k-i)
其中 S(i) 是阶跃响应系数,Δu 是输入的变化量。这个模型的好处是:不需要知道系统的内部结构,只需要实验数据。
我曾经踩过一个坑:用阶跃响应模型做MPC时,采样时间选得太大了。结果预测出来的轨迹跟实际系统差了十万八千里。后来才明白,阶跃响应模型的精度很大程度上取决于采样时间的选择。采样时间太大,会丢失系统的动态信息;采样时间太小,模型阶数又太高。
4.4 三种模型的对比与选择
这三种模型到底选哪个?我个人的经验是这样的:
| 模型类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 状态空间模型 | 能描述内部动态,适合多变量系统 | 需要知道系统结构,参数辨识复杂 | 复杂工业过程、航空航天 |
| 传递函数模型 | 形式简单,经典控制理论成熟 | 只适用于SISO系统,非线性处理困难 | 单变量系统、教学演示 |
| 阶跃响应模型 | 不需要模型结构,直接从数据得到 | 模型阶数高,对噪声敏感 | 工业现场、过程控制 |
4.5 从模型到预测——核心逻辑
有了预测模型,我们怎么用它来做预测呢?说白了就是:给定当前的状态和未来的控制输入,用模型算出未来的输出。
以状态空间模型为例,预测的公式是这样的:
Y_p = F·x(k) + G·U
其中 Y_p 是预测的输出序列,U 是未来的控制输入序列,F 和 G 是由系统矩阵 A、B、C 计算得到的预测矩阵。
关键点:预测矩阵 F 和 G 是离线计算好的,在线运行时只需要做矩阵乘法。这就是MPC能实时运行的原因之一。
下面这张图展示了预测模型在MPC中的核心位置:
4.6 实战:用Python实现状态空间预测
光说不练假把式。咱们来看看怎么用Python实现状态空间模型的预测:
import numpy as np
class StateSpacePredictor:
def __init__(self, A, B, C, D):
self.A = A
self.B = B
self.C = C
self.D = D
def predict(self, x0, U, N):
"""
x0: 初始状态
U: 未来控制输入序列,形状 (N, m)
N: 预测时域
"""
n = self.A.shape[0] # 状态维度
p = self.C.shape[0] # 输出维度
# 初始化预测矩阵
F = np.zeros((p*N, n))
G = np.zeros((p*N, N))
# 计算F矩阵
for i in range(N):
F[i*p:(i+1)*p, :] = self.C @ np.linalg.matrix_power(self.A, i+1)
# 计算G矩阵
for i in range(N):
for j in range(i+1):
G[i*p:(i+1)*p, j] = self.C @ np.linalg.matrix_power(self.A, i-j) @ self.B
# 计算预测输出
Y_p = F @ x0 + G @ U.flatten()
return Y_p.reshape(N, p)
使用建议:在实际项目中,我一般会把预测矩阵F和G离线算好,存起来。在线运行时只需要做矩阵乘法,速度能快不少。
4.7 模型失配怎么办?
说实话,完美的模型是不存在的。模型和实际系统之间总会有差距,这就是模型失配。我在做项目时遇到过好几次,模型预测得挺好,一上实际系统就翻车。
怎么处理?我的经验是:
- 加反馈校正:用实际输出和预测输出的差值来修正预测
- 在线辨识:实时更新模型参数
- 鲁棒设计:在优化问题中加入约束,让控制器对模型误差不那么敏感
这三种方法各有千秋。我个人比较喜欢加反馈校正,简单有效,而且不会增加太多计算量。
好了,关于预测模型就讲这么多。记住一点:模型是MPC的基石,模型选得好,后面的事就顺了。选模型的时候,多想想你的系统是什么特点,现场能拿到什么数据,计算资源够不够用。这些实际问题,往往比理论推导更重要。