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, 這樣比較麻煩, 後面再看看有沒有什麼直接返回的解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章