與對比分析)
做控制算法驗證我最不喜歡的工作就是每換一套被控對象就要重新推一遍模型更不用說在模型失配之后再去調(diào)一堆觀測器和狀態(tài)估計參數(shù)。這套數(shù)值驗證仿真程序解決的就是這個痛點MFAPC無模型自適應預測控制和 MFAILC無模型自適應迭代學習控制在理論上都不需要顯式建模只靠輸入輸出數(shù)據(jù)就能在線或迭代地調(diào)整控制律。我用 MATLAB 把兩個算法從公式落成了可運行的代碼能在同一框架下對比跟蹤誤差、抗干擾能力和參數(shù)敏感度。自動化專業(yè)學生、剛開始接觸數(shù)據(jù)驅(qū)動控制的研究生以及想快速驗證算法效果的工程師都可以拿這套程序做基線。下面從原理到實現(xiàn)再到調(diào)試經(jīng)驗和結果解讀把整個程序講透。1. 從模型依賴到數(shù)據(jù)驅(qū)動這兩種算法到底在解決什么問題1.1 傳統(tǒng)控制為什么繞不開建模大多數(shù)經(jīng)典控制方法的第一步都是建模。PID 雖然不需要精確模型但參數(shù)整定嚴重依賴工程經(jīng)驗MPC 需要預測模型滑模、反步法更是離不開對象微分方程。真實工業(yè)對象往往有強非線性、參數(shù)時變和未建模動態(tài)模型越精細計算開銷和辨識成本越高模型一旦失配控制性能掉得比誰都慘。無模型自適應控制MFAC的出發(fā)點很直接既然精確模型難拿那就干脆放棄模型把被控對象在每一個工作點附近用一個非常簡單的時變線性關系近似出來。這個“時變線性關系”不是我們對物理機理的假設而是一種數(shù)學上的等價轉(zhuǎn)化。只要對象滿足一定的有界性和光滑性條件在相鄰兩個采樣時刻之間輸入變化和輸出變化之間就存在一個時變系數(shù)。1.2 緊格式動態(tài)線性化與偽偏導數(shù)MFAC 家族里最常用的是緊格式動態(tài)線性化Compact Form Dynamic LinearizationCFDL。對離散時間非線性系統(tǒng)CFDL 說的是Δy(k1) φ(k)·Δu(k)其中 Δy(k1) y(k1) - y(k)Δu(k) u(k) - u(k-1)。這里的 φ(k) 叫作偽偏導數(shù)Pseudo Partial DerivativePPD。注意它并不是對象的真實偏導數(shù)而是一個吸收了對象非線性、時變特性和外部擾動影響的時變參數(shù)本質(zhì)上可以看成當前工作點附近的“等效增量增益”。這個式子有什么好處好處特別大控制器設計不再需要知道 f 的具體形式只需要在線估計 φ(k)。一個標量參數(shù)用差分數(shù)據(jù)就能遞推辨識出來這就是整個程序的核心底層。只要 φ 估計得準控制律就可以設計成“用當前預測誤差除以等效增益”的形式。1.3 MFAPC 和 MFAILC 的分工邏輯MFAPC 和 MFAILC 雖然都建立在 CFDL 基礎上解決的是兩類不同問題。MFAPC 針對的是實時在線控制系統(tǒng)在同一個時間軸上連續(xù)運行控制器每個采樣周期都要決策一個控制增量。它把預測控制里的“滾動優(yōu)化、反饋校正”思想搬到了無模型框架下用預測時域內(nèi)的輸出偏差來反推當前控制量。因為 PPD 是隨時間在線更新的對象特性變了φ(k) 會跟著變控制律也隨之調(diào)整所以它對時變系統(tǒng)有天然的適應能力。MFAILC 針對的是重復運動過程機械臂每次執(zhí)行同一個軌跡、注塑機每個批次走同樣的工藝曲線、電機反復跟蹤同一個速度曲線。這類系統(tǒng)的特點是時間軸不再單獨存在而是嵌套在“批次數(shù)”里面。迭代學習控制每一次運行結束后用本次的跟蹤誤差去修正下一輪的輸入軌跡讓誤差隨迭代次數(shù)逐步衰減。它的控制作用不是采樣時刻的瞬時調(diào)整而是整個輸入序列在“迭代軸”上的演進。說白了MFAPC擅長對象特性在變、任務實時變化的情況MFAILC擅長任務固定、重復運行、希望越跑越準的情況。仿真程序同時實現(xiàn)這兩個算法最大的價值就是可以把同一套被控對象放進兩種運行模式里直接量化它們的差異。2. 仿真程序整體架構與驗證指標設計2.1 程序模塊劃分整套程序按模塊拆分會更清楚我實際編寫時分成四塊對象模塊被控對象的差分方程、非線性算式、時變參數(shù)切換邏輯統(tǒng)一封裝成函數(shù)方便替換。控制器模塊MFAPC 主循環(huán)和 MFAILC 雙層循環(huán)分別實現(xiàn)兩者共用 PPD 估計器函數(shù)。信號模塊參考軌跡生成、干擾疊加、噪聲注入、輸入約束限幅。分析模塊誤差指標計算、曲線繪制、迭代收斂趨勢統(tǒng)計。這種劃分的好處是改對象不用動控制器調(diào)控制器不用動對象。仿真實驗最怕的就是把對象邏輯和控制邏輯耦合在一起后面想換一個被控對象改代碼改到懷疑人生。2.2 驗證對象與基線設計程序里建議至少準備三個被控對象線性定常系統(tǒng)用于理論驗證檢測算法實現(xiàn)是否準確。非線性時變系統(tǒng)用于驗證自適應能力比如參數(shù)在運行中途突變。帶輸出噪聲和外部干擾的系統(tǒng)用于驗證魯棒性。我個人用的典型線性對象是y(k1) 1.2·y(k) - 0.4·y(k-1) 1.0·u(k) 0.8·u(k-1)非線性對象則用經(jīng)典算例y(k1) y(k)/(1 y(k)^2) u(k) 0.7·u(k-1)第二個對象在 y 接近零點時增益變化明顯能比較充分地考察 PPD 估計器跟不跟得上。參考軌跡可以選方波、正弦、斜坡或者梯形速度曲線。這里建議不要只用階躍因為階躍參考對預測控制太友好了不容易暴露問題。我習慣用帶突變的正弦組合比如 0~200 步正弦200~400 步切換成方波這樣可以一次看夠穩(wěn)態(tài)跟蹤和瞬態(tài)響應。2.3 評價指標如何設計指標直接影響結論的可信度不要只看最后一張圖。RMSE 用于衡量整體跟蹤精度公式不用多說就是誤差平方和開根號。MaxAbsError 用于衡量峰值偏差特別能反映突變點的表現(xiàn)??刂颇芰?ΣΔu2 用于衡量控制量抖動程度。兩個算法精度差不多的時候誰的輸入更平穩(wěn)工程上更重要。迭代收斂速度MFAILC專用定義第一次滿足 RMSE 閾值所需迭代次數(shù)。評價時建議固定對象和參考軌跡單獨變化算法參數(shù)記錄指標到二維表里。沒有量化對比就直接畫曲線說“效果不錯”的基本等于沒做驗證。3. 核心算法與 MATLAB 實現(xiàn)細節(jié)3.1 被控對象離散模型與信號生成MATLAB 里被控對象直接寫成函數(shù)比如非線性對象function y_next plant_nonlinear(y, y_prev, u, u_prev, a_noise) y_next y / (1 y^2) u 0.7 * u_prev a_noise * randn; end對象函數(shù)建議把噪聲強度作為參數(shù)傳進來這樣在對比算法時可以保持完全相同的一組隨機種子結果才有可對比性。仿真中不要每次運行都改變隨機種子否則你很難判斷性能差異來自算法還是噪聲。我習慣在腳本開頭用 rng(2024) 固定隨機流確保重復實驗得到一致結果。3.2 MFAPC 控制器實現(xiàn)MFAPC 的核心循環(huán)分三步PPD估計、構建預測矩陣、求解控制增量。PPD 估計器采用帶重置的遞推格式φ?(k) φ?(k-1) η·Δu(k-1)·(Δy(k) - φ?(k-1)·Δu(k-1)) / (μ Δu(k-1)2)重置條件為 |φ?(k)| 小于閾值、Δu(k) 過小或者 φ? 符號跳變此時令 φ?(k) φ??。這里的 μ 是個很小的正數(shù)主要防止分母為零。沒有重置機制的 PPD 估計器很容易在對象增益接近零時把參數(shù)沖到很大。預測模型的構造是 MFAPC 與普通 MFAC 的核心區(qū)別。CFDL 一次只給出了 Δy(k1) 和 Δu(k) 的關系若要預測未來 N_y 步需要假設 PPD 在預測時域內(nèi)近似不變。于是?(ki) y(k) φ?(k)·[Δu(k) Δu(k1) ... Δu(ki-1)]寫成矩陣形式就是Y Y? Φ·ΔU其中 Φ 是 N_y × N_u 的下三角矩陣行越往下包含的 Δu 項越多。目標函數(shù)選經(jīng)典預測控制形式J ‖Yr - Y‖2 λ·‖ΔU‖2對 ΔU 求極值得到ΔU(k) (Φ?Φ λI)?1·Φ?·(Yr - Y?)實際只取 ΔU(k) 第一項作為當前控制增量。核心代碼大致是這樣for k 3 : Nsim dy y(k) - y(k-1); du u(k-1) - u(k-2); % 1. PPD 估計 denom mu du^2; phihat(k) phihat(k-1) eta * du / denom * (dy - phihat(k-1) * du); % 2. 重置機制 if abs(phihat(k)) eps_phi || abs(du) eps_du phihat(k) phihat0; end % 3. 構建預測矩陣 Phi: Ny x Nu Phi zeros(Ny, Nu); for i 1 : Ny for j 1 : min(i, Nu) Phi(i, j) phihat(k); end end Y0 y(k) * ones(Ny, 1); Yr ref(k1 : kNy); dU (Phi * Phi lambda * eye(Nu)) \ (Phi * (Yr - Y0)); u(k) u(k-1) rho * dU(1); % rho 是步長因子 end這里面最容易被忽略的是矩陣維度。預測時域 N_y 必須大于等于控制時域 N_u否則 Φ 不是“列滿秩×帶寬三角”的正常結構求解時數(shù)值性質(zhì)很差。一般推薦 N_y 取 3~5N_u 取 1~2不是越大越好。3.3 MFAILC 控制器實現(xiàn)MFAILC 的結構跟 MFAPC 完全不同它是雙層循環(huán)外層是迭代次數(shù) j內(nèi)層是時間 k。每一輪迭代先用當前輸入軌跡跑一遍對象記錄完整的輸出軌跡然后按時間點逐個更新輸入序列。PPD 在迭代軸上的估計方式是φ??(k) φ????(k) η·Δu???(k)·(Δy???(k1) - φ????(k)·Δu???(k)) / (μ Δu???(k)2)注意這里每個時間點 k 都有自己獨立的 φ?(k)不能像 MFAPC 那樣只維護一個標量。因為輸入軌跡上的每個點在不同迭代中會反復修正它們各自的“輸入增量到輸出增量”的映射關系不一樣必須分別估計。學習律采用帶步長的形式u???(k) u?(k) ρ·φ??(k) / (λ φ??(k)2)·e?(k1)其中 e?(k1) y_r(k1) - y?(k1)。分母里的 λ 不光是防止 φ?0 時除零更重要的是調(diào)節(jié)學習增益φ? 大時分母近似 φ?2學習律趨于 1/φ?φ? 小時分母被 λ 主導學習增益被限制住避免參數(shù)估計不準時把輸入軌跡改得亂七八糟。一段可運行的循環(huán)結構如下u_cur zeros(Nsim, 1); % 初始輸入軌跡也可以先跑一次得到基線 for j 1 : MaxIter % 使用當前輸入軌跡運行對象 y zeros(Nsim, 1); for k 1 : Nsim-1 y(k1) plant(y(k), y(k-1), u_cur(k), u_cur(k-1), noise_on); end % 計算跟蹤誤差 e ref(2:Nsim) - y(2:Nsim); % 按時間點更新輸入軌跡 u_next u_cur; for k 1 : Nsim-1 du u_cur(k) - u_cur(k-1); dy y(k1) - y(k); phihat(k) phihat_prev(k) eta * du / (mu du^2) * (dy - phihat_prev(k) * du); if abs(phihat(k)) eps_phi || abs(du) eps_du phihat(k) phihat_init(k); end u_next(k) u_cur(k) rho * phihat(k) / (lambda_ilc phihat(k)^2) * e(k); phihat_prev(k) phihat(k); end u_cur u_next; record_rmse(j) sqrt(mean(e.^2)); endMFAILC 的初始輸入軌跡非常影響收斂速度。如果初始輸入全為零第一次迭代誤差可能很大但一般也能收斂。比較聰明的做法是先跑一次普通 MFAC把得到的輸入軌跡作為初始 u_cur這樣迭代次數(shù)能省一半。3.4 參數(shù)整定經(jīng)驗匯總兩個算法的參數(shù)含義不一樣但調(diào)參邏輯有相通之處。下表是我反復實驗后的建議范圍參數(shù)所屬算法作用建議范圍調(diào)整方向η兩者共用PPD 估計步長0.1~1太大易發(fā)散太小收斂慢μ兩者共用防止分母為零0.0001~1越小估計越靈敏但抗噪差ρ兩者共用控制/學習步長0.4~1太大系統(tǒng)易振蕩λMFAPC控制能量懲罰0.001~1越大控制越保守、響應越慢N_yMFAPC預測時域3~5越大滾動優(yōu)化效果越弱越慢N_uMFAPC控制時域1~2太大容易加劇抖動λ_ilcMFAILC學習律分母0.01~1越大學習增益越低MaxIterMFAILC迭代次數(shù)50~200依據(jù)收斂曲線判斷這些數(shù)字是經(jīng)驗值不是定理。不同被控對象對參數(shù)敏感度差別很大調(diào)參時一次只動一個變量。我最常犯的錯誤就是兩個參數(shù)一起調(diào)出了問題根本不知道是誰引起的。4. 數(shù)值結果與性能對比分析4.1 三種場景下的仿真結果我用固定參考軌跡在三個對象上做了對比實驗。線性定常系統(tǒng)上MFAPC 在 N_y4、N_u2、λ0.01、η0.6 的條件下RMSE 大約在 0.012 附近控制量平滑沒有明顯抖動。MFAILC 第一次迭代 RMSE 約 0.35到第 25 次迭代降到 0.005跟蹤精度略優(yōu)于 MFAPC畢竟它可以反復利用整條軌跡的誤差信息。但要注意MFAILC 的精度優(yōu)勢來自離線學習的“重復紅利”如果任務只跑一次它沒有任何優(yōu)勢。非線性時變對象上我把對象增益在中間時刻切換讓參數(shù)發(fā)生跳變。MFAPC 的 PPD 估計器能在大約 10 到 20 個采樣周期的在線調(diào)整后重新鎖定RMSE 會短暫惡化之后恢復。MFAILC 因為整個輸入軌跡是在迭代軸上學習的如果參考軌跡和對象都變了前一迭代學到的輸入軌跡基本作廢得重新學習。這個對比很能說明問題MFAPC 適合變化的在線環(huán)境MFAILC 適合固定任務。帶噪聲和輸出干擾的情況下MFAPC 的控制量會出現(xiàn)明顯高頻分量。這是預期的因為 PPD 估計把噪聲當成了真實輸出變化。解決辦法不是把 η 調(diào)小到學習能力變差而是對輸出做先濾波或者在 PPD 估計的差分項里加一個平滑。MFAILC 因為整個軌跡是批量處理的噪聲在迭代平均中會被部分抵消所以它在強噪聲下的收斂趨勢反而比 MFAPC 穩(wěn)。4.2 結果背后反映的算法特性從結果可以提煉出幾條對實際選型有用的結論。MFAPC 本質(zhì)上是“在線辨識等效增益 滾動預測優(yōu)化”所以它對初始參數(shù)不敏感對時變對象有自適應能力但性能上限受限于 PPD 估計精度。當對象在相鄰采樣點之間的變化過于劇烈比如快速切換方向CFDL 近似會變差控制量容易沖過頭。MFAILC 本質(zhì)上是“批量修正輸入軌跡”它把整個時間的跟蹤誤差都利用上了所以穩(wěn)態(tài)精度可以非常高。但它有兩個先天弱點一是不能處理迭代之間的任務變化二是對初始狀態(tài)偏移敏感——如果每一輪的初始狀態(tài)不一樣學習到的輸入軌跡很難對新的一次任務有好的效果。仿真程序把兩種算法放在同一套代碼框架里最重要的意義就在這里不是告訴你哪個算法更好而是讓你直觀看到它們適用邊界在哪里。5. 常見問題與排查技巧5.1 PPD 估計發(fā)散這是仿真里出現(xiàn)頻率最高的問題。表現(xiàn)是 phihat 曲線突然沖到幾十上百控制量跟著劇烈波動系統(tǒng)很快跑飛。排查順序按概率排列先看 Δu 是否長時間保持為零。如果輸入長時間不變化PPD 估計的信息來源就斷了分母 μ Δu2 里只有 μ 撐著估計只會漂移。對策是給輸入疊加持續(xù)激勵信號或者在重置條件里增加對 Δu 的檢查。再看 μ 是否設得太小。μ 太小會讓估計對噪聲過于敏感尤其輸出帶高斯噪聲時差分 dy 的信噪比很差。最后看 ηη 最好從 0.3 起步先確認不發(fā)散再加到 0.8。還要強調(diào)一點重置條件不是擺設。對象增益穿過零附近時φ? 會出現(xiàn)符號跳變?nèi)绻恢刂每刂屏糠柨赡芊戳讼到y(tǒng)直接發(fā)散。我的程序里重置閾值取 0.01 到 0.05同時判斷 |φ?(k)| 與 Δu 的邊界寧可多重置幾次也別讓它自由漂移。5.2 控制量高頻抖動MFAPC 控制量抖動的根因通常是預測模型把噪聲當成了可以優(yōu)化掉的偏差。理想情況下PPD 估計器只建模輸入變化到輸出變化的因果關系但輸出噪聲會混入 dy污染 φ???刂屏恳欢断乱慌牡?dy 又受影響形成正反饋。我的處理習慣一是把 λ 從 0.001 調(diào)到 0.05 起用控制能量懲罰壓住抖動二是減小 ρ從 1 降到 0.6 左右三是在輸出端加一階慣性濾波比如 y_filtered α*y (1-α)*y_filteredα 取 0.7。濾波帶來的相位滯后在仿真里通??山邮艿茨愕尿炞C目標——如果驗證重點是高頻跟蹤能力濾波會掩蓋問題這時候還是優(yōu)先調(diào) λ。5.3 MFAILC 收斂慢MFAILC 跑了很多次迭代誤差還在 0.1 以上基本是學習增益太小或初始軌跡太差。對應措施把初始輸入軌跡改為零階保持的參考軌跡縮放值不要全零起步適當加大 ρ但同時要小心第二次迭代輸入就可能振蕩把 λ_ilc 減小到 0.01 到 0.1增強學習強度。還有一個容易被忽略的因素參考軌跡在時間軸上提前一個采樣點。學習律用的是 e(k1)對應的是 u(k) 到 y(k1) 的時序關系。如果代碼里不小心對錯了索引誤差和輸入之間隔了兩個周期學習律就會學混亂。我在調(diào)試時就踩過這個坑跟蹤誤差曲線在 100 次迭代里幾乎不動仔細查才發(fā)現(xiàn)是 e(k1) 寫成了 e(k)。5.4 快速排查速查表現(xiàn)象優(yōu)先排查參數(shù)處理建議phihat 發(fā)散Δu激勵不足、μ太小、η太大疊加激勵信號μ上調(diào)至0.1η降到0.3控制量抖動λ太小、ρ太大、噪聲混入λ調(diào)至0.05ρ降至0.6輸出濾波跟蹤穩(wěn)態(tài)誤差大PPD重置太頻繁、N_y太小放寬重置閾值N_y調(diào)至5MFAILC不收斂索引錯位、初始軌跡差、ρ太小嚴格校核時延初始軌跡設為參考值預測矩陣奇異N_y小于N_u保證N_y ≥ N_u因為程序是分模塊的定位問題很快對象函數(shù)單獨跑一遍看輸出是否合理PPD 估計單獨畫出來看曲線是否平滑最后再疊加控制器閉環(huán)。逐層排除比直接在閉環(huán)里猜快得多。6. 把仿真程序用起來的一些體會6.1 從仿真到實驗的過渡仿真驗證只是第一步。我經(jīng)??吹接腥朔抡媲€調(diào)得很漂亮一到實物就翻車最典型的是把仿真里無限帶寬的控制量直接丟給執(zhí)行器。程序里最好一開始就加入控制輸入限幅和變化率限幅比如 u ∈ [-1, 1]、Δu 限幅在 0.05 以內(nèi)。這樣仿真結果更接近實物的真實邊界避免“仿真能用、實物超限”的尷尬。另一個仿真與實驗差距的重要來源是對象時延。仿真對象常常忽略純時延但實際系統(tǒng)都有測量延遲建議在對象函數(shù)里加入一到兩個采樣周期的延遲環(huán)節(jié)提前考察算法在這種“相位損失”下的穩(wěn)定性。6.2 后續(xù)可以擴展的方向這套程序可以繼續(xù)加裝幾塊內(nèi)容。一是把 PPD 估計器從緊格式換到全格式動態(tài)線性化加入更多歷史輸入輸出數(shù)據(jù)適應更復雜的對象。二是給 MFAPC 增加輸入約束處理把二次規(guī)劃引入優(yōu)化步讓控制增量受限時仍有可行解。三是把 MFAILC 的固定學習增益改成自適應遺忘因子迭代到后期自動放慢學習速度避免輸入軌跡在噪聲激勵下反復橫跳。我個人實際使用中的體會是MFAPC 的參數(shù)初值對快速調(diào)試非常重要第一次跑通時不追求最優(yōu)先用大 μ、小 η、中等 λ 讓系統(tǒng)穩(wěn)定再逐步收緊參數(shù)逼近精度極限。MFAILC 則建議每次修改對象模型后都清空上一輪的 φ? 和輸入軌跡歷史千萬不要在舊軌跡上硬疊新對象的學習結果。仿真驗證的目的不是刷出“看起來很好”的曲線而是幫你理解算法在什么條件下會失靈后續(xù)到了實驗平臺才不至于手足無措。