ROS 接口定义:自定义 msg / srv / action(五)

发布时间:2026/10/30 9:53:41
ROS 接口定义:自定义 msg / srv / action(五)

ROS 接口定义:自定义 msg / srv / action(五)

通用基础优先 · 第五篇|ROS 通识系列|Docker 实战

一图读懂本文:三类接口文件 → 字段类型与嵌套 → 生成机制 → 版本兼容 → 数采 canonical 接口。

前面几篇用的都是 ROS 内置接口(String、JointState…)。但做数采平台,我们要让不同本体"说同一种话",就必须自己定义接口。这一篇讲清楚.msg / .srv / .action怎么写、怎么生成、以及版本兼容的坑。

一、接口文件:声明"数据的长相"

接口就三类,对应三种通信:

文件通信结构例子
.msgTopic一行一个字段抓取状态:夹爪开度 + 是否到位
.srvService请求---响应设置力矩阈值
.actionActiongoal---result---feedback执行一段示教
新手视角 · 写接口就是"设计一张表格":动笔前先回答三个问题——①这张表格谁来填、谁来看(发布者/订阅者);②每个格子是什么、什么单位、什么坐标系;③未来会加格子吗(预留兼容空间)。表格设计好了,机器人之间才不会"各说各话";表格设计烂了,后面每个用这张表的人都要来还债。

二、字段类型:基础类型 + 嵌套复用

ROS 接口支持基础类型(int32 / float64 / bool / string / time / duration等)和数组(int32[])、定长数组(float64[6]),还能嵌套其他消息。

# 自定义一个夹爪状态消息:my_robot_interfaces/msg/GripperState.msg float64 opening # 夹爪开度 0~1 bool grasped # 是否抓稳 geometry_msgs/Pose pose # 直接复用标准位姿消息
# 自定义一个"执行示教"动作:my_robot_interfaces/action/PlayTrajectory.action string trajectory_id # 目标:哪条轨迹 --- bool success # 结果:成败 float64 elapsed_sec # 结果:耗时 --- float32 progress # 反馈:0~1 进度

三、放进包里并生成(Docker 实战)

接口必须放在一个 ROS 包里,并在构建时由rosidl生成对应代码(Python/C++)。最简流程:

# 1) 建一个接口专用包(容器内,已 source) mkdir -p ~/ws/src/my_robot_interfaces && cd ~/ws/src/my_robot_interfaces

rosidl_generate_interfaces(${PROJECT_NAME}
“msg/GripperState.msg”
“action/PlayTrajectory.action”)

ros2 interface show my_robot_interfaces/msg/GripperState
ros2 interface show my_robot_interfaces/action/PlayTrajectory

提示:容器里完整走 colcon 构建比较重,本篇重点是"接口怎么定义"。可以先只记文件写法,等第 08 篇(包与构建)再动手编译。先会用ros2 interface show看别人定义好的接口,也是基本功。
老手温故 · 生成机制与零拷贝:rosidl在编译期把 .msg/.srv/.action 生成目标语言的类型代码(C++/Python),所以接口变更必须重编译依赖它的包。ROS 2 还支持进程内零拷贝(intra-process):两个节点放在同一进程(组件容器)时,大消息如图像可共享内存传递,跳过序列化——这是第 09 篇"组合节点"在机载设备上省 CPU 的底层原因。接口演进建议走语义化版本:加字段=兼容(次版本+1);改类型/改语义=破坏性(主版本+1,旧接口保留过渡期)。

四、版本兼容:接口是"契约",改了要小心

接口一旦被别的节点依赖,就是不可随意破坏的契约:

  • 加字段:通常安全(老节点忽略新字段);
  • 删/改字段类型或顺序:破坏性变更,必须升接口版本或新建接口名;
  • 数采平台里,统一动作空间的第一步就是各本体对齐同一套.msg字段定义(参考 RDT 的 128 维统一动作布局思路)。
老手温故 · 契约里最值钱的三行注释(来自项目实战):①单位——本项目核验过某本体文档"两页分别写 degree 与 radian"的自相矛盾,字段旁必须写死单位;②坐标系——position 是相对谁的(基座还是相机)?;③方向约定——夹爪 0 是"张开"还是"闭合"?这三行没写清,adapter 层迟早要还债,而且往往是在真机联调时才爆出来。

五、接回数采平台

跨品牌适配的本质,是定义一套平台中立的 canonical 接口(如统一的RobotState.msg:关节角/力矩/末端位姿),再让 KUAVO、其他本体的驱动把自家数据映射(retargeting)进这套接口。接口定义权,就是数据主权。

六、小结与下篇

  • 三接口文件对应三通信:.msg→Topic、.srv→Service、.action→Action;
  • 字段支持基础类型、数组、定长数组,并可嵌套标准消息;
  • 接口由rosidl生成代码,放包里构建;
  • 接口即契约,破坏性变更要升版本;
  • 下一篇:参数与配置——把频率、标定系数等"配置项"从代码里外置出来。
参考资料:ROS 2 官方 Tutorials(Creating custom msg and srv / action);接口规范 docs.ros.org/en/jazzy/Concepts/About-Interfaces。示例包名 my_robot_interfaces 为示意。