ROS中订阅最新消息以及对消息队列的浅谈
ros的topic:创建消息类型、发布、订阅
1. ROS话题的发布
#include <ros/ros.h>
#include "ros_tutorials_topic/MsgTutorial.h"// MsgTutorial消息头文件,构建后自动生成
int main(int argc, char** argv) //节点主函数
{
ros::init(argc, argv, "topic_publisher"); //初始化节点
ros::NodeHandle nh; //声明节点句柄来与ROS系统进行通行
/*
声明发布者,创建一个使用ros_tutorial_topic功能包MsgTutorial消息文件
的发布者ros_tutorial_pub。话题名称是“ros_tutorial_msg",
消息发布者队列(queue)的大小设置为100
*/
ros::Publisher ros_tutorial_pub = nh.advertise<ros_tutorials_topic::MsgTutorial>
("ros_tutorial_msg", 100);
//设定循环周期。 "10" 是10Hz, 是以0.1间隔重复
ros::Rate loop_rate(10);
ros_tutorials_topic::MsgTutorial msg; //以MsgTutorial消息文件格式声明一个名称为msg的消息
int count = 0;
while(ros::ok())
{
msg.stamp = ros::Time::now(); // 把当前时间传给msg的下级消息stamp
msg.data = count; //将变量count的值传给下级消息data
ROS_INFO("send msg = %d", msg.stamp.sec); //显示stamp.sec消息
ROS_INFO("send msg = %d", msg.stamp.nsec); //显示stamp.nsec消息
ROS_INFO("send msg = %d", msg.data);
ros_tutorial_pub.publish(msg); //发布消息
loop_rate.sleep(); //按照上述定义的循环周期进行暂歇
++count; //变量count加1
}
return 0;
}
2. ROS话题订阅
#include "ros/ros.h"
#include "ros_tutorials_topic/MsgTutorial.h"
/*
这是一个消息后台函数,
此函数在收到一个下面设置的名为ros_tutorial_msg的话题时候被调用
输入的消息是从ros_tutorials_topic功能包接收MsgTutorial消息
*/
void msgCallback(const ros_tutorial_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recieve msg = %d", msg->stamp.sec); //显示stamp.sec消息
ROS_INFO("recieve msg = %d", msg->stamp.nsec); //显示stamp.nsec消息
ROS_INFO("recieve msg = %d", msg->data); //显示data消息
}
int main(int argc, char **argv) //节点主函数
{
ros::init(argc, argv, "topic_subscriber"); //初始化节点名称
ros::NodeHandle nh; //声明用于和ROS系统通信的节点句柄
/*声明订阅者, 创建一个订阅者 ros_tutorial_sub,
利用ros_tutorial_topic功能包的MsgTutorial消息文件
话题名称是“ros_tutorial_msg", 订阅者队列(queue)的大小设置为100
*/
ros::Subscriber ros_tutorial_sub = nh.subscribe("ros_tutorial_msg", 100, msgCallback);
// 用于调用后台函数,等待接收消息。在接收消息时执行后台函数
ros::spin();
return 0;
}
3 ros::spin()和ros::spinonce()的区别
ros::spin()和ros::spinonce()的区别
两者均为ROS消息回调处理函数,区别在于前者调用后不会再返回,也即主程序执行到这就不再继续执行;而后者在调用后还可以继续执行之后的程序。