第二章:MPC数学基础——状态空间模型、离散化方法、二次规划(QP)问题、约束处理

各位同学,欢迎来到第二章。

说实话,MPC(模型预测控制)听起来挺唬人的。但拆开来看,核心就四个东西:状态空间模型离散化二次规划约束处理。搞懂了这四个,你就拿到了MPC的钥匙。

我个人习惯,讲数学之前先讲直觉。咱们先不推公式,先想想:你要控制一个系统,总得知道它长什么样吧?这就是状态空间模型。计算机只能处理离散数据,所以得把连续模型离散化。然后,你要在每一步算出一个最优的控制量,这就是二次规划。最后,你总不能把电机转速拉到一万转吧?这就是约束。

好,咱们一个一个来。

2.1 状态空间模型:系统的“身份证”

状态空间模型,说白了就是描述系统内部状态的数学工具。我刚开始做电机控制时,总觉得用传递函数就够了。直到有一次,我需要同时控制位置和速度,传递函数那套东西根本搞不定。嗯,从那以后,我就老老实实用状态空间了。

标准形式长这样:

连续时间状态空间方程:
ẋ(t) = A x(t) + B u(t)
y(t) = C x(t) + D u(t)

其中:
x(t) —— 状态向量(比如位置、速度)
u(t) —— 输入向量(比如电压、扭矩)
y(t) —— 输出向量(比如传感器读数)
A —— 系统矩阵(描述内部动态)
B —— 输入矩阵(描述输入如何影响状态)
C —— 输出矩阵(描述状态如何映射到输出)
D —— 前馈矩阵(通常为0)

关键点:状态变量必须能完全描述系统的未来行为。选错了状态变量,你的MPC就废了。

举个例子,一个简单的直流电机模型:

状态变量:x = [θ (角度), ω (角速度)]
输入:u = V (电枢电压)
输出:y = θ (角度)

A = [0, 1; 0, -b/J]
B = [0; Kt/J]
C = [1, 0]
D = [0]

其中 b 是阻尼系数,J 是转动惯量,Kt 是扭矩常数

我在项目中遇到过一个问题:有人把电机电流也当作状态变量,结果模型阶数太高,控制器跑不动。你想想看,MPC是要在线求解的,模型越复杂,计算量越大。所以,状态变量的选择要精炼

2.2 离散化方法:让计算机听懂你的模型

计算机是离散的,而物理世界是连续的。所以,你得把连续模型变成离散模型。常用的方法有三种:

方法 精度 计算量 适用场景
前向欧拉法 采样频率高、精度要求低
后向欧拉法 数值稳定性要求高
零阶保持法(ZOH) 工业标准,推荐使用

我个人习惯用零阶保持法。为什么?因为它假设输入在两个采样点之间保持不变,这跟实际DAC输出一模一样。我曾经试过用前向欧拉法,结果采样频率不够高时,模型直接发散。嗯,那场面,挺尴尬的。

离散化后的模型长这样:

离散时间状态空间方程:
x(k+1) = A_d x(k) + B_d u(k)
y(k) = C_d x(k) + D_d u(k)

其中:
A_d = e^(A*Ts)
B_d = ∫(0→Ts) e^(A*τ) dτ * B
C_d = C
D_d = D
Ts —— 采样时间

避坑指南:我曾经在STM32上实现MPC,采样时间设成了1ms,结果A_d矩阵计算用了0.5ms。你想想看,控制器还没算完,下一个采样点就到了。所以,采样时间的选择要综合考虑模型复杂度和处理器性能

2.3 二次规划(QP)问题:MPC的“大脑”

MPC的核心,就是在每个采样时刻,求解一个优化问题。这个优化问题,通常是一个二次规划(QP)问题。

标准形式:

minimize:  0.5 * z^T * H * z + f^T * z
subject to:  A_ineq * z ≤ b_ineq
             A_eq * z = b_eq
             lb ≤ z ≤ ub

其中:
z —— 决策变量(通常是未来N步的控制量和状态量)
H —— Hessian矩阵(必须是半正定)
f —— 梯度向量
A_ineq, b_ineq —— 不等式约束
A_eq, b_eq —— 等式约束
lb, ub —— 上下界约束

为什么是二次规划?因为MPC的目标函数通常是二次型:

J = Σ (x_ref - x)^T * Q * (x_ref - x) + Σ u^T * R * u

Q —— 状态权重矩阵(越大,跟踪越紧)
R —— 输入权重矩阵(越大,控制越平缓)

说白了,就是让状态尽量靠近目标,同时控制量不要太大。我刚开始做时,Q和R都是瞎调的。后来发现,Q和R的比值决定了系统的响应速度和控制能耗。你想想看,Q设得太大,系统响应快但容易震荡;R设得太大,系统反应慢得像老牛拉车。

注意:Hessian矩阵H必须是半正定的,否则QP问题可能无解。我在项目中遇到过,因为Q矩阵设成了负定,结果求解器直接报错。嗯,那一次排查了整整两天。

2.4 约束处理:MPC的“安全锁”

MPC最大的优势之一,就是能显式处理约束。没有约束的MPC,跟LQR没什么区别。

常见的约束类型:

  • 输入约束:u_min ≤ u ≤ u_max(比如电机最大电压)
  • 状态约束:x_min ≤ x ≤ x_max(比如位置极限)
  • 输出约束:y_min ≤ y ≤ y_max(比如传感器量程)
  • 变化率约束:Δu_min ≤ Δu ≤ Δu_max(比如加速度限制)

约束处理的核心,就是把它们全部写成线性不等式的形式,塞进QP问题里。

举个例子,输入约束:

u_min ≤ u(k) ≤ u_max

写成矩阵形式:
[ I ] * u ≤ u_max
[ -I ] * u ≤ -u_min

我曾经在无人机项目中,只加了输入约束,没加状态约束。结果无人机在急转弯时,姿态角超出了安全范围,差点炸机。嗯,从那以后,我再也不敢漏掉状态约束了。

经验之谈:约束越紧,可行域越小,QP求解越容易失败。所以,约束要尽量宽松,但必须保证安全。我一般会留10%-20%的余量。

2.5 知识体系总览

下面这张图,是我自己画的MPC数学基础框架。你把它存下来,以后写代码时对照着看。

MPC数学基础框架 状态空间模型 离散化方法 二次规划(QP) 约束处理 核心要素 • 状态变量选择 • A/B/C/D矩阵 • 连续时间模型 常用方法 • 前向欧拉法 • 后向欧拉法 • 零阶保持法(ZOH) 关键参数 • H矩阵(半正定) • Q/R权重矩阵 • 预测时域N 约束类型 • 输入约束 • 状态约束 • 变化率约束 MPC核心流程 连续模型 → 离散化 → 构建QP问题 → 加入约束 → 在线求解 四个模块缺一不可,任何一个出问题,MPC都跑不起来 💡 经验:先仿真验证模型,再上硬件

好了,这一章的内容就到这里。数学基础打牢了,后面写代码才不慌。下一章,咱们直接上代码,用Python实现一个完整的MPC控制器。


公众号:蓝海资料掘金营,微信deep3321