1. MPC模型预测控制概述
模型预测控制(Model Predictive Control,MPC)是现代控制工程中一种先进的控制策略,特别适用于多变量、有约束的复杂系统。与传统的PID控制相比,MPC具有明显的优势:
- 预测能力:基于系统模型预测未来一段时间内的行为
- 约束处理:能够显式考虑系统输入、输出和状态的约束
- 优化特性:在每个控制周期求解一个有限时域的优化问题
在实际工程中,MPC已广泛应用于:
- 自动驾驶车辆的轨迹跟踪
- 工业过程控制
- 机器人运动控制
- 航空航天领域
提示:MPC的核心思想是"滚动优化"——在每个控制周期,基于当前状态求解一个有限时域的最优控制问题,但只执行第一步的控制量,下一周期重新进行优化。
2. MPC基本原理与数学推导
2.1 预测模型构建
MPC的基础是系统的数学模型,通常采用离散状态空间表示:
code复制x(k+1) = A·x(k) + B·u(k)
y(k) = C·x(k)
其中:
- x ∈ ℝⁿ 是状态向量
- u ∈ ℝᵐ 是控制输入向量
- y ∈ ℝᵖ 是输出向量
- A,B,C 是系统矩阵
对于非线性系统,通常在工作点附近线性化或直接使用非线性模型。
2.2 目标函数设计
MPC在每个时刻k求解如下优化问题:
code复制min J = Σ [x'(k+i|k)Qx(k+i|k) + u'(k+i|k)Ru(k+i|k)]
其中:
- Q ≥ 0 是状态权重矩阵
- R > 0 是控制权重矩阵
- N 是预测时域长度
2.3 约束处理
MPC可以处理多种约束:
- 控制输入约束:u_min ≤ u(k) ≤ u_max
- 状态约束:x_min ≤ x(k) ≤ x_max
- 输出约束:y_min ≤ y(k) ≤ y_max
这些约束直接作为优化问题的约束条件。
3. MPC实现方案
3.1 C++实现框架
C++实现采用模块化设计,主要组件包括:
- MPC求解器核心:
cpp复制class MPCSolver {
public:
struct Param {
int N; // 预测步长
double dt; // 采样周期
Eigen::MatrixXd Q, R; // 权重矩阵
Eigen::VectorXd uLower, uUpper; // 控制约束
};
bool solve(const State& x0, const RefTraj& ref, ControlSeq* u);
};
- 车辆模型:
- 双积分模型(2阶)
- 自行车模型(3阶)
- 单轨模型(4阶)
- 可视化接口:
基于GLFW和Dear ImGui实现实时可视化,支持参数在线调整。
3.2 MATLAB实现框架
MATLAB实现更侧重算法验证和快速原型开发:
matlab复制function u = SolveLinearMPC(A,B,C,Q,R,low,high,x0,refs,N)
% 构建QP问题
H = blkdiag(kron(eye(N),R), kron(eye(N-1),Q));
f = zeros(N*size(u,1)+(N-1)*size(x,1),1);
% 调用quadprog求解
options = optimoptions('quadprog','Display','off');
u = quadprog(H,f,[],[],[],[],low,high,[],options);
end
4. 工程案例详解
4.1 双积分系统控制
双积分系统是最基础的MPC验证案例:
状态方程:
code复制dx/dt = v
dv/dt = u
MATLAB实现关键步骤:
- 定义系统矩阵
- 设计权重Q,R
- 设置预测时域N
- 调用MPC求解器
典型参数:
matlab复制Q = diag([10, 1]); % 位置权重>速度权重
R = 0.1; % 控制量权重
N = 10; % 预测步长
Ts = 0.1; % 采样时间
4.2 倒立摆控制
倒立摆是典型的非线性不稳定系统,线性化后的状态方程:
code复制x = [θ, θ̇, x, ẋ]ᵀ
u = F (作用力)
控制难点:
- 非线性特性强
- 需要同时平衡和位置控制
解决方案:
- 在工作点附近线性化
- 调整Q矩阵使摆角权重更高
4.3 车辆运动学控制
自行车模型状态方程:
code复制ẋ = v·cos(θ)
ẏ = v·sin(θ)
θ̇ = v/L·tan(δ)
MPC任务:
- 路径跟踪
- 速度规划
关键参数:
- 前视距离
- 曲率约束
- 加速度限制
4.4 车辆动力学控制
单轨模型更接近真实车辆动力学:
状态变量:
code复制x = [y, v_y, φ, r]ᵀ
控制输入:
code复制u = [δ, a]ᵀ
实现要点:
- 离散化模型
- 设计权重矩阵
- 设置约束条件
- 实时求解
5. 实现技巧与注意事项
5.1 数值稳定性处理
- 权重矩阵缩放:
cpp复制// 典型做法是将状态量纲统一
Q.diagonal() << 1.0, 0.1, 1.0, 0.1;
R.diagonal() << 0.01;
- 约束软化:
对于可能冲突的约束,引入松弛变量避免无解。
5.2 实时性优化
-
热启动:
重用上一周期的解作为初始猜测。 -
代码优化:
- 使用Eigen的Map避免内存拷贝
- 固定大小矩阵优于动态矩阵
- 启用编译器优化(-O3)
- 求解器选择:
- OSQP:通用性强
- qpOASES:嵌入式友好
- acados:专门为MPC优化
5.3 调试技巧
- 可视化分析:
- 状态轨迹
- 控制输入
- 优化目标值
- 参数调节经验:
- 先调Q保证稳定性
- 再调R平滑控制
- 最后调整N平衡实时性和性能
- 常见问题排查:
code复制问题:求解时间过长
检查:1. 问题规模 2. 求解器配置 3. 热启动
问题:控制振荡
检查:1. R矩阵权重 2. 预测时域 3. 模型精度
6. 工程部署建议
6.1 从MATLAB到C++
迁移路径:
- 在MATLAB中验证算法
- 使用MATLAB Coder生成C代码
- 集成到C++框架
- 替换求解器为嵌入式兼容版本
6.2 嵌入式实现考虑
- 内存管理:
- 预分配所有内存
- 避免动态内存分配
- 实时性保证:
- 固定计算时间
- 看门狗监控
- 降级策略
- 数值精度:
- 32位浮点测试
- 定点数实现
6.3 测试验证方案
- 单元测试:
- 模型一致性
- 求解器正确性
- 闭环测试:
- 软件在环(SIL)
- 硬件在环(HIL)
- 实车测试:
- 逐步扩大操作范围
- 安全监控机制
7. 扩展与进阶
7.1 非线性MPC
处理强非线性系统的方案:
- 连续线性化(LTV-MPC)
- 直接非线性优化
- 神经网络近似
7.2 鲁棒MPC
考虑模型不确定性的方法:
- 最小-最大MPC
- 随机MPC
- 管式MPC
7.3 学习型MPC
结合机器学习:
- 模型学习
- 代价函数学习
- 约束学习
在实际项目中,我们通常从线性MPC开始,根据需求逐步引入更复杂的特性。MPC的强大之处在于其统一的框架可以适应各种控制问题,但同时也需要工程师对优化理论和系统建模有深入理解。
