在ROS教學介紹中,有提供一個烏龜練習題來介紹ROS基本的通訊方式。這次我們要以這個練習題為基礎,練習建立自己的節點並完成接受、發布訊息的功能。。
事前準備
在教學的文章[1]中有提到,在安裝好ROS後,可以直接啟動預設安裝好的烏龜節點來測試。依照以下方式啟動烏龜練習題:
roscore
首先啟動一個終端機並輸入roscore。這個動作我建議可以想成是啟動一個管理所有接下來ROS資訊用的主控節點。
rosrun turtlesim turtlesim_node
開啟新終端機畫面輸入上面的指令後,會出現一個烏龜的畫面。
rosrun turtlesim turtle_teleop_key
開啟新終端機畫面,輸入指令後,即可啟動控制烏龜的遙控器。開啟後,按下鍵盤中的方向鍵就可以控制烏龜前進、後退、轉彎。
新嘗試
開啟控制器後,可以控制烏龜到處移動。但你有注意到嗎? 當我們把烏龜移動到畫面的邊緣時,終端機會跳出烏龜撞到牆壁的提示 (Oh no ! I hit the wall!)。接下來我們要用這個訊息來當作練習的契機。
題目
我們要建立一個節點,會接收由turtlesim_node發出的撞牆訊息,並且在接收到訊息後,要轉發一個格式為Float64的新訊息出去。
實作
建立管理節點與建立發布、接收節點的方式可以參考以下文章。
建立節點的資料夾
這裡我使用 catkin_create_pkg 的指令,建立了一個叫做test_program的資料夾。
檢查發布訊息topic
因為題目是要先接收到撞牆資訊後,再發出一個訊號出去。因此我們首先會需要先調查,負責發布 Oh no ! I hit the wall! 這筆資訊。
有一種簡單檢測的方式:
直接透過 rostopic echo /topic名稱 的方式來監聽不同topic的資料,看看有哪一個topic有發布此訊息。
根據不斷嘗試、不斷犧牲烏龜去撞牆壁後,我們可以得知透過 /rosout_agg 就可以得到Oh no ! I hit the wall! 的訊息。
檢查topic 格式
使用 rostopic type /rosout_agg 查訊後可以得知其格式為 rosgraph_msgs/Log。
檢查格式中的訊號資料
透過 rosmsg info rosgraph_msgs/Log 後可以得到
加上剛才在檢查topic時顯示的結果,msg這個欄位裡的資料就會是我們要讀取的訊息,另外還可以確認msg這個欄位中的資訊,是字串的格式。
建立接收的部分
程式上方需要先使用 from rosgraph_msgs.msg import Log 來建立讀取/rosout_agg的格式。根據前一步我們得知的結論,我們需要讀取Log資訊中的msg欄位的資料,因此我們只要使用data.msg即可讀取該欄位的訊息。讀取完訊息後,只需要加入比對是否為Oh no ! I hit the wall!,我們就可以接著進行後發布的動作。
下方程式中,我使用了 split() 的python功能,先將讀取到的msg資料切割成數個字串,透過比對第一個切割後的字串欄位,只要該字串內容為 Oh 即表示該次訊息為Oh no ! I hit the wall!。
建立發送部分
發送時因為題目指定要發布 Float64 的格式,因此需要在程式最前端加入 from std_msgs.msg import Float64。在程式中,我習慣將要發布的topic資料先定義一個變數在定義節點名稱之前,之後需要時只需指定此變數即可發布訊息。
根據題目要求,節點會需要在接收到Oh no ! I hit the wall!訊息後,發出一個訊息,因此發布的程式,直接寫在接收的部分中就可以。下面程式中,最後一行的print是用來確認程式有發布資訊出去用。
建立的程式
測試
開啟新的終端機啟動剛才建立的節點,接著開啟一個新的終端機,使用 rostopic echo /topic名稱 的方式監控建立的節點有無順利發布訊號出來,最後只要控制烏龜去牆邊,既可得到結果。
結論
順利完成測試,並且確認有順利發出訊息後,就表示我們建立的節點有成功的執行。接著可以挑戰看看,自己建立一個發布訊息的格式來取代目前題目指定的Float64格式,如果也順利完成了,恭喜,最基本的練習已經完成,可以開始挑戰複雜一點、大一點的題目了!