馬達的力氣是有上限的
在紙面上,控制器想發出多大的指令都行。PID 控制器根據機器人當前位置與目標位置之間的誤差算出一個數值,再把它交給馬達。但真實的馬達是有上限的:供電電壓是固定的,電流超過某個值就會過熱,輸出力矩也存在一個根本無法突破的峰值。當控制器要求的力超過硬體能給的,指令就會被「削頂」。這種削頂就叫致動器飽和。
想像你踩油門,而油門已經踩到底了。你再怎麼用力,車也不會加速更快——踏板已經飽和。控制器的處境一模一樣:超過極限後,再要求更多也得不到任何回報。飽和不是故障,每個真實系統都有它。危險在於:控制器內部的運算並不知道馬達已經「聽不進去了」,它會繼續按照「指令完整執行了」的假設去計算。
積分飽和:積分項越堆越高
PID 裡的積分項,存在的意義就是消滅那個頑固的殘餘偏差。當比例項和微分項都穩定下來後,往往還會留下一個小小的恆定誤差——重力把手臂往下拉、摩擦力把它拖住。這個揮之不去的偏移就叫穩態誤差,而積分項靠「把誤差隨時間累加起來」來消除它:只要還有缺口,積分就會不斷增長,直到累積出足夠的力把缺口徹底補平。
現在把它和飽和疊加起來。假設機器人離目標很遠,馬達已經頂到最大輸出。誤差始終很大,因為機器人在物理上根本動不了更快——而積分項還在盡職盡責地一秒一秒累加這個巨大的誤差,膨脹到一個驚人的數值。這種在飽和期間失控般的累積,就叫積分飽和(integrator wind-up)。
破壞會在終點處顯現。當機器人終於到達目標,誤差翻轉為零——但臃腫的積分項不會瞬間消失。它必須靠一段方向相反、長度相當的反向誤差來「放掉」。於是機器人會徑直衝過目標,嚴重過衝,然後不得不往回擺,有時還要來回振盪好幾下才停下。一個在溫和模擬裡看起來很正常的控制器,可能在真實致動器一飽和的那一刻就變得狂野、失穩。
讓 PID 守規矩的實用防護
好消息是:積分飽和有一套久經考驗的對策,而且加起來都很省事。抗積分飽和的核心思路只有一句話——別再騙積分項了。要讓它知道馬達實際輸出了多少,這樣在飽和期間,它就不會再去累加那些它根本無能為力的誤差。
- 箝制積分。只要指令處於飽和狀態,就停止往累積誤差裡繼續添加,並給積分項設一個合理的上限。這是最簡單的抗積分飽和手段,往往單靠它就夠用。
- 反算補償。把「請求的指令」與「被削頂後的指令」之差回饋回積分器,在馬達頂滿時溫和地把它「放水」排掉。這樣積分項是平滑退掉的,而不是一下子全卸。
- 限制目標值及其變化率。別下達致動器根本跟不上的跳變指令。讓目標平滑地爬升,控制器從一開始就不會去要求不可能的事,也就根本不會陷入飽和。
- 對微分項做濾波。微分項響應的是誤差的變化率,這讓它對感測器雜訊極其敏感。原始雜訊會被放大成抖動的指令。給微分項加一個輕度低通濾波,或把微分增益調小一點,就能讓它繼續發揮作用,而不至於對每一個帶雜的讀數都大喊大叫。
要注意,這幾項防護多半會和你的增益整定相互牽連。一個為追求速度而調得激進的控制器,會更頻繁地飽和、積分飽和也更嚴重,所以抗積分飽和和整定最好放在一起考慮,而不是當成兩件互不相干、事後再補的事。目標是:即便硬體被逼到極限,整個迴路依然可預測,並保持穩定性。
下一步去哪:PID 之後
PID 之所以是機器人領域的主力,是有道理的:它簡單、穩健,幾乎不需要機器人的模型。但它把每個關節孤立地對待,對自己正在對抗的物理一無所知——重力、慣性、關節之間的耦合。對於又快、又重、或需要緊密協調的運動,這些盲點就開始讓你付出代價,而上面那些補丁能做的也就到此為止。
下一階就是「進階控制」這一章,那裡的控制器會用機器人的動力學模型來規劃自己的指令。計算力矩控制會預先抵消掉重力和慣性,剩下的活兒就輕鬆得能交給一個簡單的回饋迴路。模型預測控制(MPC)會往未來看好幾步,而且關鍵在於——它能把致動器的極限當作如實的約束直接納入,於是從一開始就不會發出會導致飽和的指令。而線性二次型調節器(LQR)以及更廣義的最佳控制,則透過最小化一個你自己定義的代價函數來整定整個迴路,在精度與代價之間求得平衡。