ROS 之 advertise 详解

在学习过程中接触到如下的一段话


  // ROS handles
  ros::NodeHandle node_;
  tf::TransformListener tf_;
  tf::TransformBroadcaster* tfB_;
  message_filters::Subscriber<sensor_msgs::LaserScan>* scan_filter_sub_;
  tf::MessageFilter<sensor_msgs::LaserScan>* scan_filter_;
  ros::Publisher sst_;
  ros::Publisher marker_publisher_;
  ros::Publisher sstm_;
  ros::ServiceServer ss_;

  // Set up advertisements and subscriptions
  tfB_ = new tf::TransformBroadcaster();
  sst_ = node_.advertise<nav_msgs::OccupancyGrid>("map", 1, true);
  sstm_ = node_.advertise<nav_msgs::MapMetaData>("map_metadata", 1, true);
  ss_ = node_.advertiseService("dynamic_map", &SlamKarto::mapCallback, this);
  scan_filter_sub_ = new message_filters::Subscriber<sensor_msgs::LaserScan>(node_, "scan", 5);
  scan_filter_ = new tf::MessageFilter<sensor_msgs::LaserScan>(*scan_filter_sub_, tf_, odom_frame_, 5);
  scan_filter_->registerCallback(boost::bind(&SlamKarto::laserCallback, this, _1));
  marker_publisher_ = node_.advertise<visualization_msgs::MarkerArray>("visualization_marker_array",1);

查阅了官网,现在对相关作如下的解释

advertise( ) function

 * The advertise() function is how you tell ROS that you want to
 * publish on a given topic name. This invokes a call to the ROS
 * master node, which keeps a registry of who is publishing and who
 * is subscribing. After this advertise() call is made, the master
 * node will notify anyone who is trying to subscribe to this topic name,
 * and they will in turn negotiate a peer-to-peer connection with this
 * node.  advertise() returns a Publisher object which allows you to
 * publish messages on that topic through a call to publish().  Once
 * all copies of the returned Publisher object are destroyed, the topic
 * will be automatically unadvertised.
 *
 * The second parameter to advertise() is the size of the message queue
 * used for publishing messages.  If messages are published more quickly
 * than we can send them, the number here specifies how many messages to
 * buffer up before throwing some away.
 */
  1. advertise( ) 返回一个 Publisher 对象。 通过调用对象的 publish( )函数, 你可以在这个topic上发布 message。
  2. 当所有的 Publisher 对象都被摧毁, 所有的 topic 也会被关闭。
  3. 第二个参数是 message 队列的大小

ROS Publisher 与 Subscriber 实例

包含相关头文件

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

初始化定义 Publisher 和 Subscriber

  //Publisher object manual update map    Qing Li
  ros::Publisher mapUpdateManual_Broadcaster;
  //Publisher object manual update map    Qing Li
  ros::Subscriber sub;

完善定义

    // Publisher object manual update map    Qing Li
  mapUpdateManual_Broadcaster = node_.advertise<std_msgs::String>("MapUpdateManual", 1, true);

  // Subscribe object manual update map    Qing Li   
  sub = node_.subscribe("MapUpdateManual", 1000, &SlamKarto::manualUpdateMap, this);

Subscribe 的处理函数

 void SlamKarto::manualUpdateMap(const std_msgs::String::ConstPtr& msg)
{
    if(updateMap())
    {
        ROS_DEBUG("Updated the map");
        }
    return;
    }

总结与反思

  1. 在编写过程中开在了很多地方, 还是要理解每个参数的意思。 当然最傻的一个错误就是在类内部定义了
  ros::Publisher mapUpdateManual_Broadcaster;
  ros::Subscriber sub;

我在完善的过程中, 又复写了这样的话

    ros::Publisher  mapUpdateManual_Broadcaster = node_.advertise<std_msgs::String>("MapUpdateManual", 1, true);
   ros::Subscriber  sub = node_.subscribe("MapUpdateManual", 1000, &SlamKarto::manualUpdateMap, this);

当 slam_karto 运行过程中, 用rostopic list 始终看不到 名称为 MapUpdateManual 的 topic。 是因为第二种写法相当于重新定义了一个 publisher 和 Subscriber 不在实例化范围内, 不是那个私有的对象, 所以当然不能在 rostopic 显示了。

2. 在编写过程中还有一个问题
moi@moi-ThinkPad-T440p:~$ rostopic pub /MapUpdateManual std_msgs/String "ABC"
publishing and latching message. Press ctrl-C to terminate

当我发布话题的时候,他会一直停留在 “publishing and latching message. Press ctrl-C to terminate” 这句话。 我再次输入还需要 ctrl-c, 这样比较麻烦, 后面再看看有没有什么直接返回的解决方案。

猜你喜欢

转载自blog.csdn.net/Fourier_Legend/article/details/82109817
今日推荐