###### tags: `自駕車` # F-Drive PID 控制 自駕車的控制並不是單純車子偏向道路左側就向右轉、偏向道路右側就向左轉: ``` 轉右 ^ | ------+ | ------+------>車子偏右 | +------ | ``` 這樣的控制方式往往會轉過頭, 這是因為感測資訊進到系統裡的時間一定比實際發生的時間晚, 也就是說自駕車已經修正回道路中央, 感測器才會回饋資訊回控制系統修正轉向, 在這段落差時間內, 自駕車仍然維持原本的轉向, 所以實際結果會超過道路中央, 這稱為**過衝 (overshoot)**。甚至因為偏向另一側造成後續再往回修正, 造成來回修正的震盪。 如果以溫度加熱器為例, 即使到達設定溫度後立刻關閉加熱器, 由於加熱器本身仍有餘溫, 所以還會持續加熱一小段時間, 造成溫度超過設定門檻。 ## 比例 (Proportional) 控制 為了避免過衝, 我們可以使用比例控制, 比例控制簡單來說就是依據當前狀態與設定值的差異, 依照比例調整控制強度。以自駕車來說, 就是指依照偏離道路中央的程度, 調整轉向的角度, 偏越多調越大、 ``` 轉右 ^ \ | \ | \| ------\------>車子偏右 |\ | \ | \ ``` 圖中這條直線的斜率, 可以控制轉彎幅度, 斜率越大, 轉向調整的幅度就越大。 ## 積分 (Integra) 控制 在理想的狀況下, 使用比例控制就可以讓自駕車完美的保持在道路中央行進, 不過現實環境中, 可能因為零組件的公差、路面的摩擦力差異、或是路面的傾斜角度不同, 即使前輪轉向控制在正中間, 也可能無法走出直線, 而會有偏差。 為了彌平環境外力造成的影響, 就會需要觀察過去一段時間內的偏差總和: ``` 車子偏右 ^ | | |⠄⠆⠇⠆⠆⠄ ⠄⠄ +------------------->時間 | |>3<|>0<| ⠁⠃⠃ | 累積偏差 | V 車子偏左 ``` 如果過去一段時間的偏差總和沒有歸零, 表示我們修正的結果可能受到環境外力的影響, 因此必須利用偏差總和來增加修正量。以自駕車的例子來說, 我們期望修正結果車子會回到道路正中央, 但如果偏差累積的結果車子仍偏向道路左邊, 這表示我們要加大往右轉的角度, 消抵環境外力的影響。 ## 微分 (Derivative) 控制 除了環境外力影響以外, 自駕車本身有運動的慣性, 例如當自駕車從右轉改為往左轉, 但原本往右轉的力道不會立即消失, 這會削減當前往左轉的修正效果。因此我們也要觀察過去一段時間內偏差的改變趨勢, 預測未來的偏差走向, 藉此來調整控制力道。 以自駕車來說, 如果現在偏向車道右側, 正在以左轉修正: ``` 車子偏右 ^ 往左轉修正 | | | V | ⠄⠆⠇ +------------------->時間 | | | V 車子偏左 ``` 但發現偏差值不減反增, 這就有可能是因為車子的慣性仍在往右甩動, 因此就必須增加往左轉的角度, 藉此消抵慣性的作用。 ## PID 控制 依據前面的介紹, 自駕車實際轉彎的角度可以下列算式表示: $$ 轉動角度 = K_p \times 偏差值 + K_i \times 累積偏差 + K_d \times 偏差變化 $$ 實際上 F-Drive 並沒有使用積分控制, 只有使用 PD 控制, 它將車道分成 100 等分, 車道中央為 50, 並以鏡頭中央點為車子位置, 計算車子位置與車道中央的差距作為偏差值。因此, 若偏差值為正, 表示車子偏向道路右側;反之偏差值為負, 表示車子偏向道路左側。F-Drive 會使用 PD 控制的簡化形式先調整車子的位置: $$ 調整後位置 = 目前車子位置 + 0 \times 累積偏差 + 2 \times (本次偏差 - 前次偏差) $$ 若車子在車道左側, 且持續往道路左側偏移, 則**本次偏差減前次偏差**為負值, 上述算式等於將車子的位置往道路左側調整, 強迫加大往右轉的修正角度;反之若車子在車道左側, 且持續往右偏, 則**本次偏差減前次偏差**為正數, 上述算式等於將車子的位置往右調整, 減緩稍後向右轉的角度, 可以避免過衝。 最後, F-Drive 會依照調整後的車子位置以比例控制的方式, 轉換為旋轉角度, 它會將靠近道路中央的兩側 25 個百分比位置與較遠的兩側 25 個百分比位置使用不同的比例轉換轉彎角度, 以便讓偏差較小時旋轉變化幅度較小, 而在偏差較大時選轉幅度較大, 較快修正回到道路中央。 利用這樣的 PD 控制, 就可以讓自駕車避免單純只有 P 控制時左右搖擺的狀況, 保持幾乎直行的完美效果。