在ROS中,想在回调函数中发布消息,有两个思路:
(1)把函数写成类的形式,把需要的一些变量在类中声明为全局变量。【推荐,模块化好】
(2)在函数中,把回调函数需要调用的变量声明为全局变量。也可以解决这个问题。【不好,不符合面向对象的风格】
#include <ros/ros.h>
class SubscribeAndPublish
{
public:
SubscribeAndPublish()
{
//Topic you want to publish
pub_ = n_.advertise<PUBLISHED_MESSAGE_TYPE>("/published_topic", 1);
//Topic you want to subscribe
sub_ = n_.subscribe("/subscribed_topic", 1, &SubscribeAndPublish::callback, this); //注意这里,和平时使用回调函数不一样了。
}
void callback(const SUBSCRIBED_MESSAGE_TYPE& input)
{
PUBLISHED_MESSAGE_TYPE output;
//.... do something with the input and generate the output...
pub_.publish(output);
}
private:
ros::NodeHandle n_;
ros::Publisher pub_;
ros::Subscriber sub_;
}//End of class SubscribeAndPublish
int main(int argc, char **argv)
{
//Initiate ROS
ros::init(argc, argv, "subscribe_and_publish");
//Create an object of class SubscribeAndPublish that will take care of everything
SubscribeAndPublish SAPObject;
ros::spin();
return 0;
}
sub_ = n_.subscribe("/subscribed_topic", 1, &SubscribeAndPublish::callback, this);
注意这句,回调函数的使用方法之一。
第四个参数我们之所以用this,是因为第四个参数是一个指向【回调函数所在对象】的指针,官方文档例子里把sub定义在了类外面,我们把sub定义在了类的构造函数里面,所以this就是在实例化对象的时候指向对象的指针。(关于this:当调用成员函数a.volume 时,编译系统就把对象a的起始地址赋给this指针;构造函数:建立对象时自动执行。结合两者,在本例中建立类对象时,自动生成指向本对象的指针。)