服務通訊
2.2 服務通訊
服務通訊也是ROS中一種極其常用的通訊模式,服務通訊是基於請求響應模式的,是一種應答機制。也即: 一個節點A向另一個節點B傳送請求,B接收處理請求併產生響應結果返回給A。比如如下場景:
機器人巡邏過程中,控制系統分析感測器資料發現可疑物體或人... 此時需要拍攝照片並留存。
在上述場景中,就使用到了服務通訊。
- 一個節點需要向相機節點發送拍照請求,相機節點處理請求,並返回處理結果
與上述應用類似的,服務通訊更適用於對時時性有要求、具有一定邏輯處理的應用場景。
概念
以請求響應的方式實現不同節點之間資料互動的通訊模式。
作用
用於偶然的、對時時性有要求、有一定邏輯處理需求的資料傳輸場景。
案例
實現兩個數字的求和,客戶端節點,執行會向伺服器傳送兩個數字,伺服器端節點接收兩個數字求和並將結果響應回客戶端。
另請參考:
-
http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28c%2B%2B%29
-
http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28python%29
2.2.1 服務通訊理論模型
服務通訊較之於話題通訊更簡單些,理論模型如下圖所示,該模型中涉及到三個角色:
- ROS master(管理者)
- Server(服務端)
- Client(客戶端)
ROS Master 負責保管 Server 和 Client 註冊的資訊,並匹配話題相同的 Server 與 Client ,幫助 Server 與 Client 建立連線,連線建立後,Client 傳送請求資訊,Server 返回響應資訊。
整個流程由以下步驟實現:
0.Server註冊
Server 啟動後,會通過RPC在 ROS Master 中註冊自身資訊,其中包含提供的服務的名稱。ROS Master 會將節點的註冊資訊加入到登錄檔中。
1.Client註冊
Client 啟動後,也會通過RPC在 ROS Master 中註冊自身資訊,包含需要請求的服務的名稱。ROS Master 會將節點的註冊資訊加入到登錄檔中。
2.ROS Master實現資訊匹配
ROS Master 會根據登錄檔中的資訊匹配Server和 Client,並通過 RPC 向 Client 傳送 Server 的TCP地址資訊。
3.Client傳送請求
Client 根據步驟2 響應的資訊,使用 TCP 與 Server 建立網路連線,併發送請求資料。
4.Server傳送響應
Server 接收、解析請求的資料,併產生響應結果返回給 Client。
注意:
1.客戶端請求被處理時,需要保證伺服器已經啟動;
2.服務端和客戶端都可以存在多個。
圖解
2.2.2 服務通訊自定義srv
需求:
服務通訊中,客戶端提交兩個整數至服務端,服務端求和並響應結果到客戶端,請建立伺服器與客戶端通訊的資料載體。
流程:
srv 檔案內的可用資料型別與 msg 檔案一致,且定義 srv 實現流程與自定義 msg 實現流程類似:
-
按照固定格式建立srv檔案
-
編輯配置檔案
-
編譯生成中間檔案
1.定義srv檔案
服務通訊中,資料分成兩部分,請求與響應,在 srv 檔案中請求和響應使用---
分割,具體實現如下:
功能包下新建 srv 目錄,新增 xxx.srv 檔案,內容:
# 客戶端請求時傳送的兩個數字
int32 num1
int32 num2
---
# 伺服器響應傳送的資料
int32 sum
2.編輯配置檔案
package.xml中新增編譯依賴與執行依賴
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend> <!-- exce_depend 以前對應的是 run_depend 現在非法 -->
CMakeLists.txt編輯 srv 相關配置
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# 需要加入 message_generation,必須有 std_msgs
add_service_files(
FILES
AddInts.srv
)
generate_messages(
DEPENDENCIES
std_msgs
)
注意: 官網沒有在 catkin_package 中配置 message_runtime,經測試配置也可以
3.編譯
編譯後的中間檔案檢視:
C++ 需要呼叫的中間檔案(.../工作空間/devel/include/包名/xxx.h)
Python 需要呼叫的中間檔案(.../工作空間/devel/lib/python3/dist-packages/包名/srv)
後續呼叫相關 srv 時,是從這些中間檔案呼叫的