恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
MATLAB MPC仿真:从二次规划到闭环控制的全流程实现
首页
资讯中心
/
MATLAB MPC仿真:从二次规划到闭环控制的全流程实现
MATLAB MPC仿真:从二次规划到闭环控制的全流程实现
发布时间:2026/9/2 8:17:43
简介本资源是一套面向控制理论学习者与自动化工程实践者的MPC模型预测控制MATLAB仿真程序适用于高校控制类课程设计、科研入门及工业优化控制算法验证场景。压缩包共27个文件全部为.m脚本含主控函数main.m、约束MPC实现cmpc.m、拉盖尔网络lagc.m、动态MPC dmpc.m、二次规划求解quadraticPrograming.m等总大小仅15KB轻量易读便于逐行理解算法逻辑与模块分工。已有2476人下载学习反映出其在初学者进阶MPC建模、预测、滚动优化与实时控制律更新等核心环节中的实用价值。读者可直接运行仿真观察带约束条件下的闭环响应掌握状态空间建模、性能指标构造、QP求解接口调用及控制器参数整定等关键技能是深入理解模型预测控制原理与MATLAB工程实现的优质入门范例。1. 项目概述从理论到实践的MPC仿真之旅如果你正在学习或研究模型预测控制并且已经厌倦了那些只讲理论、不给代码的教材和论文那么你来对地方了。这个“MPC模型预测控制MATLAB仿真程序”项目正是为了解决这个痛点而生。它不是一个简单的、只能跑通一次的演示脚本而是一个结构清晰、模块化、可扩展的仿真框架旨在让你真正理解MPC从问题构建、优化求解到闭环仿真的每一个环节。MPC的核心魅力在于其“滚动优化”和“反馈校正”的思想。简单来说它不像传统的PID控制器那样只根据当前误差来决定控制动作。MPC更像一个“先知”它会基于当前系统的状态预测未来一段时间内系统的行为然后通过求解一个优化问题计算出未来一系列最优的控制输入。但最关键的是它只实施第一个控制量到了下一个时刻它会重新测量系统状态再次进行预测和优化如此循环往复。这种机制使得MPC能够天然地处理多变量、带约束比如阀门开度有上限、温度不能超标的复杂控制问题在过程控制、机器人、自动驾驶等领域应用广泛。然而理论上的优美往往伴随着实践上的门槛。QP二次规划求解、状态估计、约束处理、实时性挑战……每一个环节都可能让初学者望而却步。这个MATLAB仿真程序的价值就在于它剥开了这些复杂的外壳用可运行的代码展示了MPC的完整工作流程。无论你是控制专业的学生还是希望将MPC应用于实际项目的工程师通过拆解和运行这个程序你都能获得远超书本的直观感受和实操经验。接下来我将带你深入这个仿真程序的内部逐一拆解其设计思路、关键模块和实现细节。2. MPC仿真程序的整体架构与设计哲学一个健壮、易用的MPC仿真程序其架构设计远比实现几个算法函数更重要。好的架构能让我们像搭积木一样清晰地看到数据流、模块间的接口并且方便我们进行修改和调试。这个程序通常采用分层或模块化的设计思想我们可以将其核心结构分解为以下几个层次2.1 数据层与模型层一切的基石任何控制算法的起点都是被控对象的数学模型。在MPC中我们通常使用离散时间的状态空间模型形式为x(k1) A * x(k) B * u(k)y(k) C * x(k) D * u(k)其中x是状态向量u是控制输入向量y是输出向量A, B, C, D是相应的系统矩阵。在仿真程序中模型层不仅仅是一组矩阵。它应该被封装成一个独立的结构体或类对象。例如我们可以定义一个PlantModel类其属性包含A, B, C, D, dt采样时间其方法包含predict开环预测和update模型更新如果考虑自适应的话。这样做的好处是当我们需要更换被控对象模型时只需修改或替换这个模型对象而不需要去改动控制器的代码。数据层则负责在仿真过程中存储和传递数据。典型的仿真数据流是在每个采样时刻k控制器接收当前的状态测量值x(k)和参考轨迹r(k:kNp)经过计算输出控制量u(k)这个u(k)作用于被控对象模型模型计算出下一时刻的状态x(k1)和输出y(k1)然后x(k1)作为新的测量值反馈给控制器循环往复。程序需要清晰地维护这些随时间变化的序列如X_history,U_history,Y_history用于最后的绘图和分析。2.2 控制层MPC控制器的核心实现这是程序的心脏。一个完整的MPC控制器模块应该包含以下几个子功能预测方程构建根据模型(A, B, C)和预测时域Np、控制时域Nc通常Nc Np推导出未来状态/输出关于当前状态和未来控制输入的预测方程。通常我们会构建一个大的矩阵方程将未来Np步的输出向量Y表示为Y Psi * x(k) Theta * U的形式其中U是未来Nc步待优化的控制输入序列。这一步是纯数学推导可以在程序初始化时离线完成以提升在线计算效率。优化问题构建将控制目标转化为标准的优化问题形式。最常见的MPC目标是二次型性能指标J sum_{i1}^{Np} (y(ki) - r(ki))^T * Q * (y(ki) - r(ki)) sum_{i0}^{Nc-1} u(ki)^T * R * u(ki)其中Q和R是权重矩阵分别惩罚输出跟踪误差和控制量变化。将第一步的预测方程代入这个目标函数J经过整理J可以转化为一个关于优化变量U的标准二次型Quadratic形式J 1/2 * U^T * H * U f^T * U const。同时系统的物理约束如控制量幅值约束Umin u Umax控制增量约束DeltaUmin du DeltaUmax输出约束Ymin y Ymax也需要被转化为关于U的线性不等式约束A_ineq * U b_ineq。至此一个带约束的二次规划QP问题就构建完成了。QP求解器调用这是MPC在线计算中最耗时的部分。MATLAB提供了强大的优化工具箱我们可以使用quadprog函数来求解这个QP问题。在程序中我们需要将构建好的H, f, A_ineq, b_ineq矩阵以及等式约束如果有的话正确地传递给quadprog。一个重要的技巧是使用“热启动”warm start即将上一个采样时刻求解得到的最优控制序列U_opt作为当前时刻quadprog求解的初始猜测值这可以显著加快求解器的收敛速度。控制量提取与实现求解器返回的是未来Nc步的最优控制序列U_opt [u(k); u(k1); ...; u(kNc-1)]。根据MPC的滚动优化原则我们只取序列中的第一个元素u(k)施加给被控对象。同时我们可以将整个U_opt序列保存下来用于分析控制器的“前瞻”行为。2.3 仿真层与可视化层让结果说话仿真层负责将上述所有模块串联起来实现一个完整的闭环仿真循环。其伪代码逻辑如下初始化设定仿真时长 Tsim采样时间 dt初始化状态 x0初始化历史记录数组。 for k 0 : (Tsim/dt) % 1. 获取当前状态在仿真中直接从模型“真实状态”获取或加入噪声模拟测量 x_current X_real(:, k); % 2. 获取未来参考轨迹例如设定点或一条路径 r_future get_reference(k, Np); % 3. 调用MPC控制器 [u_opt, U_sequence] MPC_Solver(x_current, r_future); % 4. 施加控制量更新被控对象模型状态 x_next A * x_current B * u_opt; % 这里可以加入过程噪声 % 5. 存储数据 X_history(:, k1) x_next; U_history(:, k) u_opt; % 6. 更新循环 X_real(:, k1) x_next; end可视化层则是在仿真结束后通过绘图将控制效果直观地展示出来。至少应包含以下几个关键图表输出跟踪图绘制被控输出y和参考信号r随时间的变化直观展示跟踪精度和动态响应。控制输入图绘制控制量u随时间的变化检查其是否平滑、是否满足幅值约束。状态轨迹图绘制系统内部状态x的变化有助于深入理解系统动态。优化性能图可以绘制每个时刻的目标函数值J观察控制器的优化效果是否平稳。注意在架构设计时务必保持各模块间的“低耦合”。即模型模块的修改不应影响控制器模块的调用接口更换QP求解器比如从quadprog换为其他第三方库也应尽可能简单。这通常通过定义清晰的数据结构如model,config,data结构体和函数接口来实现。3. 核心模块深度解析与MATLAB实现要点理解了整体架构我们再来深入看看几个核心模块在MATLAB中具体如何实现以及有哪些容易踩坑的细节。3.1 系统建模与离散化精度与实时性的权衡在仿真中我们通常直接使用离散时间模型。但如果你的模型来源于连续时间的物理方程或传递函数离散化是第一步。MATLAB中常用c2d函数。这里有一个关键选择离散化方法。‘zoh’(零阶保持器)假设控制输入在采样周期内保持不变这是最常用也最符合数字控制器实现现实的方法。‘foh’(一阶保持器)假设控制输入在采样周期内线性变化精度更高但计算稍复杂。‘tustin’(双线性变换/塔斯廷变换)能保持频率响应的某种映射关系在需要关注频率特性的场合使用。实操要点对于大多数工业过程控制‘zoh’足矣。离散化时务必确保采样时间Ts选择合理。一个经验法则是采样频率应至少是系统闭环带宽的10倍。如果Ts太大离散化会引入较大误差甚至导致系统不稳定如果Ts太小则会不必要地增加在线计算负担。在程序中我们可以这样实现% 假设已有连续系统矩阵 Ac, Bc, Cc, Dc Ts 0.1; % 采样时间需要根据系统动态调整 sys_c ss(Ac, Bc, Cc, Dc); sys_d c2d(sys_c, Ts, ‘zoh’); [A, B, C, D] ssdata(sys_d);常见问题离散化后系统不稳定检查原连续系统是否稳定以及Ts是否过大。对于非常快的系统可能需要更小的Ts。3.2 预测方程与QP问题构建效率提升的关键这是MPC实现中公式推导最集中的部分。我们的目标是将未来输出表示为Y Psi * x(k) Theta * U。手动推导对于高阶系统非常繁琐且易错。在MATLAB程序中我们可以利用矩阵运算来批量构建Psi和Theta。构建Psi(与初始状态相关)Psi矩阵的每一块是C * A^i其中i从1到Np。我们可以用一个循环来构建Psi zeros(Np*ny, nx); % ny输出维度nx状态维度 for i 1:Np Psi((i-1)*ny1:i*ny, :) C * A^i; % 注意这里用的是离散系统的A矩阵 end构建Theta(与控制输入相关)Theta矩阵是一个下三角块矩阵其第i行、第j列块为C * A^(i-j) * B(当ij)否则为0。这里Nc是控制时域当j Nc时我们通常假设u(kj) u(kNc-1)即控制量保持不变。构建Theta需要仔细处理索引Theta zeros(Np*ny, Nc*nu); % nu控制输入维度 for i 1:Np for j 1:min(i, Nc) Theta((i-1)*ny1:i*ny, (j-1)*nu1:j*nu) C * A^(i-j) * B; end % 处理控制时域之后的部分如果iNc if i Nc for j Nc1:i % 实际上这部分的影响已经体现在了当jNc时使用A^(i-Nc)的项上 % 更严谨的做法是在构建U向量时将Nc之后的控制量用最后一个值表示 end end end在实际高效实现中我们常采用“紧凑形式”通过构建增广模型来简化Theta的计算并利用MATLAB的矩阵操作避免显式循环。构建QP矩阵H和f 根据性能指标J我们可以得到H Theta^T * Q_bar * Theta R_barf (Psi * x(k) - R_ref)^T * Q_bar * Theta其中Q_bar blkdiag(Q, Q, ..., Q)是块对角矩阵重复Np次R_bar类似R_ref是将未来Np步的参考轨迹堆叠成的列向量。Q_bar kron(eye(Np), Q); % 使用克罗内克积构建块对角矩阵 R_bar kron(eye(Nc), R); H Theta * Q_bar * Theta R_bar; % H矩阵是对称的quadprog要求H必须是正定或半正定 f (Psi * x_current - R_ref) * Q_bar * Theta;重要提示quadprog要求H矩阵是正定或半正定的以确保问题是凸的。R矩阵通常选择为正定对角阵如R r * eye(nu)r 0这能保证H的正定性。如果H不是正定的quadprog可能会报错或无法找到全局最优解。3.3 约束处理从理论到代码的桥梁约束是MPC强大能力的体现但也是实现中的难点。我们需要将各种物理约束统一转化为A_ineq * U b_ineq的形式。1. 控制量幅值约束Umin u(ki) Umax,i 0, ..., Nc-1。 这可以写成两个不等式u(ki) Umax-I * u(ki) Umax-u(ki) -Umin--I * u(ki) -Umin对于整个控制序列U [u(k); ...; u(kNc-1)]我们需要构建一个大的单位矩阵I_total kron(eye(Nc), eye(nu))。 那么A_u [I_total; -I_total]b_u [repmat(Umax, Nc, 1); repmat(-Umin, Nc, 1)]。2. 控制增量约束DeltaUmin u(ki) - u(ki-1) DeltaUmax。 定义差分矩阵D使得DU [u(k)-u(k-1); u(k1)-u(k); ...]。D是一个带负号的下对角矩阵。假设u(k-1)是上一时刻实施的控制量为已知量u_prev。 那么约束可以写为D * U repmat(DeltaUmax, Nc, 1)-D * U repmat(-DeltaUmin, Nc, 1)同时需要将u_prev的影响移到不等式右边b_delta [repmat(DeltaUmax, Nc, 1) d; repmat(-DeltaUmin, Nc, 1) - d]其中d是一个向量其第一个元素为u_prev其余为0。3. 输出约束Ymin y(ki) Ymax,i 1, ..., Np。 利用预测方程Y Psi * x(k) Theta * U输出约束可以转化为Theta * U Ymax - Psi * x(k)-Theta * U -Ymin Psi * x(k)最终将所有不等式约束垂直拼接起来得到总的A_ineq和b_ineqA_ineq [A_u; A_delta; A_y]; b_ineq [b_u; b_delta; b_y];注意事项输出约束特别是硬约束可能导致QP问题不可行即找不到满足所有约束的解。在实际应用中通常采用“软约束”处理即为输出约束引入松弛变量并在目标函数中对其施加很大的惩罚权重这样既能在大多数时候满足约束又能在极端情况下保证问题有解。3.4 使用quadprog求解与热启动构建好H, f, A_ineq, b_ineq后就可以调用quadprog了。基本调用格式如下options optimoptions(‘quadprog’, ‘Display’, ‘off’, ‘Algorithm’, ‘interior-point-convex’); [U_opt, fval, exitflag] quadprog(H, f’, A_ineq, b_ineq, [], [], [], [], U0, options);H, fQP问题的二次项和一次项矩阵。A_ineq, b_ineq线性不等式约束。第5、6个参数Aeq, beq是线性等式约束如果没有就填[]。第7、8个参数lb, ub是变量的上下界约束。注意如果我们已经在A_ineq, b_ineq中包含了所有约束这里就可以填[]。但有时单独指定lb, ub对求解器更友好。需要避免重复指定约束。U0初始猜测点。这就是实现“热启动”的地方将上一个时刻求解得到的最优序列U_opt_prev稍作平移去掉已实施的第一项在末尾补上一个合理的值如最后一项或零作为本次的U0可以大幅减少迭代次数。options优化选项。将Display设为‘off’可以避免命令行输出刷屏。Algorithm可以选择‘interior-point-convex’内点法适用于中小规模问题或‘active-set’有效集法。必须检查exitflagexitflag大于0表示求解成功等于0表示达到最大迭代次数小于0表示求解失败。在仿真中如果出现exitflag 0应该给出警告并采取备用策略例如使用上一时刻的控制量或者使用无约束的最小二乘解。4. 仿真闭环构建与结果分析实战有了所有模块我们现在将它们组装起来进行一个完整的闭环仿真。我们以一个经典的双积分器系统例如一个在平面上无摩擦的小车的位置控制为例。4.1 被控对象与控制器参数设定首先定义连续时间双积分器系统ddx u状态选为位置和速度x [p; v]则状态空间方程为Ac [0 1; 0 0],Bc [0; 1],Cc [1 0](我们控制位置)Dc 0。% 1. 系统定义与离散化 Ac [0 1; 0 0]; Bc [0; 1]; Cc [1 0]; Dc 0; Ts 0.05; % 50ms采样周期 sys_c ss(Ac, Bc, Cc, Dc); sys_d c2d(sys_c, Ts, ‘zoh’); [A, B, C, D] ssdata(sys_d); nx size(A,1); nu size(B,2); ny size(C,1); % 2. MPC控制器参数 Np 20; % 预测时域 Nc 5; % 控制时域 Q 10; % 输出误差权重 (标量因为只有一个输出) R 0.1; % 控制输入权重 % 3. 约束 Umin -2; Umax 2; % 控制量幅值约束 DeltaUmin -1; DeltaUmax 1; % 控制增量约束 % 输出约束这里暂时不设硬约束或用软约束 % 4. 仿真参数 Tsim 5; % 总仿真时间5秒 Nsim ceil(Tsim / Ts); % 仿真步数 x0 [0; 0]; % 初始状态 [位置; 速度] u_prev 0; % 上一时刻控制量初始为04.2 离线计算构建预测矩阵与QP常量部分为了提高在线计算效率所有不依赖于当前状态x(k)的矩阵都应该在仿真循环开始前预先计算好。% 构建 Psi 和 Theta 矩阵 (代码参考3.2节此处略) % 构建 Q_bar, R_bar Q_bar kron(eye(Np), Q); R_bar kron(eye(Nc), R); % 构建H矩阵常量部分 (不包含可能随时间变化的部分但这里H是常数) H Theta’ * Q_bar * Theta R_bar; % 构建控制量幅值约束矩阵 A_u, b_u (不依赖于状态) I_Nc eye(Nc); A_u [kron(I_Nc, eye(nu)); kron(I_Nc, -eye(nu))]; b_u [repmat(Umax, Nc, 1); repmat(-Umin, Nc, 1)]; % 构建控制增量约束矩阵 A_delta (常数部分) % ... (具体构建略参考3.3节) % 注意b_delta 的一部分依赖于 u_prev需要在每个循环里更新4.3 在线循环滚动优化与反馈这是仿真的核心循环。我们设计一个参考轨迹比如一个从0到1的阶跃信号。% 初始化存储数组 X_history zeros(nx, Nsim1); X_history(:,1) x0; U_history zeros(nu, Nsim); Y_history zeros(ny, Nsim1); Y_history(:,1) C * x0; J_history zeros(1, Nsim); % 参考轨迹 (阶跃信号) ref 1; R_ref ref * ones(Np*ny, 1); % 未来Np步的参考都是1 % 初始化优化变量猜测值 U0 zeros(Nc*nu, 1); for k 1:Nsim % 1. 获取当前状态 (在完美测量仿真中就是真实状态) x_current X_history(:, k); % 2. 更新依赖于当前状态和u_prev的约束向量 % 2.1 输出约束的b_y (如果启用软约束这部分逻辑不同) % b_y [Ymax_vec - Psi*x_current; -Ymin_vec Psi*x_current]; % 2.2 控制增量约束的b_delta d zeros(Nc*nu, 1); d(1:nu) u_prev; % 只有第一个增量受上一时刻影响 b_delta [repmat(DeltaUmax, Nc, 1) d; repmat(-DeltaUmin, Nc, 1) - d]; % 2.3 合并所有约束的b_ineq b_ineq [b_u; b_delta]; % 这里假设没有输出硬约束 % 3. 更新QP目标函数的一次项f f (Psi * x_current - R_ref)’ * Q_bar * Theta; % 4. 求解QP options optimoptions(‘quadprog’, ‘Display’, ‘off’, ‘Algorithm’, ‘interior-point-convex’); [U_opt, fval, exitflag] quadprog(H, f’, A_ineq, b_ineq, [], [], [], [], U0, options); if exitflag 0 warning(‘QP求解失败在时刻 %d, exitflag%d’, k, exitflag); % 应急策略使用上一时刻控制序列的平移或置零 U_opt U0; end % 5. 提取当前控制量 u_current U_opt(1:nu); % 6. 施加控制量更新系统状态 (加入轻微过程噪声模拟不确定性) process_noise 0.00 * randn(nx,1); % 小噪声 x_next A * x_current B * u_current process_noise; y_next C * x_next; % 7. 记录数据 U_history(:, k) u_current; X_history(:, k1) x_next; Y_history(:, k1) y_next; J_history(k) fval; % 8. 为下一次循环做准备热启动 U0 [U_opt(nu1:end); U_opt(end-nu1:end)]; % 平移去掉第一个复制最后一个 u_prev u_current; % 更新上一时刻控制量 end4.4 结果可视化与性能分析仿真结束后绘制图形分析控制器性能。figure(‘Position’, [100 100 1200 800]) t (0:Nsim)*Ts; subplot(3,1,1) plot(t, Y_history, ‘b-‘, ‘LineWidth’, 1.5); hold on; plot(t, ref*ones(size(t)), ‘r—‘, ‘LineWidth’, 1.2); xlabel(‘时间 (s)’); ylabel(‘输出 y (位置)’); title(‘MPC控制输出跟踪效果’); legend(‘系统输出’, ‘参考轨迹’, ‘Location’, ‘best’); grid on; subplot(3,1,2) stairs(t(1:end-1), U_history, ‘m-‘, ‘LineWidth’, 1.5); xlabel(‘时间 (s)’); ylabel(‘控制输入 u’); title(‘控制输入序列’); hold on; plot([t(1), t(end)], [Umax, Umax], ‘r—‘); plot([t(1), t(end)], [Umin, Umin], ‘r—‘); legend(‘控制量’, ‘约束边界’, ‘Location’, ‘best’); grid on; subplot(3,1,3) plot(t(1:end-1), J_history, ‘g-‘, ‘LineWidth’, 1.5); xlabel(‘时间 (s)’); ylabel(‘目标函数值 J’); title(‘优化目标函数值变化’); grid on;通过分析这些图我们可以评估跟踪性能输出是否能快速、平稳、无静差地跟踪参考信号超调量、调节时间是多少控制量行为控制输入是否平滑是否始终满足幅值和增量约束在约束边界上的行为如何优化过程目标函数值是否随着时间收敛求解器是否在每个时刻都成功求解5. 调试技巧、常见问题与性能优化即使按照上述步骤搭建了仿真你也可能会遇到各种问题。下面是一些实战中积累的排查经验和优化技巧。5.1 调试与问题排查清单QP问题不可行exitflag -2原因约束条件相互冲突过于严格导致没有解。例如输出约束Ymin/Ymax设置得太紧而控制量约束Umin/Umax又太小系统物理上无法在指定时间内达到要求。排查首先检查所有约束数值是否合理。尝试暂时移除部分约束如输出约束看问题是否消失。使用软约束代替硬约束。MATLAB调试在quadprog调用前打印A_ineq和b_ineq的维度确保它们正确。检查H矩阵的条件数cond(H)如果条件数过大如 1e10可能导致数值问题可以尝试给R矩阵加一个很小的正则化项如R R 1e-6*eye(nu)。H矩阵非正定exitflag -6或警告原因H Theta^T Q_bar Theta R_bar理论上应为正定但如果R权重太小或为零且系统存在不稳定零点或Theta不满秩H可能半正定甚至奇异。解决确保R矩阵是正定的即使是很小的正数对角阵。这是保证问题凸性的最直接方法。控制效果震荡或不稳定原因1预测时域Np太短。控制器“目光短浅”无法预见未来的动态导致短视行为。解决增大Np通常至少应覆盖系统的主要动态响应时间。原因2权重Q和R设置不合理。R相对于Q太大控制器过于“吝啬”控制能量响应迟钝R太小则控制量可能剧烈变化。解决系统性地调节权重。可以先从R开始设一个较小的值观察响应然后调整Q的不同分量如果是多输出以平衡不同输出的跟踪速度。原因3采样时间Ts不合适。Ts太大导致离散化误差大控制律粗糙Ts太小则可能放大数值误差和高频噪声。解决根据系统带宽重新选择Ts。仿真速度慢瓶颈99%的情况在于quadprog的在线求解。优化1热启动如前所述务必使用热启动。优化2减少优化变量在满足性能要求的前提下尽量减小控制时域Nc。Nc决定了优化变量U的维度对计算复杂度影响巨大QP复杂度通常与变量维度的立方相关。优化3使用更高效的QP求解器对于线性MPC其QP问题具有特殊的结构Hessian矩阵恒定约束矩阵是带状稀疏的。可以寻找利用这种结构的专用QP求解器如qpOASES、OSQP的MATLAB接口它们比通用的quadprog快得多。优化4显式MPC如果系统是线性的且约束是多面体并且状态和参数的组合空间不大可以考虑离线计算最优控制律的分段仿射函数在线时只需查表和简单计算速度极快。MATLAB的MPC工具箱可以生成显式MPC控制器。5.2 高级功能扩展思路当基础仿真跑通后你可以尝试以下扩展让程序更贴近实际应用状态估计器观测器在实际系统中我们往往不能直接测量所有状态x。这时需要设计一个状态观测器如龙伯格观测器、卡尔曼滤波器根据可测量的输出y和控制输入u来估计状态x_hat。在仿真中你可以模拟带有测量噪声的输出然后让MPC控制器基于x_hat进行计算。参考轨迹生成与预览不是所有参考信号都是阶跃。对于路径跟踪如自动驾驶参考轨迹是未来一系列时变的设定点。你的程序需要能够接收或生成这样的轨迹r(k1), r(k2), ..., r(kNp)。软约束与约束优先级如前所述对输出约束使用软约束在目标函数中加入松弛变量的惩罚项rho * epsilon^2并约束Y - epsilon Ymax和Y epsilon Ymin其中epsilon 0。rho需要取一个非常大的数以保证只有在必要时才违反约束。积分抗扰在目标函数中加入输出误差的积分项惩罚或者像传统PID那样在MPC的预测模型中加入一个积分状态可以有效消除由于常值干扰引起的稳态误差。代码生成与部署MATLAB Coder 可以将你的MPC算法代码需要满足一定规范自动转换为C代码从而部署到嵌入式处理器或工业PLC中。这是将仿真研究转化为实际产品的关键一步。这个MPC仿真程序就像一辆等待你驾驶和改装的车。从成功运行第一个闭环仿真开始到逐步引入噪声、约束、状态估计再到尝试不同的优化求解器和代码生成每一步的探索都会让你对模型预测控制这门强大而优美的技术有更深的理解。最重要的是亲手调试和修改代码过程中遇到的每一个错误和解决的每一个问题都是书本上无法给予的宝贵经验。本文还有配套的精品资源点击获取