2.使用STDR進行ROS小車超聲波避障策略模擬實驗
轉自連結:http://www.corvin.cn/573.html
0x00 什麼是模擬實驗
在沒有真實物理實體實驗裝置的情況下,通過在計算機上用軟體模擬真實裝置執行的效果,這就叫做軟體模擬實驗,用軟體模擬是一條可行性高、測試成本低、實驗效率高的一條路。就拿ROS小車的避障策略設計來說,如果我們設計了一個避障策略想要實驗一下效果如何的話,一般都需要先做一個真實的ROS小車,這樣就需要花費不少的錢。當在真實的小車上實驗時還會遇到小車電池電量不夠、執行時間短、測試環境不夠完善等各種問題,有時為了測試一次避障策略程式就需要準備好長時間使小車處於正常工作狀態才能開始實驗,費時費力。
如果我們使用軟體模擬出真實小車的各種引數、各種運動狀態的話,我們將自己的程式在模擬中跑起來就方便多了,STDR就是這麼一款可以模擬ROS小車在二維平面移動的軟體,模擬軟體中的小車上感測器釋出的資料跟真實的小車釋出的話題資料基本上是一樣的,那麼我們的避障策略程式就可以很好的在模擬軟體上進行實驗修改完善,當在模擬環境中沒有問題的話,最後再在真實的小車上執行,這樣就會有事半功倍的效果。
0x01 模擬小車介紹
當使用如下命令來啟動STDR模擬軟體時會自動的載入一個ROS模擬差速驅動小車,我們可以把它當作跟turtlebot一樣的小車即可,只有線速度x和角速度z:
roslaunch stdr_launchers server_with_map_and_gui_plus_robot.launch
使用如下命令即可在rviz中開啟該模擬軟體,稍微配置一下即可得到如下圖所示的小車超聲波感測器探測範圍:
roslaunch stdr_launchers rviz.launch
0x02 設計超聲波避障策略
由於該ROS機器人上面裝有5個超聲波感測器,為了在本次實驗中減輕設計策略的複雜度我們只使用機器人前面的三個感測器,分別是正前方、左側、右側感測器,下面的流程圖是設計的使用三個超聲波感測器來避障的程式設計流程圖(該避障策略僅供參考,只是為了實驗需要而設計的,在真實的環境中我們可能需要設計更為複雜完善的避障策略),如果下圖看不清楚的話可以檢視以下附件:
0x03 熟悉超聲波話題及其訊息格式
首先來認識一下超聲波話題和訊息格式,在首先啟動了模擬器後接下來通過如下圖所示命令來操作:
對於sensor_msgs/Range.msg的具體詳細描述可以從roswiki的官網獲得,網址如下:
http://mirror.umd.edu/roswiki/doc/diamondback/api/sensor_msgs/html/msg/Range.html
輸出當前超聲波話題內容,可以看到與定義的格式內容是匹配的:
0x04 獲取一個超聲波的測距輸出
我們先以正前方的超聲波sonar_0來演示如何編寫程式碼獲取其測距輸出值,我們首先建立自己的超聲波避障軟體包ultrasonic_obstacle_avoidance,在工作空間的src目錄下使用如下命令來建立:
catkin_create_pkg ultrasonic_obstacle_avoidance roscpp sensor_msgs
接下來進入剛才建立的軟體包下的src目錄下建立main.cpp,輸入如下程式碼,該程式碼可以讀取robot0上的sonar_0的測距值並列印輸出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
然後修改CMakeLists.txt配置檔案,按照如下圖所示修改:
最後就可以來編譯該程式碼了,在catkin_ws目錄下執行catkin_make編譯,然後source devel/setup.bash配置好環境變數,如下操作:
[email protected]:~/catkin_ws$ catkin_make
[email protected]:~/catkin_ws$ source devel/setup.bash
編譯完成後就可以來執行檢視效果了,首先啟動STDR模擬軟體,然後在啟動列印超聲波資料的節點,分別在兩個終端下執行如下兩條命令:
[email protected]:~/catkin_ws$ roslaunch stdr_launchers server_with_map_and_gui_plus_robot.launch
[email protected]:~/catkin_ws$ rosrun ultrasonic_obstacle_avoidance ultrasonic_obstacle_avoidance_node
當啟動節點後可以發現已經有列印資料,當我們使用鍵盤來遙控小車四處走動時可以發現該資料也跟著變動,啟動鍵盤遙控節點命令如下:
[email protected]:~$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py
0x05 實現完整避障策略進行模擬
現在已經可以獲取單個超聲波感測器的輸出了,接下來我們就按照前面的程式設計流程圖來獲取其他感測器輸出實現完整的避障程式碼,完整程式碼如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
|
在以上原始碼中需要注意以下幾點,方便大家更容易理解程式碼:
(1)使用unsigned char的變數的低3bit來記錄三個超聲波感測器測距值是否到達警戒值,高5bit不使用,如果我們有更多的超聲波的話就可以用上了.對於低3bit來說,為了方便大家更容易的與三個位置的超聲波感測器相對應,因此就規定3bit中最高位存放左邊超聲波感測器的報警標誌,中間bit放置正前方超聲波感測器報警標誌,最低bit放置右邊超聲波感測器報警標誌,如下所示:
(高5bit不儲存任何標誌) (左邊) (正前方) (右邊)
X X X X X 0 0 0
(2)使用一個double陣列range_array來儲存三個超聲波感測器每次回調回來的測距值,同樣的為了方便與三個超聲波位置匹配,在range_array[0]儲存的是左邊sonar的測距值,range_array[1]儲存的是正前方sonar的測距值,range_array[2]儲存的是右邊sonar的測距值.
下面準備編譯該程式碼,由於我們新增了控制小車移動的訊息geometry_msgs/Twist.msg格式,因此需要相應的修改CMakeLists.txt和package.xml檔案,首先是修改CMakeLists.txt檔案,按照如下圖修改即可:
修改package.xml檔案,按照如下圖所示修改:
接下來就可以來重新編譯程式碼了,編譯完成後重新啟動STDR模擬器,然後在啟動我們的避障節點程式來檢視效果:
通過上面的模擬效果來看,我們的機器人在三個超聲波測距模組下基本上可以進行自由的避障行走,但是模擬中難免也會遇到其他問題,像下圖這種振盪判斷,會導致機器人一直在一個地方左右搖擺:
其實在上面出現的這個問題是由於我們的程式碼設計有問題,我們通過模擬就可以模擬出該效果,省了我們在真實的小車上來測試效果了,那下面來說出現該現象的原因:
(1)當小車正前方的超聲波測距顯示距離太近時,會來判斷左右兩邊的超聲波測距值哪個更大一點,哪邊大一點就說明那邊肯定更空一點.
(2)例如我們判斷左側超聲波資料大點,那就往左邊轉動,但是剛轉過去一點點,在ROS的主迴圈中又開始下一輪判斷超聲波資料了.
(3)由於剛才是往左邊轉了一點,這樣就導致右邊的資料肯定就比左邊的又大了,那在本輪的避障中又控制小車往右邊轉動了.
(4)這樣就會出現上面動圖出現的現象了,小車在不停的左右擺動.
對於出現這種現象既然我們已經知道了產生的原因,那麼就需要來找到解決辦法來消滅掉這個bug,大家可以在上面提供的原始碼基礎上來修改完善,算是作為大家的課後習題了,而且第一位小夥伴解決了該問題並在公眾號中給我發訊息留言的話,就會有獎勵啊,大家來開動腦子想想更好的避障策略來遍歷整個房間且不會撞到牆上吧,有了這個STDR就可以很容易的驗證大家的避障策略是否可行了.
0x06 參考資料
[1].STDR在ROS WiKi上主頁地址[OL]. http://wiki.ros.org/stdr_simulator/Tutorials
[2].sensor_msgs/Range.msg在ROS WiKi網站上的定義[OL]. http://mirror.umd.edu/roswiki/doc/diamondback/api/sensor_msgs/html/msg/Range.html
[3].evarobot_sonar讀取超聲波資料的例項教程[OL]. http://wiki.ros.org/evarobot_sonar/Tutorials/indigo/Writing%20a%20Simple%20Subscriber%20for%20Sonar%20Sensor