ros 发布器和订阅器

发布器节点:

talker.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

 int main(int argc, char **argv)
 {
 /**初始化ROS。它允许ROS通过命令行进行名称重映射。同样,也在这里指定节点的名称——必须唯一。这里的名称必须是一个base name,不能包含/ .**/

   ros::init(argc, argv, "talker");

   /**为这个进程的节点创建一个句柄。第一个创建的NodeHandle会为节点进行初始化,最后一个销毁的NodeHandle会清理节点使用的所有资源。**/

   ros::NodeHandle n;

   /**告诉节点管理器master将要在chatter topic上发布一个std_msgs/String的消息。这样master就会告诉所有订阅了chatter topic的节点,将要有数据发布。第二个参数是发布序列的大小。在这样的情况下,如果发布的消息太快,缓冲区中的消息在大于1000个的时候就会开始丢弃先前发布的消息。NodeHandle::advertise() 返回一个 ros::Publisher对象,它有两个作用: 1) 它有一个publish()成员函数可以在topic上发布消息; 2) 如果消息类型不对,它会拒绝发布。**/

   ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

   /**ros::Rate对象可以允许指定自循环的频率。它会追踪记录自上一次调用Rate::sleep()后时间的流逝,并休眠直到一个频率周期的时间。在这个例子中,让它以10hz的频率运行。**/

   ros::Rate loop_rate(10);

   int count = 0;

   while (ros::ok())
   {/**roscpp会默认安装一个SIGINT句柄,它负责处理Ctrl-C键盘操作——使得ros::ok()返回FALSE。ros::ok()返回false,如果下列条件之一发生:SIGINT接收到(Ctrl-C);被另一同名节点踢出ROS网络;ros::shutdown()被程序的另一部分调用;所有的ros::NodeHandles都已经被销毁.一旦ros::ok()返回false, 所有的ROS调用都会失效。**/

     //发布消息类型
     std_msgs::String msg;
     std::stringstream ss;
     ss << "Hello World" << count;
     msg.data = ss.str();

     /**使用一个由msg file文件产生的‘消息自适应’类在ROS网络中广播消息。现在使用标准的String消息,它只有一个数据成员"data"。当然也可以发布更复杂的消息类型。**/

     /**ROS_INFO日志文件输出,类似的函数用来替代printf/cout. **/

     ROS_WARN("%s", msg.data.c_str());

     /**现在已经向所有连接到chatter topic的节点发送了消息。**/

     chatter_pub.publish(msg);

     /**在这个例子中并不是一定要调用ros::spinOnce(),因为不接受回调。然而,如果想拓展这个程序,却又没有在这调用ros::spinOnce(),那么回调函数就永远也不会被调用。所以,在这里最好还是加上这一语句。**/

     ros::spinOnce();

   /**这条语句是调用ros::Rate对象来休眠一段时间以使得发布频率为10hz。**/  

     loop_rate.sleep();

     ++count;

   }

   return 0;
 }

 

订阅器节点listener 节点

 listener.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_WARN("I heard: [%s]", msg->data.c_str());
}

//这是一个回调函数,当消息到达chatter topic的时候就会被调用。消息是以 boost shared_ptr指针的形式传输,这就意味着可以存储它而又不需要复制数据

int main(int argc, char **argv){

   /**初始化ROS。它允许ROS通过命令行进行名称重映射——目前,这不是重点。同样,也在这里指定节点的名称——必须唯一。这里的名称必须是一个base name,不能包含/ .**/

   ros::init(argc, argv, "listener");

   /**为这个进程的节点创建一个句柄。第一个创建的NodeHandle会为节点进行初始化,最后一个销毁的NodeHandle会清理节点使用的所有资源。**/

   ros::NodeHandle n;

  /**告诉master要订阅chatter topic上的消息。当有消息到达topic时,ROS就会调用chatterCallback()函数。第二个参数是队列大小,以防处理消息的速度不够快,在缓存了1000个消息后,再有新的消息到来就将开始丢弃先前接收的消息。NodeHandle::subscribe()返回ros::Subscriber对象,必须让它处于活动状态直到不再想订阅该消息。当这个对象销毁时,它将自动退订上述的消息。有各种不同NodeHandle::subscribe()函数,允许指定类的成员函数,甚至是Boost.Function对象可以调用的任何数据类型。**/

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

 /**ros::spin()进入自循环,可以尽可能快的调用消息回调函数。如果没有消息到达,它不会占用很多CPU,所以不用担心。一旦ros::ok()返回FALSE,ros::spin()就会立刻跳出自循环。这有可能是ros::shutdown()被调用,或者是用户按下了Ctrl-C,使得master告诉节点要shutdown。也有可能是节点被人为的关闭。**/

  ros::spin();
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值