首先贴上roswiki上消息发布器的代码:
#include "ros/ros.h" #include "std_msg/string.h" #include <sstream> int main(int argc,char**argv) { ros::init(argc,argv,"talker"); ros::NodeHandle n; ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000) ros::Rate loop_rate(10); int count=0; while(ros::ok()) { std_msgs::String msg; std::stringstream ss; ss<<"hello world"<<count; msg.data=ss.str(); ROS_INFO("%s",msg.data.c_str()); chatter_pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); ++count; } return 0; }ros::init(argc,argv,"talker")在我的博客ros解析(一)中已经说明了。
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);它的作用是:告诉ROS希望在给定的主题名称上发布内容。这将调用对ROS主节点的调用,该节点保存一个注册表,记录谁在发布和谁在订阅。在发出这个advertising()调用之后,主节点将通知任何试图订阅此主题名称的人,然后他们将与此节点协商对等连接。advertising()返回Publisher对象,该对象允许您通过调用publish()发布关于该主题的消息。一旦返回的Publisher对象的所有副本都被销毁,主题就会被销毁,将自动不广播。advertising()的第二个参数是用于发布消息的消息队列的大小。如果发布消息的速度比我们发送消息的速度快,这里的数字指定在丢弃一些消息之前要缓冲多少消息。
告诉 master 我们将要在 chatter(话题名) 上发布 std_msgs/String 消息类型的消息。这样 master 就会告诉所有订阅了 chatter 话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 1000 个的时候就会开始丢弃先前发布的消息。
NodeHandle::advertise() 返回一个 ros::Publisher 对象,它有两个作用: 1) 它有一个 publish() 成员函数可以让你在topic上发布消息; 2) 如果消息类型不对,它会拒绝发布。
ros::Rate loop_rate(10);ros::Rate 对象可以允许你指定自循环的频率。它会追踪记录自上一次调用 Rate::sleep() 后时间的流逝,并休眠直到一个频率周期的时间。
在这个例子中,我们让它以 10Hz 的频率运行。
81 int count = 0; 82 while (ros::ok()) 83 {如果下列条件之一发生,ros::ok() 返回false:
SIGINT 被触发 (Ctrl-C)被另一同名节点踢出 ROS 网络ros::shutdown() 被程序的另一部分调用节点中的所有 ros::NodeHandles 都已经被销毁一旦 ros::ok() 返回 false, 所有的 ROS 调用都会失效。
chatter_pub.publish(msg);这里,我们向所有订阅 chatter 话题的节点发送消息。
ros::spinOnce();这个语句是作用于回调函数中的,在这个例子中并不是一定要调用 ros::spinOnce(),因为我们不接受回调。然而,如果你的程序里包含其他回调函数,最好在这里加上 ros::spinOnce()这一语句,否则你的回调函数就永远也不会被调用了。
这条语句是调用 ros::Rate 对象来休眠一段时间以使得发布频率为 10Hz。