模型预测控制(Model Predictive Control, MPC)作为现代控制理论的重要分支,其核心在于"滚动优化"和"反馈校正"两大机制。与传统的PID控制不同,MPC具有处理多变量、带约束控制问题的天然优势。让我们先从一个直观的类比开始理解:
想象你在驾驶汽车时,不会只盯着眼前一米的路况,而是会观察前方数十米的道路情况,根据预判提前调整方向盘和油门。MPC正是模拟了这种"前瞻性"控制策略,通过系统模型预测未来多个时刻的状态,并求解最优控制序列。
MPC的基础是系统的数学模型,通常采用离散状态空间表示:
code复制x(k+1) = Ax(k) + Bu(k)
y(k) = Cx(k)
其中A、B、C为系统矩阵,x为状态变量,u为控制输入。对于非线性系统,可通过泰勒展开在工作点附近线性化处理。在倒立摆案例中,我们正是通过小角度假设将非线性模型线性化。
注意:模型精度直接影响控制效果。实践中建议通过系统辨识或参数估计获取准确模型参数。
MPC在每个控制周期求解如下优化问题:
min J = Σ [x'(k)Qx(k) + u'(k)Ru(k)] + x'(N)Px(N)
其中:
这个二次型目标函数需要满足系统动力学约束以及可能存在的输入输出约束(如执行器饱和限制)。
MPC采用"预测-优化-执行-校正"的闭环策略:
这种机制使MPC具有天然的鲁棒性,能够克服模型失配和外部扰动的影响。在车辆控制案例中,正是这种实时校正能力保证了跟踪精度。
MATLAB的Control System Toolbox提供了完整的MPC解决方案。以双积分系统为例,进阶实现应关注:
matlab复制% 创建MPC控制器时建议指定采样时间
mpcobj = mpc(sys, Ts, PredictionHorizon, ControlHorizon);
% 约束设置(示例:限制控制量变化率)
mpcobj.MV.RateMin = -0.5;
mpcobj.MV.RateMax = 0.5;
% 权重调节技巧
mpcobj.Weights.OutputVariables = [1 0]; % 输出权重
mpcobj.Weights.ManipulatedVariables = 0.1; % 控制量权重
mpcobj.Weights.ManipulatedVariablesRate = 0.01; % 控制变化率权重
实测发现:预测时域通常设为响应时间的1.5-2倍,控制时域取预测时域的1/3-1/2效果最佳。
对于倒立摆等非线性系统,可采用以下策略:
matlab复制% 非线性MPC示例框架
nlobj = nlmpc(nx,ny,nu);
nlobj.Model.StateFcn = @pendulumStateFcn;
nlobj.Jacobian.StateFcn = @pendulumStateJacobian;
通过compare命令验证控制效果:
matlab复制[T,~,~] = sim(mpcobj,T,r);
[y,t,u] = sim(mpcobj,T,r);
compare(mpcobj,T,r)
调试建议:
C++实现需要解决三个核心问题:
改进后的MPC求解框架:
cpp复制#include <qpOASES.hpp> // 专业QP求解库
void solveMPC(const MatrixXd& A, const MatrixXd& B,
const MatrixXd& Q, const MatrixXd& R,
const VectorXd& x0, VectorXd& u_opt) {
// 构造QP问题
int N = 10; // 预测时域
MatrixXd H = /* 构造Hessian矩阵 */;
VectorXd f = /* 构造梯度向量 */;
MatrixXd A_const = /* 构造约束矩阵 */;
VectorXd lb, ub; // 约束边界
// 使用qpOASES求解
QProblem qp(N, 0); // 0表示无等式约束
qp.init(H.data(), f.data(), A_const.data(),
lb.data(), ub.data(), 0, 0);
VectorXd sol(N);
qp.getPrimalSolution(sol.data());
u_opt = sol.head(1); // 仅取第一步控制量
}
倒立摆状态方程:
code复制θ'' = (mglsinθ - bθ' + mlcosθu)/(I + ml²)
线性化后得到状态空间模型,MPC需要处理:
运动学模型:
code复制ẋ = v cosθ
ẏ = v sinθ
θ̇ = v tanδ/L
MPC设计要点:
通过大量工程实践总结的调参口诀:
典型参数范围:
现象:求解器返回不可行或数值错误
解决方法:
在车辆控制项目中,我们曾遇到GPS信号丢失的情况。通过增加基于IMD的状态估计器,并调整MPC的鲁棒性权重,最终实现了30秒盲跑仍能保持车道。
最近在无人机编队项目中,我们采用C++11实现的MPC控制器,在树莓派4B上达到了100Hz的稳定运行频率。关键是将Eigen矩阵运算与qpOASES求解器结合,并利用ARM NEON指令加速。