ROS2笔记4--服务通讯

ROS2中话题通讯可以实现多个ROS节点之间数据的单向传输,不过话题通讯是一种异步通信机制,发布者无法准确知道订阅者是否收到消息。而服务通信是一种基于请求响应的通信模型,在通信双方中客户端发送请求数据到服务端,服务端响应结果给客户端。
0
 
从服务实现机制看这种形式是CS模型,客户端需要数据时针对具体的服务发送请求信息,服务端收到请求后进行处理并返回应答信息。
以加法计算器为例

1、新建功能包

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

2、服务端实现

编写服务端server_demo.py文件实现服务端功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
 
class Service_Server(Node):
    def __init__(self, name):
        super().__init__(name)<br>        # 创建一个服务端,使用的是create_service函数<br>        # 参数分别为:服务数据类型、服务名称、服务回调函数
        self.src = self.create_service(AddTwoInts, "/add_two_ints", self.AddTwoInts_callback)
  <br>    # 定义服务回调函数
    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是类型,可以通过如下命令查看类型
 
1
ros2 interface show example_interfaces/srv/AddTwoInts

其中“--”上面部分是request,下面部分是response。request包含两个变量a,b;response包含变量sum
 

3、客户端实现

在server_demo.py统计目录下创建文件client_demo.py,编写客户端功能代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
 
class Service_Client(Node):
    def __init__(self, name):
        super().__init__(name)<br>        # 创建客户端,使用create_client函数<br>        # 传入参数分别是:服务数据类型、服务名称
        self.client = self.create_client(AddTwoInts, "/add_two_ints")<br>        # 循环等待服务端启动
        while not self.client.wait_for_service(timeout_sec=1.0):
            print("service not available, waiting...")<br>        # 创建服务请求数据对象
        self.request = AddTwoInts.Request()
 
    def send_request(self):
        self.request.a = 10
        self.request.b = 20<br>        # 发送服务请求
        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)<br>        # 判断数据是否处理完成
        if client_demo.future.done():
            try:<br>                # 获取服务返回结果
                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
编译工作空间
1
cd ~/ros_ws colcon build --package-selects pkg_service source install/setup.bash 

5、运行程序

分终端分别启动服务端节点和客户端节点
1
2
ros2 run pkg_service server_demo
ros2 run pkg_service client_demo

服务端打印:

0
客户端打印:
0
 
 
 
posted @   Lucky帅小武  阅读(260)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示