ros 发布信息频率_ROS 消息

ros消息类型,即是ros话题的格式,可视为ros的数据类型,基本上是指同一个意思。ros消息类型是基于C++基本类型封装为.msg文件实现,rosmsg指令用于消息管理。

一. ros预定义的消息类型

所谓预定义消息类型是可以直接引用,不需要自己实现,ros自定义数据类型通常包括两类,一类是在 std_msgs 包下,包含基本数据类型,例如字符型、整型以及浮点型等;一类是在 common_msgs 包下,包含常用的数据类型、例如传感器数据类型、导航数据类型以及几何数据类型等。

1. 基本数据类型

基本数据类型位于 std_msgs包,在ROS 话题篇,我们使用了ros字符串类型 std_msgs/String,就是一种基本类型,可使用 rosls 查看其消息文件路径:

rosls std_msgs/msg/String.msg

如图:

使用 roscat 通过消息文件查看其具体实现:

roscat std_msgs String.msg

如图:

也可直接使用 rosmsg 查看其具体实现:

rosmsg show std_msgs/String

如图:

可以通过 rosmsg 查看 ros 所有的基本数据类型:

rosls std_msgs/msg/

也可以通过如下网页查看:http://wiki.ros.org/std_msgs​wiki.ros.org

2. 常用数据类型

常用数据类型基本上是基于基本数据类型封装而成,按照功能,封装在不同的包内,例如图像数据封装在 sensor_msgs包 下,通过 rosls 和 rosmsg 指令查看如下:

rosls sensor_msgs/msg/Image.msg

rosmsg show sensor_msgs/Image

如图:

除了图像基本数据外,还包含一个消息类型:std_msgs/Header,此消息类型包含三项:序列号, 时间戳 以及 帧id, 帧id表示消息类别,例如 camera,表示相机数据;序列号表示是第几帧数据,时间戳常用语与其他消息做同步使用。基本上所有的常用数据类型都会包含此数据类型。

可以通过如下链接查看所有的常用消息类型:https://wiki.ros.org/common_msgs?distro=kinetic​wiki.ros.org

二. 自定义消息类型

虽然ros提供了较为丰富的预定义消息类型,但是在实际开发中,经常需要自己定义合适的数据类型以满足自己的需求,下面通过创建两个节点,介绍下如何自定义消息,以及如何使用自定义消息。

1. 创建自定义消息

roscd beginner_tutorials/

mkdir msg

touch msg/Num.msg

Num.msg文件内容如下:

int32 a

int32 b

至此我们创建了一个自定义消息。

文件链接:https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/msg/Num.msg​github.com

这里我们创建的消息格式是 .msg,在c++程序中,消息是以头文件形式出现,所以需要把 .msg 文件编译为 .h 文件。

2. 配置package.xml

在 package.xml 文件中添加如下三行,使用任何自定义消息,都必须使用这三行。

message_generation

message_runtime

message_runtime

文件链接:https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/package.xml​github.com

第一行表示编译时依赖,第二行导出依赖,即其他包中程序可以使用本消息,第三行表示运行时依赖。

3. 配置CMakeLists.txt

将 message_generation 加入到 find_package(), find_package() 要与 package.xml 文件中的 build_depend 一致,表示编译时依赖的包。

将 Num.msg 加入 add_message_files(),表示要编译的消息文件。放开 generate_messages(),表示生成消息头文件。

将 message_runtime 加入 catkin_package() 表示导出运行时依赖。

这里看不明白也没关系,在添加消息时,按照这个套路配置就可以了。至此我们完成自定义消息配置。

4. 检测自定义消息是否完成

rosmsg show beginner_tutorials/Num

输出:

int32 a

int32 b

表示自定义消息成功。在这一步我们还没有编译消息文件,下一步编译消息文件。

三. 编译消息文件

catkin_make

编译完之后,会生成相应的头文件:./devel/include/beginner_tutorials/Num.h

四. 使用自定义消息

1. 创建订阅节点listener_msg

cp listener.cpp listener_msg.cpp

做如下修改:

第13行,将节点名 listener 改为 listener_msg

第16行,将话题名 chatter 改为 chatter_msg

第5行,修改回调函数参数。

第2行,引入消息头文件。修改后内容如下:

#include "ros/ros.h" //ros.h 包含ros程序常用的头文件。

#include "beginner_tutorials/Num.h" //自定义消息类型。

//回调函数定义,参数类型需要与所订阅的消息类型保持一致

void chatterCallback(const beginner_tutorials::Num::ConstPtr& msg)

{

ROS_INFO("I heard: [%d %d %d]", msg->a,msg->b,msg->a+msg->b);

}

int main(int argc, char **argv)

{

ros::init(argc, argv, "listener_msg"); //初始化ros,并命令节点名。

ros::NodeHandle n; //初始化节点,调用ros api接口句柄。

ros::Subscriber sub = n.subscribe("chatter_msg", 1, chatterCallback); //定义一个订阅者。

ros::spin(); //不返回函数,监听订阅者中的回调队列,并执行回调函数。

return 0; //正常运行时,不会执行到。

}

可参考链接:https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/src/listener/listener_msg.cpp​github.com

2. 创建发布节点talker_msg

cp talker.cpp talker_msg.cpp

做如下修改:

第2行引入消息头文件,注意格式,需要包含包名。

第6行修改节点名。

第9行修改话题名,以及消息类型,消息类型与头文件格式保持一致,都要添加包名。

第12行,定义一个消息变量。

第14和15行,更新消息内容。

第16行打印消息。

第17行发布消息。修改后如下:

#include "ros/ros.h" //ros.h 包含ros程序常用的头文件。

#include "beginner_tutorials/Num.h" //自定义消息类型。

int main(int argc, char **argv)

{

ros::init(argc, argv, "talker_msg"); //初始化ros,并命令节点名。

ros::NodeHandle n; //初始化节点,调用ros api接口句柄。

//定义一个发布者

ros::Publisher chatter_pub = n.advertise<:num>("chatter_msg", 1);

ros::Rate loop_rate(10); //设置发布频率

int count = 0; //发布消息计数

beginner_tutorials::Num num; //定义一个消息变量。

while (ros::ok()){ //检测节点是否正常运行

num.a = count;

num.b = count+1;

ROS_INFO("%d %d %d", num.a,num.b,num.a+num.b); //打印消息

chatter_pub.publish(num); //发布消息

ros::spinOnce(); //处理回调函数,会返回,这里也可以不加,因为此节点没有回调函数。

loop_rate.sleep(); //与Line 11配套使用,用于控制发布频率。

++count; //消息计数。

}

return 0;

}

可参考链接:https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/src/talker/talker_msg.cpp​github.com

3. 添加到CMakeLists.txt

添加如下指令:

add_executable(listener_msg src/listener/listener_msg.cpp)

target_link_libraries(listener_msg ${catkin_LIBRARIES})

add_dependencies(listener_msg ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

add_executable(talker_msg src/talker/talker_msg.cpp)

target_link_libraries(talker_msg ${catkin_LIBRARIES})

add_dependencies(talker_msg ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

完成文件参考链接:https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/CMakeLists.txt​github.com

五. 编译工程

catkin_make

六. 运行测试节点

roscore

rosrun beginner_tutorials listener_msg

rosrun beginner_tutorials talker_msg

运行效果如下如:

使用 rqt_graph 指令,如下图:

可以比较清晰看到节点话题之间的关联。

七. 小结

本篇介绍了ros预定义的消息类型,以及如何自定义消息类型,以及如何使用自定义消息类型。消息类型是话题独有,话题是ros最为常用的通信方式,属于异步通信,下一篇介绍ros同步通信方式:服务。

你可能感兴趣的:(ros,发布信息频率)