引言:
在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息… std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型。
msgs只是简单的文本文件,每行具有字段类型和字段名称,可以使用的字段类型有:
int8
,int16
,int32
,int64
(或者无符号类型:uint*
)float32
,float64
string
time
,duration
- other msg files
- variable-length
array[]
and fixed-lengtharray[C]
ROS中还有一种特殊类型:Header
,标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有 Header标头。
一、创建自定义msg文件:
在上一篇文章中,已经建立了工作空间,接着上面的内容,在工作空间/src/功能包
文件夹下创建msg命名的文件夹
,在文件夹中创建自定义消息名.msg
,输入以下内容:
time stamp
bool flag_QR
bool flag_YOLOV
bool flag_Load
如果定义字符串string类型,注意s
要小写,大写编译不通过
二、配置CmakeLists文件:
1、package.xml
中添加编译依赖与执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
2、CMakeLists.txt
编辑 msg 相关配置
(1)添加message_generation
需要加入 message_generation,必须有std_msgs
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
(2)配置 msg 源文件
add_message_files(
FILES
Flag.msg ##自己msg文件的名字
)
(3)配置generate_messages
生成消息时依赖于std_msgs
generate_messages(
DEPENDENCIES
std_msgs
)
(4)执行时依赖
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
行取消注释并在末尾添加message_runtime
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES task
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
三、编写发布方C++文件:
#include<task/Flag.h> //导入消息头文件
#include <task/task.h>
int main(int argc,char *argv[]){
setlocale(LC_ALL,"");
/*初始化节点句柄*/
ros::init(argc,argv,"task");
ros::NodeHandle nh;
ros::Publisher Flag_pub = nh.advertise<task::Flag>
("task/Flag", 10);
//设置主频率
ros::Rate rate(20.0);
//测试自定义msg
task::Flag flag;
flag.stamp = ros::Time::now();
flag.flag_Load = false;
flag.flag_QR = false;
flag.flag_YOLOV = false;
while(ros::ok()){
Flag_pub.publish(flag);
ros::spinOnce();
rate.sleep();
}
return 0;
}
四、配置CmakLists文件:
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(task src/task.cpp)
add_dependencies(task ${PROJECT_NAME}_generate_messages_cpp)
target_link_libraries(task
${catkin_LIBRARIES}
)
五、测试:
编译通过后运行
roscore
rosrun task task
另开终端,重新进入工作空间,打印话题消息(必须要进入工作空间,否则会报错)
rostopic echo /task/Flag
报错:
正常:
附:在ROS中,时间戳(timestamp)是用来表示某个事件发生时间的一种方式。时间戳通常由两部分组成:一个整数(secs
)表示自某个特定时间点(如1970年1月1日00:00:00 UTC)到事件发生时的秒数(即“秒级时间戳”),以及一个整数(nsecs
)表示事件发生时相对于秒级时间戳的纳秒数(即“纳秒偏移量”