在學習過程中接觸到如下的一段話
// 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.
*/
- advertise( ) 返回一個 Publisher 對象。 通過調用對象的 publish( )函數, 你可以在這個topic上發佈 message。
- 當所有的 Publisher 對象都被摧毀, 所有的 topic 也會被關閉。
- 第二個參數是 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;
}
總結與反思
- 在編寫過程中開在了很多地方, 還是要理解每個參數的意思。 當然最傻的一個錯誤就是在類內部定義了
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, 這樣比較麻煩, 後面再看看有沒有什麼直接返回的解決方案。