Duckietown 專案 – Duckiebot DB21M 基礎操作(三) – PID controller 的使用

一、前言

在上一篇文章「Duckietown 專案 – Duckiebot DB21M 基礎操作(二) – Differential drive configuration 的使用」中,我們成功的透過 Differential drive configuration 讓 Duckiebot DB21M(以下皆稱為小鴨車)接受到往前行的指令時,能夠走在一條直線上。

透過 Differential drive configuration 這種簡化的輸入÷輸出驅動模式,讓我們能夠控制小鴨車的動作,那我們是否也能夠設計一個控制系統,讓小鴨車在自動駕駛中,做出我們想要的反應呢?例如根據白線與黃線的相對位置,自動駕駛於兩條線道之間?

二、PID controller

現在我們先想像一個問題 : 要怎麼讓一個磚塊飛起來呢?一個控制工程師也許會這樣回答,「透過這種控制方法,就可以讓磚頭飛起來── 飛機 x 磚頭÷磚頭」。磚頭項目互相抵消,只留下飛機,而飛機又可以飛,這樣不就讓磚頭飛起來了!

藉由這個讓磚頭飛起來的笑話其實抓住了前饋控制(feedforward control)的本質:根據擾動或給定值的變化按補償原理來進行工作的控制系統。但事實上,模型的不確定性與實際上所遇到的問題,會讓實際輸出與期望輸出的結果有所不同。如下方示意圖,原本預期向上飛行的飛機,過程中卻因為訊號延遲或雜訊等干擾因素,導致飛機向下墜落的結果,都會讓我們在解決控制問題時變得更加困難。

為了讓控制系統能夠有更好的效果,有一個非常受歡迎的控制方法,Proportional Integrative Derivative ,簡稱為 PID 控制器便因應而生。

Proportional Integrative Derivative

Proportional (比例 )、​Integral (積分)、Derivative ( 微分)

這是一個反饋(feedback)控制方法,這個控制系統即使在沒有任何預先輸入相關模型的情形下,也能夠正常運作。

在 PID 控制方法中,是由三個線性訊號組合而成的,分別是:

  1. tracking error (追蹤誤差)
  2. integral tracking error (積分追蹤誤差)
  3. derivative tracking error (微分追蹤誤差)

PID 控制器便是設計與上述三個線性訊號組合的相關線性係數,來達成令人滿意的控制表現。

PID 控制器是可以直覺地被設計並實現出來的一種方法,它也能夠在整個系統執行過程中,邊執行邊調整控制反應,並且在各種不同的實際應用上都能有令人滿意的表現。

要使用 PID 控制器,便需要使用到誤差訊號,這是由控制器實際輸出的數值與參考訊號的數值,互相比較得來的結果。

舉個例子,小鴨車想要以 V0的速度穩穩地走在一條綠色虛線上,車頭朝向正前方的角度以 0 度表示。如果現在小鴨車的位置是在綠色虛線下方往前行進,這與我們想要小鴨車走在綠色虛線上,有著很明顯的誤差值e0,如下圖所示。

PID 控制器中的 P(Proportional) 部分,指的便是與誤差數值大小呈現一個線性比例關係(正比)的訊號,並且這個訊號會嘗試將小鴨車往誤差數值的相反方向移動,如下圖所示。

若我們嘗試將 P 控制器的係數增加時,小鴨車便可越快回到綠色虛線上,這也將導致在這個閉環裡,小鴨車的反應速度將會提高。但需要注意的是, P 控制器的係數增加,小鴨車能夠穩定地走在綠色虛線上所花費的時間也會相對地提高,小鴨車也通常會在綠色虛線上出現震盪運動,如下圖所示。

PID 控制器中的 D(Derivative) 部分,指的是誤差變化的頻率並呈現線性比例的關係,或是誤差的導數。D 控制器讓小鴨車能夠預測鄰近未來會發生什麼錯誤,讓小鴨車能夠避免過度反應,並增加控制器的整體穩定性。換句話說,D 控制器的係數將會降低系統的反應時間,如下圖所示。

但 D 控制器的係數也不是全然都有良好的影響,由於 D 控制器的係數會根據誤差變化的頻率來對整個系統做出適當的反應,因此不可避免的也會將誤差中的雜訊也一併考量在內,這使得 D控制器的係數對於誤差變化中的雜訊會變得非常敏感,因此在使用 D 控制器的係數時,需要特別小心,如下圖所示。

PID 控制器中的 I(Integrative) 部分,指的是隨著時間的進行,所累積出的誤差值。這將會讓  I 控制器能夠根據先前累積的錯誤進行修正,並由此偵測出潛在的偏差值。I 控制器將會為了嘗試降低偵測到的偏差,並回到來的穩定狀態而有所動作,如下圖所示。

當 I 控制器的係數增加時,將會使得控制器的反應變得更加震盪,但對於誤差中的雜訊並不會有任何過激的反應,如下圖所示。

接下來,我們將來試如何使用程式碼,實現 PID 控制器喔!

三、操作環境需求

1. Duckietown 的操作環境設定

在開始之前可先參照「Duckietown – Duckiebot DB21M 小鴨車專案 Jetson-Nano 版平台組裝與操作環境設定介紹」文章中「六、測試小鴨車」的步驟啟動小鴨車;在搭配「Duckietown 專案 – Duckiebot DB21M 基礎操作(一)」的內容,進行操作環境的設定。

2. 程式碼來源

我們可以直接使用 Duckietowm mooc-exercises 中的程式碼來進行練習。請在操作主機上,利用 git 下載程式碼,指令如下所示。

3. 建立 Jupyter lab 使用空間

在 duckietown-shell 的指令中,有著建立 Jupyter lab 使用空間的指令。請在 mooc-exercises/modcon 的目錄中,輸入指令:

$ dts exercises build

四、使用程式碼設計 PID 控制器

1. 執行 mooc-exercise/modcon 專案

請在 mooc-exercises/modcon 的目錄中,輸入指令:

$ dts exercises lab

指令執行成功後,Jupyter lab 便會依照預設的瀏覽器視窗開始執行應用程式。在 mooc-exercises 專案中,Jupyter Lab 的密碼皆為「quackquack」。密碼輸入正確後,便可以開啟 Jupyter Lab ,瀏覽與執行 mooc-exercises/modcon 目錄中的程式碼。我們想要練習的 PID 程式碼便在 05-PID: Heading control 程式碼當中。

根據程式碼當中的內容,一步一步的調整程式,便可以練習使用程式碼,設計出一個 PID 控制器喔!

當完成範例內容,並依照指示向 Duckietown 團隊提交程式碼成功後,便可以到「AI Driving Olympics」網站查看自己的執行結果,如下圖所示。

與大家分享本次練習通過測驗的結果如下:

五、延伸閱讀

若是對控制系統想要有更深入的了解,可以查閱下列兩個網站:

本次的 PID 控制器簡介到這邊結束囉!下一篇文章我們將會持續介紹小鴨車更多的操作功能!請各位多多關注與分享我們的文章喔!