1. 程式人生 > 其它 >服務通訊

服務通訊

2.2 服務通訊

服務通訊也是ROS中一種極其常用的通訊模式,服務通訊是基於請求響應模式的,是一種應答機制。也即: 一個節點A向另一個節點B傳送請求,B接收處理請求併產生響應結果返回給A。比如如下場景:

機器人巡邏過程中,控制系統分析感測器資料發現可疑物體或人... 此時需要拍攝照片並留存。

在上述場景中,就使用到了服務通訊。

  • 一個節點需要向相機節點發送拍照請求,相機節點處理請求,並返回處理結果

與上述應用類似的,服務通訊更適用於對時時性有要求、具有一定邏輯處理的應用場景。


概念

以請求響應的方式實現不同節點之間資料互動的通訊模式。

作用

用於偶然的、對時時性有要求、有一定邏輯處理需求的資料傳輸場景。

案例

實現兩個數字的求和,客戶端節點,執行會向伺服器傳送兩個數字,伺服器端節點接收兩個數字求和並將結果響應回客戶端。

另請參考:


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 實現流程類似:

  1. 按照固定格式建立srv檔案

  2. 編輯配置檔案

  3. 編譯生成中間檔案

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 時,是從這些中間檔案呼叫的