3. ROS2服务通信基础

ROS2服务通信基础:客户端与服务器 学习卡片

任务目标

本案例实现一个ROS2服务通信的最小闭环:创建加法服务服务器节点,接收两个整数请求并返回其和;创建客户端节点发送请求并打印响应。通过该案例掌握ROS2服务通信的接口定义、服务器/客户端实现及编译运行流程。

环境与依赖

  • 已安装ROS2(Humble或Foxy均可,以下以Humble为例)
  • 已创建ROS2工作空间 ~/ros2_ws/src
  • 需要example_interfaces包(ROS2默认自带),其中包含AddTwoInts服务接口

实现代码

在~/ros2_ws/src下创建功能包:

cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces

服务器节点 py_srvcli/py_srvcli/service_server.py:

import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class AddTwoIntsServer(Node):

    def __init__(self):
        super().__init__('add_two_ints_server')
        self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)

    def add_two_ints_callback(self, request, response):
        response.sum = request.a + request.b
        self.get_logger().info(f'收到请求: {request.a} + {request.b} = {response.sum}')
        return response

def main(args=None):
    rclpy.init(args=args)
    server = AddTwoIntsServer()
    rclpy.spin(server)
    server.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

客户端节点 py_srvcli/py_srvcli/service_client.py:

import sys
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class AddTwoIntsClient(Node):

    def __init__(self):
        super().__init__('add_two_ints_client')
        self.cli = self.create_client(AddTwoInts, 'add_two_ints')
        while not self.cli.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('服务未就绪,等待中...')
        self.req = AddTwoInts.Request()

    def send_request(self, a, b):
        self.req.a = a
        self.req.b = b
        self.future = self.cli.call_async(self.req)
        rclpy.spin_until_future_complete(self, self.future)
        return self.future.result()

def main(args=None):
    rclpy.init(args=args)
    client = AddTwoIntsClient()
    if len(sys.argv) != 3:
        client.get_logger().error('用法: python3 service_client.py 整数A 整数B')
        return
    a = int(sys.argv[1])
    b = int(sys.argv[2])
    response = client.send_request(a, b)
    client.get_logger().info(f'服务返回: {a} + {b} = {response.sum}')
    client.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

编辑 setup.py,在entry_points中添加:

entry_points={
    'console_scripts': [
        'service_server = py_srvcli.service_server:main',
        'service_client = py_srvcli.service_client:main',
    ],
},

编译与运行

cd ~/ros2_ws
colcon build --packages-select py_srvcli
source install/setup.bash

终端1——启动服务器:

ros2 run py_srvcli service_server

终端2——启动客户端(发送3和5):

ros2 run py_srvcli service_client 3 5

验证方法

  • 服务器终端应输出日志:收到请求: 3 + 5 = 8
  • 客户端终端应输出:服务返回: 3 + 5 = 8
  • 另开终端执行 ros2 service list 可看到 /add_two_ints 服务;执行 ros2 service type /add_two_ints 输出 example_interfaces/srv/AddTwoInts

预期输出(由代码逻辑直接推出):客户端传入3和5时,服务器返回8,两端日志均显示3 + 5 = 8。若输出一致,则服务通信闭环验证通过。

常见问题

  • 客户端提示“服务未就绪”:确认服务器已启动且在同一ROS2域中运行。
  • 找不到example_interfaces:执行 sudo apt install ros-humble-example-interfaces 安装。
  • colcon build失败:确认在~/ros2_ws根目录执行,且已source ROS2环境。