在 ROS 中自定义消息的完整流程需要严格遵循以下步骤,否则会导致消息无法正确生成或编译失败。以下是详细的技术流程说明:
1. 创建 .msg
文件
步骤说明
-
在功能包目录下创建
msg
文件夹(如果不存在)cd ~/catkin_ws/src/your_pkg mkdir msg
-
在
msg/
目录中创建自定义消息文件(例如SensorData.msg
)touch msg/SensorData.msg
-
定义消息字段(示例内容):
# SensorData.msg Header header # 标准消息头(包含时间戳和坐标系) string sensor_name # 传感器名称 float32 value # 测量值 float32[9] covariance # 协方差矩阵(数组类型)
技术规范
- 文件名必须为 驼峰命名法(如
SensorData.msg
) - 字段类型必须使用 ROS 支持的类型(如
int32
,string
,geometry_msgs/Point
) - 数组需用
[]
声明(如float32[]
表示动态数组)
2. 配置 package.xml
修改功能包的 package.xml
文件,添加消息生成和运行时的依赖:
<!-- package.xml -->
<build_depend>message_generation</build_depend> <!-- 编译时生成消息代码 -->
<exec_depend>message_runtime</exec_depend> <!-- 运行时依赖 -->
关键说明
message_generation
:ROS 代码生成工具的依赖,必须包含message_runtime
:消息运行时支持库,缺少会导致节点崩溃- 若依赖其他消息包(如
std_msgs
),需添加:<build_depend>std_msgs</build_depend> <exec_depend>std_msgs</exec_depend>
3. 配置 CMakeLists.txt
需修改功能包的 CMakeLists.txt
文件,依次添加以下内容:
(1) 声明消息生成依赖
find_package(catkin REQUIRED COMPONENTS
message_generation # 核心依赖
std_msgs # 标准消息包(如果使用了Header类型)
# 其他依赖...
)
(2) 注册消息文件
add_message_files(
FILES
SensorData.msg # 所有自定义的.msg文件
)
(3) 指定生成规则
generate_messages(
DEPENDENCIES
std_msgs # 依赖的外部消息包
# 其他依赖...
)
(4) 导出运行时依赖
catkin_package(
CATKIN_DEPENDS message_runtime std_msgs # 必须包含message_runtime
# 其他配置...
)
4. 编译生成代码
编译命令
cd ~/catkin_ws
catkin_make --only-pkg-with-deps your_pkg # 仅编译当前功能包
source devel/setup.bash # 刷新环境变量
生成文件路径
- C++ 头文件:
devel/include/your_pkg/SensorData.h
- Python 模块:
devel/lib/python3/dist-packages/your_pkg/msg/_SensorData.py
验证生成结果
rosmsg show your_pkg/SensorData
# 应输出:
# [your_pkg/SensorData]:
# std_msgs/Header header
# uint32 seq
# time stamp
# string frame_id
# string sensor_name
# float32 value
# float32[9] covariance
5. 在代码中使用自定义消息
Python 示例
#!/usr/bin/env python
import rospy
from your_pkg.msg import SensorData
from std_msgs.msg import Header
def publisher():
pub = rospy.Publisher('sensor_topic', SensorData, queue_size=10)
rospy.init_node('sensor_publisher')
rate = rospy.Rate(1)
msg = SensorData()
msg.header = Header(frame_id="base_link")
msg.sensor_name = "imu"
msg.value = 3.14
msg.covariance = [0.1]*9 # 初始化数组
while not rospy.is_shutdown():
pub.publish(msg)
rate.sleep()
if __name__ == '__main__':
publisher()
6. 常见错误与解决方案
错误1:找不到消息
ImportError: No module named 'your_pkg.msg'
- 原因:未正确
source devel/setup.bash
- 解决:重新 source 或检查编译日志
错误2:字段未定义
AttributeError: 'SensorData' object has no attribute 'covariance'
- 原因:修改
.msg
文件后未重新编译 - 解决:执行
catkin_make clean && catkin_make
错误3:依赖缺失
Could not find messages generated by 'std_msgs'
- 原因:
CMakeLists.txt
中未声明std_msgs
依赖 - 解决:在
find_package
和generate_messages
中添加依赖
技术总结
- 严格的文件结构:必须将
.msg
文件放在msg/
目录下 - 依赖管理:
package.xml
和CMakeLists.txt
需精确配置 - 编译顺序:修改消息定义后必须重新编译并 source 环境
- 跨包使用:若其他功能包使用此消息,需在其
package.xml
中添加<depend>your_pkg</depend>
通过此流程,开发者可以定义任意复杂的 ROS 消息,实现灵活的数据通信。