ROS2筆記4--服務通訊

ROS2中話題通訊可以實現多個ROS節點之間數據的單向傳輸,不過話題通訊是一種異步通信機制,發佈者無法準確知道訂閱者是否收到消息。而服務通信是一種基於請求響應的通信模型,在通信雙方中客戶端發送請求數據到服務端,服務端響應結果給客戶端。
0
 
從服務實現機制看這種形式是CS模型,客戶端需要數據時針對具體的服務發送請求信息,服務端收到請求後進行處理並返回應答信息。
以加法計算器爲例

1、新建功能包

ros2 pkg create pkg_service --build-type ament_python --dependencies rclpy --node-name server_demo

2、服務端實現

編寫服務端server_demo.py文件實現服務端功能
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class Service_Server(Node):
    def __init__(self, name):
        super().__init__(name)
# 創建一個服務端,使用的是create_service函數
# 參數分別爲:服務數據類型、服務名稱、服務回調函數 self.src = self.create_service(AddTwoInts, "/add_two_ints", self.AddTwoInts_callback)
# 定義服務回調函數 def AddTwoInts_callback(self, request, response): response.sum = request.a + request.b print("result.sum = ", response.sum) return response def main(): rclpy.init() server_demo = Service_Server("server_node") rclpy.spin(server_demo) server_demo.destroy_node() rclpy.shutdown()

  

服務回調函數AddTwoInts_callback這裏需要傳入參數除了self,還有requesst和response,request是服務需要的參數,response是服務返回的結果。request.a和request.b是request部分的內容,response.sum是response部分的內容。
AddTwoInts是類型,可以通過如下命令查看類型
 
ros2 interface show example_interfaces/srv/AddTwoInts

其中“--”上面部分是request,下面部分是response。request包含兩個變量a,b;response包含變量sum
 

3、客戶端實現

在server_demo.py統計目錄下創建文件client_demo.py,編寫客戶端功能代碼:
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class Service_Client(Node):
    def __init__(self, name):
        super().__init__(name)
# 創建客戶端,使用create_client函數
# 傳入參數分別是:服務數據類型、服務名稱 self.client = self.create_client(AddTwoInts, "/add_two_ints")
# 循環等待服務端啓動 while not self.client.wait_for_service(timeout_sec=1.0): print("service not available, waiting...")
# 創建服務請求數據對象 self.request = AddTwoInts.Request() def send_request(self): self.request.a = 10 self.request.b = 20
# 發送服務請求 self.future = self.client.call_async(self.request) def main(): rclpy.init() client_demo = Service_Client("client_node") client_demo.send_request() # 發送服務請求 while rclpy.ok(): rclpy.spin_once(client_demo)
# 判斷數據是否處理完成 if client_demo.future.done(): try:
# 獲取服務返回結果 response = client_demo.future.result() print("request.a = ", client_demo.request.a) print("request.b = ", client_demo.request.b) print("response.sum = ", response.sum) except Exception as e: print("Service call failed") break client_demo.destroy_node() rclpy.shutdown()

4、編輯配置文件、編譯工作空間

配置文件setup.py
0
編譯工作空間
cd ~/ros_ws colcon build --package-selects pkg_service source install/setup.bash 

5、運行程序

分終端分別啓動服務端節點和客戶端節點
ros2 run pkg_service server_demo
ros2 run pkg_service client_demo

服務端打印:

0
客戶端打印:
0
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章