Sunday, June 27, 2010

[AVR] Line Follower - An application of PID controller

3pi Line Follower
Line Follower是許多基本款的robot都會有的功能之一, 當然3pi也不例外Line Follower, 指的是robot可以延著我們所設定規劃好的路線去行進, 如左圖, 3pi將會在白底背景下, 延著黑線去行進。 它靠著line sensors去讀取黑線與白底間的比例, 來判斷左轉角度、右轉角度或是直接前進, 當然,很多的方法可以用來判斷左右轉的角度, 本篇文章的重點主要要比較「PID control-based Algorithm」以及Heuristic-based Algorithm兩種方法在line follower實驗下的差別




Heuristic-based Algorithm
  • 直接看Line Follower在程式核心部份所使用的heuristic演算法

// This is the "main loop" - it will run forever.
 while(1)
 {
  // Get the position of the line.  Note that we *must* provide
  // the "sensors" argument to read_line() here, even though we
  // are not interested in the individual sensor readings.
  unsigned int position = read_line(sensors,IR_EMITTERS_ON);

  if(position < 1000)
  {
   // We are far to the right of the line: turn left.

   // Set the right motor to 100 and the left motor to zero,
   // to do a sharp turn to the left.  Note that the maximum
   // value of either motor speed is 255, so we are driving
   // it at just about 40% of the max.
   set_motors(0,100);

   // Just for fun, indicate the direction we are turning on
   // the LEDs.
   left_led(1);
   right_led(0);
  }
  else if(position < 3000)
  {
   // We are somewhat close to being centered on the line:
   // drive straight.
   set_motors(100,100);
   left_led(1);
   right_led(1);
  }
  else
  {
   // We are far to the left of the line: turn right.
   set_motors(100,0);
   left_led(0);
   right_led(1);
  }
 }


  • 我們發現, heuristic演算法靠著sensor所回傳的黑白比例, 來做為左右轉或直走的依據; 並且, 轉彎時始終保持單一速度


PID control-based Algorithm
PID分別為proportional–integral–derivative的縮寫, 它被廣泛應用在溫度、流量或是電機傳動等等的控制上, 其理論基礎這篇文章沒辦法細說, 但概念上我們可以透過下面的說明來瞭解 首先Line Follower這個例子來講, 底下我們分別說明proportionalintegralderivative:
  • Proportional:比例, 經由sensor所傳回量化後的值, 我們可以算出3pi位於白底或黑線上的比例為何, 這就是P
  • Integral: 積分, I值紀錄了3pi的活動軌跡, 也就是在一段運行時間中, 其P」值的加總
  • Derivative: 微分, 「D」值紀錄了前後P」值的
當我們分別得到了PI、D, 且分別加上一些weighting (magic number)[註一], 最後所得到的值, 代表的是3pi的左右兩個motor在setting值上的, 而物理意義代表的是3pi轉彎的角度大小


[註一]: 目前weighting值是turing得到的(所以稱為magic number), 但是, 有許多的研究針對如何turing」提出很多新的方法, 底下截圖來自wiki [1]上針對不同方法的優缺點所做的整理, 有興趣的話倒是可以試試這些方法



  • PID Algorithm的Source Code
// This is the "main loop" - it will run forever.
 while(1)
 {
  // Get the position of the line.  Note that we *must* provide
  // the "sensors" argument to read_line() here, even though we
  // are not interested in the individual sensor readings.
  unsigned int position = read_line(sensors,IR_EMITTERS_ON);

  // The "proportional" term should be 0 when we are on the line.
  int proportional = ((int)position) - 2000;

  // Compute the derivative (change) and integral (sum) of the
  // position.
  int derivative = proportional - last_proportional;
  integral += proportional;

  // Remember the last position.
  last_proportional = proportional;

  // Compute the difference between the two motor power settings,
  // m1 - m2.  If this is a positive number the robot will turn
  // to the right.  If it is a negative number, the robot will
  // turn to the left, and the magnitude of the number determines
  // the sharpness of the turn.
  int power_difference = proportional/20 + integral/10000 + derivative*3/2;

  // Compute the actual motor settings.  We never set either motor
  // to a negative value.
  const int max = 60;
  if(power_difference > max)
   power_difference = max;
  if(power_difference < -max)
   power_difference = -max;

  if(power_difference < 0)
   set_motors(max+power_difference, max);
  else
   set_motors(max, max-power_difference);
 }
  • PID short summary


    PID control uses continuous functions to compute the motor speeds, so that the jerkiness of the previous example can be replaced by a smooth response. [2]
    • 上面這句話是節錄自3pi的使用文件中, 這句話完全說明了整個PID control的精神, 以及使用後所帶來的好處
    • 如果翻成中文, 再加上自己的一些解釋之後, 可以這麼說的: 在Heuristic Algorithm下運作的3pi流暢度低於PID control Algorithm, 因為PID control Algorithm使用了連續函式, 物理意義上可以說它考慮了前後軌跡, 來做為下一個行進路線的參考, 相較於Heuristic Algorithm忽略前面一個軌跡, 3pi在使用PID control Algorithm的行進當然會比較順!


Experiments
  • 實驗目標及方向很明確, 我們想要證明: 3pi在使用PID control-based Algorithm時會比使Heuristic Algorithm走得順, 沒錯, 就是要證明一個字 順!
  • 底下我們直接展示兩種不同演算法在3pi上的成果, 相信大家都看得出來哪一個比較smooth
  • Heuristic Algorithm
  •  
     
  • PID control-based Algorithm
     




Conclusion
Line Follower, 常被拿來當成機器人競賽的項目, 而賽車比賽中的勝負常常在轉彎的時候來決定, 從本篇文章實驗的部份就可發現不同的方法影響了轉彎時不同的流暢度, 它靠的是PID control-based AlgorithmHeuristic-based Algorithm多考慮了歷史的軌跡。然而, PID control-based Algorithm畢竟採用的是magic number, 如何讓這些參數變得更有意義將會是未來研究上的議題


「Reference
  1. http://en.wikipedia.org/wiki/PID_controller
  2. http://www.pololu.com/docs/0J21/7

Monday, June 21, 2010

How to Install OpenCV on Linux (Ubuntu)

前言
對許多人來講, 在Windows下安裝OpenCV會比在Linux下安裝相對來得輕鬆Windows下, 沒錯, 您幾乎只需要重複「下一步」的動作就可以安裝大部分的程式, 但其實在Linux下亦不難, 或許只是您不熟悉如何去下指令? 沒關係, 這篇文章簡單整理了在Ubuntu底下安裝OpenCV的兩種方法其一, 是當您想更改OpenCV的source code並自己重新編譯的方法;  另外, 則是一般的apt-get安裝方式。底下我將一步步來介紹整個流程

Before the installation」
  • 為了可以重新編譯OpenCV, 系統中必須要有C++ compiler, 如果沒有, 我們可以透過以下指令來安裝

    $ sudo apt-get install g++
    
  • 為了圖片的播放, 我們需要GTK+, 它是一個跨平台的圖形介面函式庫, GNOME即是利用GTK+來開發的。首先, 我們可以藉由以下命令來查看系統安裝了哪個版本的GTK+

    $ dpkg -l | grep libgtk
    or, 可以直接安裝

    $ sudo apt-get install libgtk2.0-dev


「Install OpenCV on Ubuntu (method 1)」
  1. http://sourceforge.net/projects/opencvlibrary/files/下載原始碼(Linux版
  2. 解壓該原始碼檔案, 且切換至該目錄假設下載的是opencv-1.0.0.tar.gz, 則我們可以使用下列命令

    tar zxvf opencv-1.0.0.tar.gz
    cd opencv-1.0.0
  3. 檢查系統所需環境是否已經安裝完畢
  4. ./configure
    當出現「Now run make...」則表示可以開始編譯了, 否則, 必須安裝所需安裝的套件
  5. 編譯OpenCV
  6. make
  7. 使用root權限來安裝OpenCV
  8. sudo make install
  9. 增加路徑/usr/local/lib」到/etc/ld.so.conf」中, 這一步主要是在設定動態函式庫的路徑,  其中/etc/ld.so.conf就是目前系統中主要用來放置函式庫的目錄
  10. 設定完路徑後, 必須重建動態函式庫目錄
  11. ldconfig



「Install OpenCV on Ubuntu (method 2)
Ubuntu底下的Synaptic Package Manager方便了我們對於各種軟體的安裝, 並且隨時可以線上更新最新版本。對於利用Synaptic來安裝OpenCV, 我們只需收尋OpenCV且套用所收尋到的套件, 就可以直接安裝了, 安裝畫面如下


或者, 您也可以打開terminal輸入想安裝的套件, 如下面指令
$ sudo apt-get install libcv4 libcvaux4 libhighgui4
$ sudo apt-get install libcv-dev libcvaux-dev libhighgui-dev
當然, 指令會因函式庫的版本名稱不同而有所不一樣最後, 設定環境變數
export LD_LIBRARY_PATH=/home/opencv/lib
export PKG_CONFIG_PATH=/home/opencv/lib/pkgconfig

「執行OpenCV範例程式
底下, 我測試了OpenCV給的範例程式camshiftdemo.c,切換到範例所在目錄且利用以下命令編譯及執行
$ g++ -I/usr/include/opencv -lcxcore -lhighgui -lm camshiftdemo.c
$ ./a.out
執行畫面如下