ROS学习----Publisher与Subscriber

1.Publisher(发布者)与subscriber(订阅者)关系。
Publisher的主要作用是对于指定话题发布特定数据类型的消息。
下面是利用代码实现一个节点,节点创建一个Publisher并发布字符串“Hello world”,其详细内容如下:

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

int main (int argc,char  **argv)
{
   //ROS节点初始化
   ros::init(argc,argv,"talker");     **2**
   //创建节点句柄
   ros::NodeHandle n;     **3**
   //创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
   ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000);      **4**
   //设置循环的频率
   ros::Rate loop_rate(10);    **5**
   int count=0;
   while(ros::ok())      **6**
   {
     //初始化std_msgs::String类型的消息
     std_msgs::String msg;       **7**
     std::Stringstream ss;         **7**
     ss<<"hello world"<<count;       **7**
     msg.data=ss.str();           **7**

   //发布消息
   ROS_INFO("%s",msg.data.c_str());       **8**
   chatter_pub.publish(msg);             **9**

  //循环等待回调函数
  ros::spinOnce();                    **10**

  //按照循环频率延时
  loop_rate.sleep();                  **11**
  ++count;
   }
   return 0;
}

代码说明:
“1”:“ros/ros.h”包含了大部分ROS中通用的头文件
“2”:初始化ROS节点,init函数包含三个参数,前两个参数是命令行或launch文件输入的参数;第三个参数定义了Publisher节点的名称,而且该名称在运行的ROS中必须是独一无二的,不允许同时存在相同名称的两个节点。
“3”:创建一个节点句柄,方便对节点资源的使用和管理。
“4”:在ROS master注册一个Publisher,并告诉系统Publisher节点将会发布以chatter为话题的String类型消息。第二个参数表示消息队列的大小,当消息数量超过队列大小时,ROS会自动删除队列中最早入对的消息。
“5”:设置循环的频率,单位是Hz。
“6”:进入节点的主循环,遇到异常的状况便会返回false,跳出循环。异常情况包括:

  • 收到SIGINT信号(Ctrl+c)
  • 被另外一个相同名称的节点踢掉线
  • 节点调用了关闭函数ros::shutdown()
  • 所有ros::NodeHandles句柄被销毁

“7”: 初始化即将发布的消息。
“8”:ROS_INFO类似与C/C++中的printf/cout函数,用来打印日志信息。
“9”:发布封装完毕的消息msg。消息发布后,Master会查找订阅该话题的节点,并且帮助两个节点建立连接,完成消息的传输。
“10”:用来处理节点订阅话题的所有回调函数
“11”:调用休眠函数使节点进入睡眠在台。但是10Hz的睡眠时间过后,节点又会开始下一阶段的循环工作

总结Publisher的流程,为:

  • 初始化ROS节点
  • 向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型。
  • 按照一定频率循环发布消息

创建Subscriber:
创建一个Subscriber以订阅Publisher节点发布的“Hello world”字符串,其源码为:

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

//接收到订阅的消息后,会进入消息回调函数
 void chatterCallback(const std_msgs::String::ConstPtr& msg)
 {
    //将接收到的消息打印出来
     ROS_INFO("I heard: [%s]",msg->data.c_str());
 }

int main(int argc,char **argv)
{
   //初始化ROS节点
   ros::init(argc,argv,"listener");

   //创建节点句柄
   ros::NodeHandle n;
 
   //创建一个Subscriber,订阅名为chatter的话题,注册回调函数chatterCallback
   ros::Subscriber sub=n.subscribe("chatter",1000,chatterCallback);

  //循环等待回调函数
  ros::spin();

   return 0;
}

Subscriber的实现简要流程:

  • 初始化ROS节点
  • 订阅需要的话题
  • 循环等待话题消息,接收到消息后进入回调函数
  • 在回调函数中完成消息处理

猜你喜欢

转载自blog.csdn.net/qq_24251645/article/details/88139094
今日推荐