5.3 KiB
5.3 KiB
16 · 自定义接口 (.msg / .srv / .action) 完全指南
目标: 理解 ROS2 自定义接口的设计原理、文件格式、rosidl 工具链、能独立写 .msg / .srv / .action。
目录
- 1. 为什么需要自定义
- 2. .msg 文件格式
- 3. .srv 文件格式
- 4. .action 文件格式
- 5. rosidl_generate_interfaces
- 6. CMakeLists.txt + package.xml 配置
- 7. C++ / Python 使用
- 8. 设计原则
- 9. 推荐阅读
1. 为什么需要自定义
ROS2 标准消息(std_msgs / sensor_msgs / geometry_msgs)覆盖了 80% 场景,但有些项目特定需求:
- 工业传感器读数(温度 + 压力 + 校准日期)
- 机器人状态(电量 + 温度 + 故障码)
- 业务动作(下单 + 支付 + 物流)
这些都需要项目特定的自定义接口。
2. .msg 文件格式
# 注释(以 # 开头)
<type> <field_name> # 字段
字段类型:
| ROS 类型 | C++ 类型 | Python 类型 |
|---|---|---|
bool |
bool |
bool |
int8/int16/int32/int64 |
int8_t/... |
int |
uint8/.../uint64 |
uint8_t/... |
int |
float32/float64 |
float/double |
float |
string |
std::string |
str |
time/duration |
builtin_interfaces::msg::Time |
Time |
| 其他消息类型 | pkg::msg::Type |
pkg.msg.Type |
type[] |
std::vector<T> |
List[T] |
type[3] |
std::array<T,3> |
Tuple[T,T,T] |
示例: msg/SensorReading.msg
std_msgs/Header header
string sensor_id
string unit
float64 value
3. .srv 文件格式
# Request 字段(--- 上)
<type> <field_name>
---
# Response 字段(--- 下)
<type> <field_name>
示例: srv/GetCalibration.srv
string sensor_id
---
float64[9] intrinsic_matrix
float64[3] bias
string calibration_date
bool valid
4. .action 文件格式
# Goal 字段(第 1 段)
<type> <field_name>
---
# Result 字段(第 2 段)
<type> <field_name>
---
# Feedback 字段(第 3 段)
<type> <field_name>
示例: action/MoveArm.action
geometry_msgs/PoseStamped target_pose
string[] joint_names
float32 max_velocity_scaling
float32 max_acceleration_scaling
---
bool success
string error_message
float64 total_time_sec
---
float32 progress
string current_state
5. rosidl_generate_interfaces
ROS2 用 rosidl 自动从 .msg/.srv/.action 生成 C++ / Python 代码:
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/SensorReading.msg"
"srv/GetCalibration.srv"
"action/MoveArm.action"
DEPENDENCIES std_msgs geometry_msgs
ADD_LINTER_TESTS
)
生成位置:
- C++ 头文件:
install/<pkg>/include/<pkg>/msg/<msg_name>.hpp - Python 模块:
install/<pkg>/lib/python3.10/site-packages/<pkg>/msg/<msg_name>.py
6. CMakeLists.txt + package.xml 配置
package.xml 必备:
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
CMakeLists.txt 顺序:
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME} ...)
ament_target_dependencies(${PROJECT_NAME}_core rclcpp "rosidl_typesupport_cpp")
rosidl_target_interfaces(${PROJECT_NAME}_core ${PROJECT_NAME} "rosidl_typesupport_cpp")
7. C++ / Python 使用
C++
#include "cpp_custom_interface/msg/sensor_reading.hpp"
auto msg = cpp_custom_interface::msg::SensorReading();
msg.sensor_id = "imu_0";
msg.value = 1.234;
publisher_->publish(msg);
Python
from cpp_custom_interface.msg import SensorReading
msg = SensorReading()
msg.sensor_id = 'imu_0'
msg.value = 1.234
publisher.publish(msg)
8. 设计原则
| 原则 | 说明 |
|---|---|
| 优先标准接口 | 90% 场景用 std_msgs / sensor_msgs |
| 字段 snake_case + 单位后缀 | velocity_mps 而不是 v |
| Header 必备 | 任何有"时间戳"的消息都加 std_msgs/Header |
| 数组 vs 单值 | float64[] 用于多维数据,单值用 float64 |
| 不要嵌指针 | 用 ID (string object_id) 而非 string& |
| 字段命名清晰 | target_pose 不是 tp,max_velocity_scaling 不是 v_max |
| Result 加 success + error_message | client 知道成功还是失败 |
9. 推荐阅读
📖 阅读路径导航
💡 这是仓库
doc/下所有文档的推荐阅读顺序。返回 README 总导航⏱ 本文预计阅读时间: 40 分钟 📍 当前位置: 第 7 / 24 篇
- ⏮ 上一篇: 参数系统深度
- ⏭ 下一篇: Lifecycle Node