從擰旋鈕到寫下目標
在前面的台階,你靠手動調控制器——把某個增益往上推一點,看它晃,再推回去。對一個馬達這樣做沒問題,但當機器人有許多互相牽扯的關節時,這會讓人精疲力竭。最優控制把問題反了過來:與其撥弄旋鈕,不如寫下你真正想要的東西,讓數學把最能實現它的控制器交給你。
首先,你把機器人寫成一個狀態空間模型:它用一份緊湊的帳本記下機器人的狀態(每個關節的位置和速度),以及今天的狀態加上你施加的控制如何滾動成明天的狀態。這與逆動力學背後的想法相同——一個描述機器如何運動的模型——只是寫成了適合控制的形式。
然後你寫下一個代價——一個你希望越小越好的數字。它通常在兩樣你永遠無法兼得的東西之間權衡:跟蹤誤差(你離想要的設定值有多遠)和控制力氣(馬達有多吃力)。想要緊跟目標?就重罰誤差。想要一個溫柔、省電的機器人?就重罰力氣。你的意圖,就活在這個代價裡。
LQR:閉式解出的最佳線性反饋
當模型是線性的、代價是二次型的——誤差的平方加上力氣的平方——這個問題就有一個優美而精確的答案。它叫線性二次型調節器,簡稱 LQR。「二次」是說一切都被平方,正是這一點讓數學能一次乾淨地解出來;「調節器」是說它把狀態推回零(或推向你的目標)。
LQR 交給你的,是一個增益矩陣 K。控制律就是 u = −Kx:測出完整狀態 x,乘以 K,那就是你的指令。這是全狀態反饋——每個關節的指令都可以依賴其他所有關節的位置和速度,而這種耦合,正是給每個關節單獨手調一個 PID 迴路永遠無法完全捕捉的。
你仍然要擰的旋鈕,是兩個權重矩陣,通常叫 Q 和 R。Q 是你對狀態誤差的懲罰力度,R 是你對控制力氣的懲罰力度。把 Q 調大,機器人變得兇猛俐落,但馬達很吃力;把 R 調大,它變得沉穩省力,卻對跟蹤更懶散。你不再一個一個地猜增益——你在調兩個旋鈕,它們表達的是同一個誠實的權衡,而增益會自動算出來。
MPC:規劃一小段,行動,再重複
LQR 很出色,卻在一點上是「盲」的:它沒有「極限」的概念。如果數學這麼說,它會毫不猶豫地要求超過馬達所能提供的扭矩。模型預測控制,簡稱 MPC,透過提前思考來解決這個問題——像下棋的人那樣,每次只想幾步。
- 預測:在這一刻,用模型把機器人向前模擬一小段時間——比如未來 1–2 秒——試一組候選的動作序列。
- 最佳化:在這些序列中搜尋,找出代價最低的那一組——跟蹤最好、力氣最省——同時遵守你寫成硬性規則的約束。
- 行動:只執行這個計劃的第一步,其餘的全部丟掉。
- 重複:一個時間步之後,再次測量真實狀態,把整件事重做一遍——正是這種不斷重新規劃,讓 MPC 對意外保持穩健。
它的超能力,就在第二步的最後那個詞:約束。你可以把鐵律告訴 MPC:馬達在扭矩上限處飽和、關節不能彎過機械限位、足式機器人的腳必須留在支撐區內、無人機不能傾斜超過安全角度。PID 迴路是在事後與致動器飽和搏鬥,而 MPC 乾脆從不規劃一個它根本做不出來的動作。
如果你覺得這和軌跡優化像表親,沒錯——MPC 本質上就是在每一個控制時間步都從頭解一個小小的軌跡最佳化問題,每秒解上幾十甚至幾百次。
如何取捨,以及它們出現在哪裡
取捨主要關乎代價——這次是計算代價。LQR 離線把它的數學解一次,然後永遠只跑一個簡單的矩陣乘法:飛快、每步幾乎免費,但它一條約束都顧不上。MPC 線上、每一步都重解一次最佳化:能力強得多,卻既吃算力,又依賴一個可信的模型。
於是,當機器人待在已知工作點附近、約束很少咬人時,工程師就選 LQR——讓四旋翼懸停、讓倒立擺穩住,那些每一微秒都要緊的快速內環。而當極限就是全部關鍵時,他們就選 MPC——讓足式機器人在崎嶇地形上落腳而不翻倒、讓自動駕駛車在車流中穿行同時尊重加速度和車道邊界、讓無人機緊貼推力極限激進飛行。
兩種方法都假設你能看到完整狀態 x,但真實感測器只給你它的一部分。這道缺口由狀態估計器填補——一個狀態觀測器或卡爾曼濾波器——它從測量中重建出缺失的狀態,再餵進去。最優控制和好的估計,是同一台機器的兩半;下一條主線,將探索估計這一半。
loop every tick:
x = estimate_state() # from sensors
plan = optimize(model, cost,
constraints, # torque, joint, safety limits
horizon = N) # simulate N steps ahead
u = plan.first_move # apply only step 1
send_to_motors(u)
# next tick: re-measure, re-plan from scratch