ROS開發 之 資料通訊(服務)
概述
ROS中通訊方式有三種,分別為話題(msg)、服務(srv)和活動(action),其中話題屬於基本的釋出/訂閱通訊方式,適用於單個節點發布訊息,一個或多個節點接受訊息的情況;服務屬於實時獲取結果的情況,應用於請求/響應式的應用環境,類似於一個函式呼叫關係,適用於基本功能的呼叫或者狀態的檢視;活動屬於無阻塞的執行方式,也應用於請求/響應式的環境,具有比服務更靈活的控制形式,並且在執 行的過程中可以對狀態的反饋,適用於執行需要較長時間的情況。
服務說明
服務是另一種用於節點之間通訊的方式,服務常用於請求/響應式的互動場景,只需要偶爾去執行並且會在較短時間裡可以完成的任務,即阻塞完成某個特定的功能。服務的實現方式跟話題相比較複雜,使用分為服務的定義和實現兩步,可以將服務的定義理解為面向物件中的介面的宣告,服務的實現理解為介面的實現。相當於首先進行介面的宣告,然後定義函式體進行介面實現。其介面定義的操作過程類似於在話題中新建一個數據型別,下面將介紹服務定義的操作步驟,例子中程式碼程式可以在這個地址下載:
類似訊息型別放置於msg目錄,服務常放置於srv子目錄中,且服務檔案以srv結尾。
- 建立目錄:mkdir srv
- 目錄中建立檔案:PersoninfoShow.srv Personinfo person --- string strOutput
- 為構建增加編譯庫:pakage.xml <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>
- 為構建增加庫說明:CMakeLists.txt find_package(#約在第10行 **** message_generation #新增 ) catkin_package(#約在第105行 **** CATKIN_DEPENDS message_runtime #新增 ) add_service_files(#約在第59行,此處不同於訊息 **** FILES PersoninfoShow.srv #新增 ) generate_messages(#約在第71行 #雖然用了自定義訊息型別,但在同個程式包中,不需要做引入說明 ) #去掉註釋以啟用
- 進入catkin根目錄:cd ~/catkin_ws
- 編譯生成:catkin_make
- 檢視服務:rossrv show PersoninfoShow
- 訊息包裡定義的服務:rossrv package vejoe_slam
服務實現
本實驗中服務的示例用於將自定義的訊息型別Personinfo的顯示格式化,在服務端輸入為Personinfo物件,輸出為將物件內容格式化為字串,在客戶端通過呼叫服務得到格式化的字串並將結果打印出來。
- 拷貝程式到src目錄:demo_service.py,demo_service_client.py
- 檔案執行授權:chmod +x demo_service.py demo_service_client.py
- 啟動主節點:roscore
- 啟動服務:rosrun vejoe_slam demo_service.py
- 呼叫服務:rosrun vejoe_slam demo_service_client.py 除了使用代理的方式在程式中呼叫,也可以直接在命令列呼叫,引數的順序為訊息型別中的順序需要一致,否則會錯配: rosservice call show_person_info [引數]
- 檢視啟動的服務列表:rosservice list
- 檢視服務詳情:rosservice info show_person_info
左上圖為啟用服務,右上圖為呼叫服務,左下圖為顯示服務資訊,右下圖為啟用主節點
如上圖所示,可以看到Personinfo中的資料定義依次為name、sex、age,因此在使用rosservice直接呼叫時程式也是按照這個順序進行解析的,上圖最後一條命令中由於將sex和age資訊寫反了,因此程式中直接將True認為是age,在python中bool型變數為int的子集,因此型別可以驗證通過,邏輯判斷中可以,不過值的顯示卻因為對應錯誤顯示錯誤。
歡迎感興趣的朋友一起加QQ群交流學習。