0. 前言
-
ROS 中可通过 publisher/subscriber 和 topic 实现设计模式中的发布-订阅模式。而传递数据的基本数据结构就是message(消息)
-
ROS 中定义了很多消息格式,比如数字、字符串、图片等。然而,在实际开发过程中,往往需要自己定义消息格式。
-
自定义消息的实际使用可分为三个部分
- 第一步:确定数据结构,创建
.msg
文件 - 第二步:构建一个包(pkg),解析上面的
.msg
文件,并发布该消息结构 - 第三步:在其他包中,使用自定义消息结构
- 第一步:确定数据结构,创建
-
参考资料:
1. 创建 .msg
文件
-
参考资料:官方文档-msg
-
ROS 有自己的 Message Description Language,专门用于
.msg
文件的创建。 -
每个
.msg
文件最终都对应一个类,文件中每一行对应一个成员变量,格式如下
fieldtype1 fieldname1
fieldtype2 fieldname2
fieldtype3 fieldname3
- fieldtype 注意事项
- 有四种类别,分别是内置类型(如float32)、其他定义的消息类型(如
geometry_msgs/PoseStamped
)、数组(长度可以固定,也可以不固定,如float32[]
或float32[10]
)、特殊类型 Header - 内置类型如下图所示
- 有四种类别,分别是内置类型(如float32)、其他定义的消息类型(如
- Header 类型是
std_msgs
中定义的
#Standard metadata for higher-level flow data types
#sequence ID: consecutively increasing ID
uint32 seq
#Two-integer timestamp that is expressed as:
# * stamp.secs: seconds (stamp_secs) since epoch
# * stamp.nsecs: nanoseconds since stamp_secs
# time-handling sugar is provided by the client library
time stamp
#Frame this data is associated with
string frame_id
- 以目标检测结果为例,定义自定义消息类型
BoxesMsg.msg
- 每张图片的检测结果对应一个
BoxesMsg
对象 - 内容包括:header、物体数量、x1y1x2y2形式的坐标、box置信度、box类别
- 每张图片的检测结果对应一个
Header header
int32 num_objects
float32[] coords
float32[] socres
int32[] classes
2. 构建 pkg 解析 .msg
文件
-
本文构建
custom_msg
包来解析上面提到的BoxesMsg.msg
-
步骤一:修改
package.xml
- 如果指定了其他包定义的自定义消息,则需要确保在package中引入了其他的包。
- 例如,要使用
Header
就需要引入std_msgs
- 例如,要使用
- 在
build_depend
和build_export_depend
中添加message_generation
- 在
exec_depend
中添加message_runtime
- 如果指定了其他包定义的自定义消息,则需要确保在package中引入了其他的包。
<build_depend>message_generation</build_depend>
<build_export_depend>message_generation</build_export_depend>
<exec_depend>message_runtime</exec_depend>
- 步骤二:修改
CMakeLists.txt
- 在
find_package
中添加message_generation
- 添加
add_message_files
和generate_messages
,注意,前后顺序不能改变
- 在
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)
# 自定义消息相关配置
add_message_files(
FILES
BoxesMsg.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
3. 在其他 pkg 中使用自定义消息
- 本质就是 引用同一工作区中pkg,这个本文就不介绍了。
- 现在主要看一下在源码中如何使用
- 前提:在
custom_msgs
包中添加了BoxesMsg.msg
文件。
- 前提:在
- 在其他包中使用
BoxesMsg.msg
主要包括- 添加头文件:
#include "custom_msgs/BoxesMsg.h"
,即<包名/文件名.h>
- 可使用对象:
BoxesMsg
、BoxesMsgPtr
、BoxesMsgConstPtr
,顾名思义,第一个是普通类,第二个和第三个都是第一个对象的指针。 - 对象中成员变量对应数据类型:
- msg中内置类型对应C++类型的关系表,在第一章中有截图
- 数组类型对应C++中的
std::vector
- 添加头文件: