與調(diào)試實戰(zhàn)指南)
簡介本資源面向車輛控制算法工程師、智能駕駛方向研究生及MATLAB/Simulink仿真開發(fā)者聚焦MPC在整車動力學(xué)控制中的工程落地問題涵蓋模型預(yù)測控制原理、多子系統(tǒng)協(xié)同優(yōu)化設(shè)計及CarSim-MATLAB聯(lián)合仿真驗證全流程。壓縮包共4個文件2個MATLAB腳本、1個Simulink模型、1個說明文檔總大小僅17KB輕量但結(jié)構(gòu)完整.m文件實現(xiàn)MPC控制器核心邏輯與參數(shù)配置.mdl模型封裝車輛動力學(xué)與控制器閉環(huán)結(jié)構(gòu).txt提供關(guān)鍵變量定義、運行步驟與約束條件說明便于快速復(fù)現(xiàn)與二次開發(fā)。已有2662人學(xué)習(xí)下載資源內(nèi)容緊扣第六章典型教學(xué)案例覆蓋車輛縱向/橫向耦合控制建模、預(yù)測時域設(shè)定、硬約束如輪胎側(cè)偏角、執(zhí)行器飽和處理及性能指標(biāo)權(quán)衡等實戰(zhàn)要點可直接用于課程設(shè)計、畢業(yè)課題或自動駕駛控制算法原型驗證。 做整車控制這些年我最常被問到的一個問題是PID明明已經(jīng)夠用了為什么還要折騰MPC每次遇到這種問題我都會反問一句如果你的目標(biāo)是讓車速在約束范圍內(nèi)快速響應(yīng)、同時把能耗壓到最低還得應(yīng)付前車突然減速這類突發(fā)工況PID還能輕松搞定嗎大概率不能。MPC模型預(yù)測控制Model Predictive Control在整車控制里的價值恰恰就體現(xiàn)在這種“多目標(biāo)、帶約束、能預(yù)判未來”的場景中。這篇博文就圍繞整車控制中的MPC算法從原理講到MATLAB實現(xiàn)再聊一聊我實際調(diào)試時踩過的坑和一些排查方法希望能給正在入門或者已經(jīng)在項目中用MPC的朋友一些參考。先說說適合誰來讀。如果你剛接觸MPC想搞明白它到底是怎么工作的這篇能幫你把原理部分啃下來如果你已經(jīng)在整車縱向控制、能量管理或者路徑跟蹤這類方向干活這篇里的MATLAB實現(xiàn)細(xì)節(jié)和參數(shù)整定經(jīng)驗可以讓你少走不少彎路。我默認(rèn)你對車輛動力學(xué)有一點基礎(chǔ)也用過MATLAB/Simulink但不要求你有多深的控制理論功底只要會基本的矩陣運算MPC的推導(dǎo)和代碼都能跟得上。1. 整車控制里的MPC到底解決什么問題1.1 為什么整車控制場景天然適合MPC先不聊公式咱們從需求倒推。整車控制范疇很廣縱向車速控制、ACC自適應(yīng)巡航、能量管理策略、底盤集成控制、路徑跟蹤這些場景有一個共同特點它們都帶有約束而且是硬約束。車速不能超過物理極限電機輸出扭矩有上下限電池SOC不能過充過放制動力不能超過路面附著系數(shù)如果你用傳統(tǒng)PID這些約束基本靠“限幅”處理也就是先算出一個控制量再把它硬截斷在約束范圍內(nèi)。這種粗暴的截斷方式帶來的問題是你可能在最需要加速的時候恰恰踩了剎車或者為了滿足約束而犧牲了本來可以更好的舒適性和經(jīng)濟性。MPC的處理方式不一樣。它在每一步優(yōu)化時就把約束寫進(jìn)優(yōu)化問題里算出來的控制量天然滿足約束而不是算完再截斷。而且MPC有一個“預(yù)測”能力它可以根據(jù)當(dāng)前狀態(tài)和模型往前看未來一段時間預(yù)測時域的系統(tǒng)行為然后在這段時間內(nèi)做整體優(yōu)化。這就好比開車時你不僅看眼前這一點而是看到前方三百米的路況再決定怎么踩油門剎車效果自然比“眼前有什么反應(yīng)什么”要好。拿ACC自適應(yīng)巡航舉例。前車突然減速傳統(tǒng)PID只能檢測到距離誤差變大了才做出反應(yīng)多少有點滯后MPC因為在前一步優(yōu)化時已經(jīng)把“預(yù)測到的前車軌跡”代入模型可以在前車真正減速之前就開始協(xié)調(diào)發(fā)動機和制動系統(tǒng)整個過程更平滑、更接近人類駕駛員的預(yù)判行為。這就是整車控制選MPC的核心原因多目標(biāo)、多約束、可預(yù)測三個需求正好是MPC的主場。1.2 MPC和PID、LQR的差異在哪很多人會有疑惑既然LQR也是最優(yōu)控制為什么不用LQRLQR確實能處理多目標(biāo)優(yōu)化而且求解快但它的約束處理能力比較弱需要在設(shè)計時把約束“軟化”成懲罰項這在實際工程里很難做到精確。PID就更不用說它本質(zhì)上是偏差驅(qū)動的沒有預(yù)測能力也沒有約束概念。我做一個直觀的對比。控制方法約束處理預(yù)測能力多目標(biāo)優(yōu)化計算量工程落地難度PID靠限幅嚴(yán)格說不算約束無弱需要加權(quán)合并極低低LQR弱需軟約束化無強但難處理硬約束低中MPC強直接寫進(jìn)優(yōu)化問題有強可靈活調(diào)節(jié)權(quán)重高中高從表里能看出來MPC的強項正是整車控制最看重的點。但它的代價也很明顯計算量大需要在線求解一個帶約束的優(yōu)化問題。所以在早期MPC主要用在對算力要求不苛刻的慢過程上比如化工過程控制。近些年隨著車載控制器算力提升以及一些高效QP求解器的出現(xiàn)MPC在整車上的實時應(yīng)用才真正變得可行。這也是為什么現(xiàn)在很多OEM和Tier1都在往MPC方向轉(zhuǎn)型。2. MPC算法原理從預(yù)測模型到滾動優(yōu)化2.1 預(yù)測模型先把車輛行為寫成狀態(tài)空間方程MPC一切的地基是預(yù)測模型。你不把被控對象的行為描述出來后面的“預(yù)測”就是空中樓閣。對整車縱向控制來說最常用的是簡化縱向動力學(xué)模型我直接給一個經(jīng)典形式x(k1) A x(k) B u(k)這里的x是狀態(tài)量通常包含車速v和加速度au是控制輸入一般是期望加速度或者電機扭矩請求。如果你只做單純的縱向速度控制一階慣性模型也能用如果做ACC狀態(tài)量里再加上相對距離Δd和相對速度Δv模型維度會高一些。我給你一個我在MATLAB里用得比較順手的縱向控制狀態(tài)空間模型例子% 車輛縱向動力學(xué)簡化模型 % 狀態(tài): x [v; a] 車速(m/s), 加速度(m/s^2) % 輸入: u acc_des 期望加速度(m/s^2) % 假設(shè): 一階慣性環(huán)節(jié)近似動力總成響應(yīng), 時間常數(shù)為 tao tao 0.5; % 動力總成響應(yīng)時間常數(shù)根據(jù)實際整車標(biāo)定 Ts 0.05; % 控制周期50ms A_cont [0 1; 0 -1/tao]; B_cont [0; 1/tao]; C_cont [1 0]; % 離散化 sys_cont ss(A_cont, B_cont, C_cont, 0); sys_disc c2d(sys_cont, Ts, zoh); A sys_disc.A; B sys_disc.B; C sys_disc.C;這個模型里有個關(guān)鍵參數(shù)tao時間常數(shù)它代表了從你發(fā)出期望加速度指令到車輛實際加速度變化之間的延遲和慣性。這個數(shù)值不是拍腦袋定的而是通過實車標(biāo)定的比如你做階躍響應(yīng)測試記錄期望加速度和實際加速度擬合出一階慣性模型的tao。不同車型、不同動力總成形式純電、混動、燃油差異很大純電車響應(yīng)快tao可能在0.2到0.3左右燃油車帶渦輪增壓的可能到0.8以上。2.2 滾動優(yōu)化核心思想就一句話反復(fù)做MPC區(qū)別于“一次性算完就不管”的控制方法在于它每步都在做優(yōu)化而且只執(zhí)行第一步的結(jié)果。我把它拆成三步在當(dāng)前時刻k讀取系統(tǒng)當(dāng)前狀態(tài)x(k)。基于預(yù)測模型向前滾動預(yù)測未來Np步的狀態(tài)然后求解一個優(yōu)化問題得到未來Nc步最優(yōu)控制序列。只把控制序列的第一步u(k)作用到系統(tǒng)上。到k1時刻重新采樣狀態(tài)重復(fù)以上過程。這就是“滾動優(yōu)化”或“滾動時域控制”的本質(zhì)。為什么要這么麻煩因為模型有誤差、外部有擾動你一次性算出來的未來控制序列在實際情況中根本不準(zhǔn)確。每步重新優(yōu)化相當(dāng)于用最新的反饋信息去修正預(yù)測誤差這也是MPC魯棒性的來源之一。我舉個例子。假設(shè)你在高速上跑ACC預(yù)測模型認(rèn)為前方車輛會勻速行駛所以MPC算出未來十步的控制序列但你只執(zhí)行當(dāng)前這一步的加速度。過了50毫秒你發(fā)現(xiàn)前車踩剎車了此時MPC重新采樣到新的相對距離和相對速度再重新優(yōu)化輸出新的控制量。這種“走一步看一步、看一步算一步”的策略保證控制始終基于最新信息。2.3 代價函數(shù)MPC怎么表達(dá)“我想要什么”MPC優(yōu)化問題里核心是代價函數(shù)。整車控制里最常用的代價函數(shù)可以寫成J Σ(i1..Np) ||y(ki) - y_ref(ki)||2_Q Σ(i0..Nc-1) ||u(ki)||2_R看著有點嚇人說白了就是“跟蹤誤差越小越好控制量越平穩(wěn)越好”。第一項是預(yù)測輸出和目標(biāo)參考軌跡的誤差平方和相當(dāng)于司機眼里“車速和設(shè)定值的偏差”第二項是控制量大小的懲罰相當(dāng)于司機踩油門的平順性考量。Q和R就是這兩者之間的權(quán)重平衡。Q大代表你更在意跟蹤精度系統(tǒng)響應(yīng)偏激進(jìn)R大代表你更在意控制動作平緩系統(tǒng)響應(yīng)偏保守。除了代價函數(shù)約束條件也是MPC的精髓。整車控制里最常見的約束有控制量約束u_min ≤ u(ki) ≤ u_max對應(yīng)電機/發(fā)動機最大和最小輸出能力。控制增量約束Δu_min ≤ Δu(ki) ≤ Δu_max對應(yīng)加速度變化率限制直接關(guān)系到平順性。狀態(tài)約束a_min ≤ a(ki) ≤ a_max保證乘客舒適性和車輛穩(wěn)定性。最終MPC每一步要解的是一個帶約束的二次規(guī)劃QP問題。它的標(biāo)準(zhǔn)形式是min 1/2 x H x f x s.t. Ax ≤ bMATLAB里只要把模型和代價函數(shù)寫出來工具箱會自動幫你拼裝這個QP然后調(diào)用求解器解出來。但如果你想真正理解MPC最好自己手推一遍QP的構(gòu)造過程后面講MATLAB實現(xiàn)的時候我會展示怎么一步步拼裝。3. MATLAB/Simulink實現(xiàn)MPC的完整流程3.1 搭模型用Simulink搭一個被控車輛MATLAB/Simulink是整車控制開發(fā)最常用的平臺沒有之一。我一般把MPC實現(xiàn)分成三個模塊被控對象模型、控制器、以及可視化分析模塊。被控對象模型有兩種選擇一是用Simscape搭物理模型二是用數(shù)學(xué)方程搭簡化模型。對于MPC算法的驗證階段我建議先用簡化模型因為調(diào)試方便、算得快邏輯和結(jié)果對上了再往Simscape或者Simulink自帶的車輛動力學(xué)庫里換。我分享一個最簡單的縱向車速控制Simulink搭建思路被控對象第二章里的離散狀態(tài)空間模型用State-Space模塊封裝。MPC控制器可以用MPC Toolbox的MPC Controller模塊也可以后面我講的手寫代碼方式。輸出顯示用Scope查看車速跟蹤曲線、控制量曲線用Display實時看數(shù)值。這里有個容易踩的坑MPC Controller模塊默認(rèn)輸入是“被控對象輸出y”和“參考輸入ref”很多新手會把狀態(tài)x直接接進(jìn)去結(jié)果老是報維度不匹配。你需要先用Measurements端口給控制器反饋可測量的輸出一般是車速v然后MPC內(nèi)部會通過狀態(tài)觀測器Kalman濾波估計完整狀態(tài)。如果你直接把狀態(tài)都測到了比如Simulink模型里狀態(tài)很容易拿到可以在MPC Controller模塊里配置“所有狀態(tài)可測”這樣反而更穩(wěn)定。3.2 用MPC Toolbox快速實現(xiàn)MPC Toolbox是最省事的方式適合走整體流程驗證。它的使用路徑很清晰先在MATLAB工作區(qū)創(chuàng)建MPC對象然后配置預(yù)測模型、采樣時間、預(yù)測時域、控制時域、權(quán)重和約束最后丟到Simulink里仿真。我寫一段典型的MPC對象創(chuàng)建代碼% 假設(shè)已經(jīng)有離散模型 sys_disc % 創(chuàng)建MPC控制器 mpc_obj mpc(sys_disc, Ts); % 設(shè)置預(yù)測時域和控制時域 mpc_obj.PredictionHorizon 20; mpc_obj.ControlHorizon 3; % 權(quán)重設(shè)置: 輸出(車速)權(quán)重高, 控制量權(quán)重適中 mpc_obj.Weights.OutputVariables 1; mpc_obj.Weights.ManipulatedVariables 0.1; mpc_obj.Weights.ManipulatedVariablesRate 0.5; % 約束設(shè)置: 期望加速度范圍 mpc_obj.ManipulatedVariables.Min -3; % m/s^2 最大制動減速度 mpc_obj.ManipulatedVariables.Max 2; % m/s^2 最大加速度 mpc_obj.ManipulatedVariables.RateMin -1; % 加速度變化率 mpc_obj.ManipulatedVariables.RateMax 1;這里的關(guān)鍵參數(shù)含義我先點一下PredictionHorizon預(yù)測時域Np是20代表預(yù)測未來20步也就是1秒20 × 50ms。這個長度要覆蓋系統(tǒng)主要動態(tài)過程。如果太短MPC“看不到”更遠(yuǎn)的影響約束可能壓不住如果太長計算量增大而且遠(yuǎn)處的預(yù)測權(quán)重小實際意義不大。ControlHorizon控制時域Nc是3代表未來只允許3步控制量自由變化后面的控制量保持不變。Nc小可以減少優(yōu)化變量數(shù)量顯著降低計算量是實車部署時常用的壓縮手段。Weights里三個權(quán)重分別對應(yīng)輸出跟蹤、控制量大小和控制量變化率。我把控制量變化率權(quán)重設(shè)成0.5是為了讓加速度請求變化平緩避免頓挫感。設(shè)置完對象后你可以在MATLAB里用sim函數(shù)離線仿真也可以在Simulink里拖MPC Controller模塊。我建議先跑離線仿真打開mpcobj的仿真結(jié)果圖看看跟蹤效果和約束滿足情況再進(jìn)Simulink閉環(huán)驗證。3.3 手寫MPC代碼繞過工具箱真正吃透原理工具箱雖好但有一個問題你很難真正理解內(nèi)部發(fā)生了什么。我強烈建議每個想深入MPC的人至少手寫一遍無約束或簡單約束的MPC這樣才能在遇到問題時不至于整個就是黑盒。這里我給一個基于Yalmip封裝的MPC求解代碼框架方便理解問題定義和求解過程% 手寫MPC: 基于Yalmip求解QP % 狀態(tài)方程: x(k1) A*x(k) B*u(k) % 代價: 跟蹤車速v_ref, 懲罰控制量變化 Np 20; Nc 3; % 定義優(yōu)化變量 u sdpvar(1, Nc); % 控制序列 x sdpvar(2, Np1); % 狀態(tài)序列 % 約束和代價初始化 constraints []; cost 0; % 初始狀態(tài)約束 constraints [constraints, x(:,1) x0]; % 預(yù)測循環(huán) for i 1:Np if i Nc u_i u(i); else u_i u(Nc); % 控制時域之后保持不變 end % 狀態(tài)更新方程 constraints [constraints, x(:,i1) A*x(:,i) B*u_i]; % 約束: 控制量限幅 constraints [constraints, -3 u_i 2]; % 代價: 輸出跟蹤誤差 控制量懲罰 cost cost (x(1,i) - v_ref(i)) * Q_out * (x(1,i) - v_ref(i)); cost cost u_i * R_in * u_i; end % 配置求解器 options sdpsettings(solver, quadprog, verbose, 0); % 求解 optimize(constraints, cost, options); % 取第一個控制量 u_first value(u(1));這段代碼的風(fēng)格是把MPC問題“直接寫出來”讓求解器去解。Yalmip的優(yōu)點是代碼接近數(shù)學(xué)描述適合學(xué)習(xí)和驗證。實際工程部署時一般不會用Yalmip而是用QP求解器比如OSQP、qpOASES、MATLAB自帶的quadprog配合C代碼生成但理解思路是完全一致的。我自己帶團隊時要求每個工程師先用這段代碼跑通一個簡單縱向控制再允許用工具箱就是怕大家只會填參數(shù)、不會看本質(zhì)。實際過程中一旦你手寫一遍后面的參數(shù)整定、問題分析效率會明顯高一個臺階。3.4 完整閉環(huán)驗證從仿真代碼到Simulink光有控制器代碼還不夠你得把它放進(jìn)閉環(huán)里驗證。我一般是這樣操作的第一步先用純MATLAB腳本做閉環(huán)仿真不拖Simulink。這一步能快速驗證算法邏輯排除模型問題。我把被控對象也寫進(jìn)去用for循環(huán)模擬每個采樣周期的控制過程% 閉環(huán)仿真 simTime 10; % 秒 steps simTime / Ts; x [0; 0]; % 初始車速為0 logV zeros(steps, 1); logU zeros(steps, 1); time 0:Ts:simTime-Ts; % 參考車速: 從0加速到20m/s v_ref_profile min(20, time * 2); for k 1:steps x0 x; v_ref v_ref_profile(min(k, length(v_ref_profile))); % 調(diào)用MPC求解得到控制量 % (這里以手寫MPC函數(shù)為例) u_k run_mpc_controller(A, B, x0, v_ref, Np, Nc); % 施加到被控對象 x A * x B * u_k; % 記錄數(shù)據(jù) logV(k) x(1); logU(k) u_k; end第二步驗證通過之后再進(jìn)Simulink把MPC Controller替換成手寫MPC模塊用MATLAB Function 或者 S-Function 封裝接上更精細(xì)的車輛模型看看在模型復(fù)雜度升高后MPC還能不能保持性能。這一步能暴露很多純腳本階段發(fā)現(xiàn)不了的問題比如模型失配、數(shù)值穩(wěn)定性、求解器收斂等。我踩過的一個很典型的坑是純腳本仿真里被控對象也是簡單的線性模型MPC控制效果完美但一進(jìn)Simulink換成Simscape高保真模型參數(shù)完全沒調(diào)結(jié)果車速震蕩甚至發(fā)散。原因就是MPC內(nèi)部的預(yù)測模型和實際被控對象失配太嚴(yán)重。后面我會專門講這個問題怎么處理。4. 參數(shù)整定與實操經(jīng)驗4.1 預(yù)測時域和控制時域的選擇邏輯參數(shù)整定是MPC落地的關(guān)鍵一環(huán)。很多新手一上來就問Np取多少合適Nc取多少合適我沒法給一個放之四海而皆準(zhǔn)的數(shù)值但可以給一套判斷邏輯。預(yù)測時域Np的選擇要覆蓋系統(tǒng)的主要瞬態(tài)過程。你可以先對被控對象做一個開環(huán)階躍響應(yīng)觀察它從初始狀態(tài)到穩(wěn)定大約需要多長時間然后把這段時間除以采樣周期Ts就得到一個粗略的Np基準(zhǔn)值。比如車輛從0加速到20m/s可能需要2到3秒采樣周期50ms那Np至少應(yīng)該做到40到60步。但Np也不是越大越好Np過大時遠(yuǎn)處的預(yù)測誤差累積QP規(guī)模變大而且遠(yuǎn)期目標(biāo)對當(dāng)前決策的貢獻(xiàn)逐漸變小容易造成數(shù)值病態(tài)。我的經(jīng)驗是Np覆蓋主要動態(tài)過程的1到1.5倍就夠了。控制時域Nc的選擇邏輯不同。Nc本質(zhì)上決定了優(yōu)化問題的自由度Nc越大控制序列的可變性越強性能理論上越好但計算量成比例增加。整車控制實時性要求高我通常把Nc控制在3到5之間。如果你用Np20、Nc3優(yōu)化變量就是3個求解速度非常快如果你把Nc提到20優(yōu)化變量就變成20個實時性可能就頂不住了。這里有個工程技巧Nc不需要等于Np因為MPC的控制特點是“未來的控制動作會逐步修正”你只需要給近期足夠的自由度遠(yuǎn)期由約束保持穩(wěn)定即可。4.2 權(quán)重Q和R怎么調(diào)才不會“翻車”權(quán)重整定是MPC最玄學(xué)也最有規(guī)律的部分。我的方法分三步走。第一步先把權(quán)重拉到“只關(guān)注跟蹤”的狀態(tài)也就是Q取較大值、R取較小值看系統(tǒng)在滿足約束的前提下能跑到多快。這個過程通常會看到控制量快速抖動、接近約束邊界甚至出現(xiàn)小幅超調(diào)。這不要緊目的是找到系統(tǒng)的性能上限。第二步逐步增大R和控制量變化率權(quán)重看跟蹤性能下降的趨勢找到“性能和平順性”的折中點。我一般會觀察兩個指標(biāo)一個是車速跟蹤的上升時間和穩(wěn)態(tài)誤差另一個是控制量變化的最大速率。如果控制量變化太激進(jìn)乘客會感覺到頓挫即使在仿真里不體現(xiàn)實車也會被標(biāo)定工程師斃掉。第三步把權(quán)重固定下來后做一次極端工況掃描比如急加速到目標(biāo)車速、高速情況下制動減速、連續(xù)坡道巡航看權(quán)重參數(shù)在所有工況下是否都能保持合理。如果某個工況下出現(xiàn)較大振蕩優(yōu)先增大控制量變化率權(quán)重而不是增大Q。因為振蕩的根源是控制動作太激進(jìn)通過R來抑制往往比通過Q來強壓更有效。這里有一組我常用的初始參考值你可以作為起點輸出權(quán)重Q車速誤差權(quán)重取1左右。控制量權(quán)重R取0.1到0.5之間具體看平順性需求。控制量變化率權(quán)重取0.2到0.8之間這是平順性的主力調(diào)節(jié)旋鈕。這組初始值大概率不會讓你一上來就失控但最終還是要根據(jù)實際工況微調(diào)沒有捷徑。4.3 約束設(shè)置的一些經(jīng)驗教訓(xùn)約束是MPC的核心優(yōu)勢也是最容易出問題的地方。我總結(jié)三個常見教訓(xùn)。第一約束上下限不要貼死物理極限。比如電機的最大加速度是3m/s2你如果真把約束設(shè)成3MPC在優(yōu)化時會頻繁碰到邊界一旦模型誤差或者噪聲讓實際車輛越過約束你根本沒留緩沖空間。我習(xí)慣留5%到10%的裕量比如設(shè)成2.7到2.8。第二約束之間要協(xié)調(diào)。比如你對控制量限幅的同時又對控制量變化率限幅這兩個約束可能互相沖突導(dǎo)致QP無解。遇到這種情況MPC會報infeasible problem仿真直接中斷。解決方法是給約束加“軟約束”的松弛變量slack variable允許約束在極端情況下被輕微違反同時在代價函數(shù)里加上對松弛量的懲罰。用工具箱時可以通過設(shè)置OutputVariables的Soft Constraint來實現(xiàn)手寫代碼時則需要在QP里顯式加入松弛變量。第三不要忽視狀態(tài)約束對可解性的影響。例如你加入加速度上限約束但參考車速本身變化太快導(dǎo)致系統(tǒng)為了跟蹤參考而必須請求超出約束的加速度此時QP也會無解。你需要檢查參考軌跡的物理可實現(xiàn)性或者把參考軌跡生成模塊也納入MPC的預(yù)測框架里讓MPC知道未來參考的變化趨勢提前調(diào)整輸出。5. 常見問題與排查技巧實錄5.1 QP求解失敗、系統(tǒng)發(fā)散怎么查在實際仿真和實車調(diào)試中最讓人頭疼的就是“上一秒還好好的下一秒控制器突然罷工”。我按經(jīng)驗列一個排查順序按這個順序查能省不少時間。第一確認(rèn)模型離散化是否正確。很多新手用c2d離散化之后直接把連續(xù)模型的A、B矩陣拿來當(dāng)離散模型用這會導(dǎo)致預(yù)測完全錯誤。務(wù)必檢查sys_disc的極點是否在單位圓內(nèi)A矩陣是否符合離散模型的特征。第二確認(rèn)QP求解器是否收斂。用工具箱時打開仿真診斷觀察是否有“The QP solver failed to find a solution”之類的提示。如果頻繁出現(xiàn)多半是約束太緊或者權(quán)重病態(tài)。可以先放松約束或者改求解器比如從默認(rèn)的KWIK算法換成QP算法。第三確認(rèn)采樣時間是否與實際控制器周期一致。MPC內(nèi)部的模型離散化基于Ts如果你的Simulink仿真步長和MPC的Ts不匹配會導(dǎo)致控制量輸出與實際系統(tǒng)狀態(tài)不同步嚴(yán)重時出現(xiàn)震蕩。我推薦在Simulink里用固定步長求解器并且步長等于MPC的Ts或者更小比如Ts/2這樣能減少這種問題。5.2 關(guān)于模型失配問題的一些經(jīng)驗MPC的性能上限取決于預(yù)測模型的準(zhǔn)確度這是一個繞不開的事實。純車仿真里模型匹配度高效果好看實車跑起來輪胎打滑、路面坡度、風(fēng)阻、電池SOC變化導(dǎo)致的動力響應(yīng)差異都會讓預(yù)測模型失真。我常用三種手段應(yīng)對模型失配。第一種在預(yù)測模型里增加擾動項。就是在狀態(tài)方程里加一個常數(shù)項或者可估計的擾動比如x(k1) A x(k) B u(k) d(k)這個d(k)可以在線估計比如用擴展Kalman濾波把坡度阻力、風(fēng)阻等未建模擾動統(tǒng)一估計出來代入MPC預(yù)測。這是最實用也見效最快的方法Model Adaptive MPC或者說帶擾動補償?shù)腗PC就是干這個的。第二種把模型參數(shù)做成調(diào)度表。比如tao動力總成時間常數(shù)隨車速和擋位變化你可以做一個二維查表供MPC模型查取當(dāng)前工況的參數(shù)。這種方法不需要復(fù)雜的在線辨識工程實現(xiàn)簡單穩(wěn)定性好。第三種采用魯棒MPC或者Tube-based MPC。這類方法把模型不確定性顯式考慮進(jìn)優(yōu)化里代價是計算量增加不少。現(xiàn)階段在整車控制器上量產(chǎn)應(yīng)用還不多但對復(fù)雜工況的前期研究很有價值。如果你想往深了做這是個很好的方向。5.3 計算實時性不夠怎么優(yōu)化MPC上實車最大的攔路虎就是實時性。我見過有些控制器的CPU主頻不算低但一跑MPC一個控制周期內(nèi)算不完整個控制節(jié)奏就亂了。優(yōu)化思路可以從三個層面入手。算法層面第一條路是減小Nc這是立竿見影的。Nc從10降到3優(yōu)化變量減少到原來的三分之一單步求解時間幾乎線性下降。第二條路是簡化預(yù)測模型比如把二階模型簡化成一階預(yù)測精度損失不大但QP規(guī)模明顯縮小。第三條路是采用顯式MPCExplicit MPC它把在線QP求解轉(zhuǎn)化為查表計算時間基本可以忽略不計代價是需要離線生成一個龐大的分區(qū)查找表適合小狀態(tài)維度的場景。工程層面你可以把MPC控制器放到獨立的核或者獨立MCU上跑與整車其他功能隔離避免其他任務(wù)搶占CPU。另外用MATLAB Coder把MPC算法生成C代碼后編譯優(yōu)化比如使用-O2甚至-O3對實時性提升很明顯。數(shù)值層面注意避免大數(shù)小數(shù)的病態(tài)矩陣。比如你狀態(tài)量是車速幾十的量級控制量是加速度個位數(shù)量級代價函數(shù)里的權(quán)重矩陣如果量級差距太大QP求解器收斂會很慢。解決方法是先對狀態(tài)和控制量做歸一化讓它們都在0到1或-1到1的范圍內(nèi)再進(jìn)入MPC計算。這個技巧我在多個項目里驗證過對求解時間和穩(wěn)定性都有明顯改善。6. 后續(xù)擴展方向MPC在整車控制上遠(yuǎn)不止縱向車速控制這一個應(yīng)用。我現(xiàn)在看到比較熱的幾個方向包括電池?zé)峁芾砗湍芰抗芾韰f(xié)同的MPC、四輪獨立驅(qū)動車輛轉(zhuǎn)矩分配的MPC、智能駕駛場景下軌跡規(guī)劃和跟蹤一體化的MPC還有面向整車執(zhí)行器冗余容錯控制的MPC。每個方向本質(zhì)上都是把MPC預(yù)測和約束的優(yōu)勢疊加到更復(fù)雜的系統(tǒng)模型和控制目標(biāo)上。如果你想把MPC往應(yīng)用層面進(jìn)一步做實我個人建議往能量管理層走一走。因為能量管理天然是一個強約束、多目標(biāo)、存在未來信息比如導(dǎo)航工況預(yù)測的問題和MPC的特性非常契合。而且能量管理對算力的要求不如底盤子系統(tǒng)那么苛刻是MPC量產(chǎn)落地比較務(wù)實的切入點。另外我個人在實際操作中的一個體會是MPC這門技術(shù)原理說實話三天能講完但真正要讓它在一臺車上穩(wěn)定跑起來靠的是接下來三個月甚至更長時間的調(diào)參、試錯和模型打磨。你可以把MPC看作一個好用的工具箱它給你提供了強大的框架但最終效果還得看你對被控對象的理解程度。工程師的功夫往往不在公式推導(dǎo)上而在面對一堆仿真曲線時能快速判斷出“是模型不對、權(quán)重不當(dāng)還是約束設(shè)置失衡”的那種感覺。這種東西沒法速成啃過幾個實際項目自然就有了。最后再分享一個小技巧不管你在什么項目里用MPC前期一定先把數(shù)據(jù)記錄和可視化做全。把狀態(tài)軌跡、控制輸入、約束邊界、參考軌跡全部存下來出問題時一條條曲線翻比看任何日志都管用。MPC調(diào)試的絕大多數(shù)問題都是通過“看曲線不對勁”這個直覺誘因才一步步定位到根因的。這個習(xí)慣建議從你第一個MATLAB仿真就開始養(yǎng)成。本文還有配套的精品資源點擊獲取