ros笔记02--从零体验ros2中的服务通信方式

ros笔记02--从零体验ros2中的服务通信方式

介绍

在ROS 2中,服务指的是远程过程调用,client调用server,server节点收到数据后计算出结果并返回给client.

服务通常期望能快速返回,因此不应当用于处理长时间的任务; 若有长时间的任务可以考虑使用 ros2 中的行为 act.

在ros2中,服务的请求和响应结构通常被定义到一个 .srv 的文件中。本文基于python案例,从零开始创建一个计算 a + b 的服务。

创建步骤

  1. 新建 dev_ws 并初始化依赖信息

    bash 复制代码
    $ mkdir -p dev_ws/src
    $ cd dev_ws
    $ rosdep install -i --from-path src --rosdistro jazzy -y
    输出: #All required rosdeps installed successfully
  2. 创建 interfaces, 新增 AddTwoInts.srv

    2.1 创建 pkg 并新增 srv/AddTwoInts.srv

    bash 复制代码
    $ cd dev_ws/src
    $ ros2 pkg create --build-type ament_cmake --license Apache-2.0 example_interfaces
    cd dev_ws/src/example_interfaces
    $ mkdir srv
    $ vim srv/AddTwoInts.srv
    int64 a
    int64 b
    ---
    int64 sum

    2.2 在CMakeLists中新增依赖

    bash 复制代码
    $ cd dev_ws/src/example_interfaces
    $ vim CMakeLists.txt
    # 新增如下内容
    find_package(rosidl_default_generators REQUIRED)
    rosidl_generate_interfaces(${PROJECT_NAME}
      "srv/AddTwoInts.srv"
     )

    2.3 在package.xml下新增如下内容

    yaml 复制代码
    <buildtool_depend>rosidl_default_generators</buildtool_depend>
    <exec_depend>rosidl_default_runtime</exec_depend>
    <member_of_group>rosidl_interface_packages</member_of_group>
  3. 创建service包

    在 src目录创建包

    bash 复制代码
    $ cd dev_ws/src
    $ ros2 pkg create --build-type ament_python --license Apache-2.0 py_srvcli --dependencies rclpy example_interfaces

    3.1 新增 service_member_function.py

    vim py_srvcli/py_srvcli/service_member_function.py

    py 复制代码
    from example_interfaces.srv import AddTwoInts
    
    import rclpy
    from rclpy.node import Node
    
    
    class MinimalService(Node):
    
        def __init__(self):
            super().__init__('minimal_service')
            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('Incoming request\na: %d b: %d' % (request.a, request.b))
    
            return response
    
    
    def main():
        rclpy.init()
    
        minimal_service = MinimalService()
    
        rclpy.spin(minimal_service)
    
        rclpy.shutdown()
    
    
    if __name__ == '__main__':
        main()

    3.2 新增 client_member_function.py

    vim py_srvcli/py_srvcli/client_member_function.py

    py 复制代码
    import sys
    
    from example_interfaces.srv import AddTwoInts
    import rclpy
    from rclpy.node import Node
    
    
    class MinimalClientAsync(Node):
    
        def __init__(self):
            super().__init__('minimal_client_async')
            self.cli = self.create_client(AddTwoInts, 'add_two_ints')
            while not self.cli.wait_for_service(timeout_sec=1.0):
                self.get_logger().info('service not available, waiting again...')
            self.req = AddTwoInts.Request()
    
        def send_request(self, a, b):
            self.req.a = a
            self.req.b = b
            return self.cli.call_async(self.req)
    
    
    def main():
        rclpy.init()
    
        minimal_client = MinimalClientAsync()
        future = minimal_client.send_request(int(sys.argv[1]), int(sys.argv[2]))
        rclpy.spin_until_future_complete(minimal_client, future)
        response = future.result()
        minimal_client.get_logger().info(
            'Result of add_two_ints: for %d + %d = %d' %
            (int(sys.argv[1]), int(sys.argv[2]), response.sum))
    
        minimal_client.destroy_node()
        rclpy.shutdown()
    
    
    if __name__ == '__main__':
        main()

    3.3 在 setup.py的console_scripts 新增如下内容

    py 复制代码
      'service = py_srvcli.service_member_function:main',
      'client = py_srvcli.client_member_function:main',
  4. 编译运行

    bash 复制代码
    $ cd dev_ws
    $ colcon build
    # 输出
    ...
    This may be promoted to an error in a future release of colcon-override-check.
    Starting >>> example_interfaces
    Finished <<< example_interfaces [4.11s]                     
    Starting >>> py_srvcli
    Finished <<< py_srvcli [1.01s]          
    
    Summary: 2 packages finished [5.21s]
    $ source install/setup.bash
    $ ros2 run py_srvcli service
    $ ros2 run py_srvcli client 2 3

    输出结果如下,service收到 2 和 3, client得到结果 5

注意事项

  1. 安装ros2的python版本最好和编译使用使用的python版本一致,否则会出现类似 Assertion `PyUnicode_IS_READY(name_attr)' failed. 的错误

    bash 复制代码
    笔者安装ros2的时候使用的python3.12 , 最初系统conda中python为3.10, 编译成功后运行client报错
    
    $ ros2 run py_srvcli client 2 3
    python3: /home/xg/files/code/gitee/learn-ros/dev_ws/build/example_interfaces/rosidl_generator_py/example_interfaces/srv/_add_two_ints_s.c:34: example_interfaces__srv__add_two_ints__request__convert_from_py: Assertion `PyUnicode_IS_READY(name_attr)' failed.
    [ros2run]: Aborted
    
    经过多次测试发现是由于编译的时候python版本和和安装时候不一致导致的,重新使用conda准备python3.12后恢复正常

说明

软件系统:

ubuntu24.04 Desktop

ros2 jazzy

python 3.12.4(conda)

参考文档:
Writing a simple service and client (Python)
Concepts/Basic/About-Services.html
理解 ROS2 服务

相关推荐
新加坡内哥谈技术1 小时前
ChunkKV:优化 KV 缓存压缩,让 LLM 长文本推理更高效
人工智能·科技·深度学习·语言模型·机器人
2401_897605653 小时前
星动纪元ERA-42:端到端原生机器人大模型的里程碑式突破
前端·人工智能·机器人
YONYON-R&D3 小时前
Reflexxes Type II 机器人和运动控制系统的实时运动规划库
机器人
xwz小王子13 小时前
Nature Machine Intelligence 提出了LEGION的机器人终身强化学习框架
人工智能·机器人
szxinmai主板定制专家1 天前
基于RK3588/RK3576+FPGA的巡检机器人六自由度机械臂的系统设计
机器人
赛逸展张胜1 天前
政策赋能科技服务,CES Asia 2025将展北京科技新貌
人工智能·科技·机器人
CES_Asia1 天前
汽车与AI深度融合:CES Asia 2025前瞻
人工智能·科技·机器人·汽车·智能音箱·智能电视
张3蜂2 天前
PromptSource官方文档翻译
人工智能·机器人·开源
WSSWWWSSW2 天前
mojo语言适合开发机器人控制系统么?
机器人·mojo
Binary Oracle2 天前
生成式聊天机器人 -- 基于Pytorch + Global Attention + 双向 GRU 实现的SeqToSeq模型 -- 上
pytorch·机器人·gru