ros中Subscribe的参数用法

subscribe常用方式

Subscribe订阅中最常用的形式如下:
ros::Subscriber sub = node.subscribe<uhf_rfid_api::UhfRfid>("messageepc", 0, rfid_callback) ;
这样只用三个参数。
其中subscribe有很多重定义。例如:

Subscriber ros::NodeHandle::subscribe    (    const std::string & topic,
                                              uint32_t     queue_size,
                                              void(*)(M)     fp,
                                              const TransportHints &     transport_hints = TransportHints() 
                                           )
M [template] M here is the callback parameter type (e.g. const boost::shared_ptr& or const M&), not the message type, and should almost always be deduced
topic Topic to subscribe to
queue_size Number of incoming messages to queue up for processing (messages in excess of this queue capacity will be discarded).
fp Function pointer to call when a message has arrived
transport_hints a TransportHints structure which defines various transport-related options

其中的参数:
       topic 为订阅的节点名,字符串类型。
       queue_size 为待处理信息队列大小。
       fp 当消息传入时,可以调用的函数指针,即回调函数。

而其中M是回调函数的不同类型,例如const boost::shared_ptr& or const M&。这样的话,我们还可以使用boost::bind()调用回调函数。
但是,我们还会遇到subscribe()的第四个参数,例如

Subscriber ros::NodeHandle::subscribe    ( const std::string &   topic,
                          uint32_t     queue_size,
                          void(T::*)(M)     fp,
                          T *     obj,
                          const TransportHints &     transport_hints = TransportHints() 

Parameters:

M [template] M here is the message type
topic Topic to subscribe to
queue_size Number of incoming messages to queue up for processing (messages in excess of this queue capacity will be discarded).
fp Member function pointer to call when a message has arrived
obj Object to call fp on
transport_hints a TransportHints structure which defines various transport-related options

看上面原型要注意的是回调函数,应该是和第四个参数的在同一个类中,上面的例子是都在类T中,并且fp和obj都是指针类型 * 的。
解释下用法,第四个参数的T* obj是将类T的对象实例的指针传给同类的回调函数,void(T::*)(M) fp。因此在实例类obj中,如果改了一个变量的值,在回调函数中也能体现出来。这样,就相当于类中使用全局变量了。

返回函数在类中

当我们要使用一个Class里面的返回函数之后,我们需要调用第四个参数。例如我们有一个class:

class Listener
{
public:
  void callback(const std_msgs::String::ConstPtr& msg);
};

如果想要调用这个class里的返回函数,可以使用第四个参数,如下:
注意需要说明的是:在这里调用subscribe是在类外面

Listener listener;
ros::Subscriber sub = n.subscribe("chatter", 1000, &Listener::callback, &listener);

第四个参数定义的class,这样我们调用的就是Listener的callback函数。如果方法在class里面,可以使用this。如下:

class Listener
{
public:
  void callback(const std_msgs::String::ConstPtr& msg){}

  void TestObject(ros::NodeHandle n)
  {
    ros::Subscriber sub = n.subscribe("chatter", 1000, &Listener::callback, this);
  }

};

这样可以调用Class里的回调函数啦。

subscribe订阅多个参数

在实际中,如果想要给回调函数传参数可以用C++ 的boost库中的boost::bind() 函数,如:

image_transport::Subscriber sub = it.subscribe(topic_root + "/camera/image", 0, boost::bind(image_callback, _1, &pub_vt));

这里,boost::bind中的第一个参数是回调函数名
第二个 _1 是一个占位符,因为回调函数image_callback的第一个参数是msg,要给它留位置。
第三个,就是传的一个参数。以此扩展,如果想要传两个参数,这样:boost::bind(image_callback, _1, &pub_vt, &pub_odo),不要把_1当做参数个数。
然后在回调函数里面,这样用:
void image_callback(sensor_msgs::ImageConstPtr image, ros::Publisher * pub_vt)
就可以把参数写在第二个实参的位置
然后来说今天的重点,我学到的第四个参数的用法,先上示例:

参考资料
ROS::NodeHandle :
http://docs.ros.org/jade/api/roscpp/html/classros_1_1NodeHandle.html#a93b0fe95db250c45fdfbc5fd9f4c0159
Using Class Methods as Callbacks:
http://wiki.ros.org/roscpp_tutorials/Tutorials/UsingClassMethodsAsCallbacks
Using Class Methods as Callbacks issu:
https://answers.ros.org/question/207254/setting-class-method-callback-from-within-object-c/
第四个参数:
http://www.cnblogs.com/feixiao5566/p/4791990.html
subsribe的四个参数详解
http://t.zoukankan.com/TIANHUAHUA-p-8464149.html
Subscribe的第四个参数用法
https://www.cnblogs.com/feixiao5566/p/4791990.html

posted @ 2022-07-28 23:29  北极星!  阅读(4155)  评论(0编辑  收藏  举报