摘要:本文基于 WSL2 Ubuntu 24.04 真机环境,完整演示 ROS 2 Jazzy 下自定义 srv 服务接口的全链路搭建与通信流程。内容涵盖:自定义接口包与纯 Python 业务包的创建、package.xml 与 CMakeLists.txt 的关键避坑配置、setup.cfg 与 setup.py 的适配补丁,以及编译、环境刷新、服务端/客户端启动与验证的完整命令。全程零冗余,照着操作即可一次跑通从接口定义到双向服务通信的全过程。
关键词:ROS 2 自定义服务接口、WSL2 ROS 2 开发、Python 服务通信实战
一、前置环境 - WSL2 Ubuntu 24.04 LTS 纯净环境
- ROS 2 Jazzy 桌面完整版
- 工作区路径:
/home/zz/ros2_ws
二、为什么选 srv 做服务通信
什么是 ROS2 的 srv
ROS 2 里的 srv 是专门定义一问一答服务通信的接口协议文件,你可以把它理解成节点之间的专属「通话约定」:客户端发起请求,服务端处理完必须返回明确的响应结果,是和 topic 发布订阅完全不同的另一套通信范式。
srv 和 topic 的对比
对比维度 topic(发布订阅) srv(服务通信) 通信模式 单向广播,发布者发完就不管 双向同步,严格的请求→应答一对一 数据流向 1 对多、多对多无状态广播 点对点,单次请求对应单次返回 核心适用场景 高频持续上报数据,比如摄像头图像、雷达点云 单次指令类操作,比如调用导航、触发拍照、电机启停 相比 topic 单向广播,自定义 srv 有三个难以替代的核心优势:
- 天然带执行反馈:发完请求立刻就能拿到服务端的执行结果,不会像 topic 那样发完指令完全不知道对方有没有收到、有没有执行成功
- 双向数据独立定义:一份 srv 文件里可以分开写请求段和响应段,入参和返回值的数据结构完全独立,不用像 topic 那样额外拆两个消息包来回发
- 编译期强类型校验:两端的请求响应字段定义不匹配直接编译报错,从根源上避免运行时传错字段、数据错位的隐性 Bug,工业级控制场景几乎 100% 用 srv 做核心交互
三、全量文件目录总览
先展示最终的完整目录结构,所有文件位置一目了然,不会放错:
~/ros2_ws/src/ ├── my_first_interfaces/ # 自定义接口包 │ ├── CMakeLists.txt │ ├── package.xml │ └── srv/ │ └── AddTwoInts.srv └── my_first_pkg/ # Python 业务包 ├── setup.cfg ├── setup.py ├── package.xml ├── resource/ │ └── my_first_pkg └── my_first_pkg/ ├── add_two_ints_server.py └── add_two_ints_client.py四、创建自定义接口包
这一步最容易触发 Jazzy 专属强制校验报错,直接按下面配置编写即可一次通过。先创建接口包,再依次配置 srv 文件、package.xml 和 CMakeLists.txt:
- 进入工作区 src 目录创建接口包
cd~/ros2_ws/src ros2 pkg create my_first_interfaces --build-type ament_cmake- 新建 srv 目录,编写 AddTwoInts.srv 文件
int64 a int64 b --- int64 sum- 替换 package.xml,关键避坑:
<member_of_group>必须放在根节点下,不要放在<export>里
<?xml version="1.0"?><packageformat="3"><name>my_first_interfaces</name><version>0.0.0</version><license>Apache-2.0</license><buildtool_depend>ament_cmake</buildtool_depend><build_depend>rosidl_default_generators</build_depend><