ROS:在 nodehandle.subscribe 中使用 lambda 作为回调

jc2*_*211 8 c++ lambda ros

我希望能够通过 lambda 定义回调,但我无法获得任何匹配的函数签名。

std::function<void(const sensor_msgs::PointCloud2)> callback = 
 [&mycapture](const sensor_msgs::PointCloud2 msg) { 
 // do something with msg and capture
 };

auto sub = ros_node.subscribe("/sometopic", 1, callback)
Run Code Online (Sandbox Code Playgroud)

我无法让它工作,因为 subscribe 需要一个函数指针。我正在尝试用 ROS 做的事情可能吗?也就是说,我可以将一个带有捕获的 lambda 传递给 subscribe 方法吗?

Ant*_*sov 8

我在 Melodic 中也遇到了这个问题。虽然使用显式强制转换来提升函数的解决方案有效,但它非常冗长。在幕后,该解决方案归结为强制编译器选择node_handle::subscribe采用两个模板参数的最后一个重载:

   * \param M [template] the message type
   * \param C [template] the callback parameter type (e.g. const boost::shared_ptr<M const>& or const M&)

  template<class M, class C>
  Subscriber subscribe(const std::string& topic, uint32_t queue_size, const boost::function<void (C)>& callback
Run Code Online (Sandbox Code Playgroud)

因为它是唯一具有两个模板参数的重载,所以可以通过显式指定这些参数来强制执行。

根据所提问题的具体情况,添加订阅者将如下所示 (C++14):

ros::Subscriber subscriber = nh.subscribe<sensor_msgs::PointCloud2, const sensor_msgs::PointCloud2&>(topic, 1, [&mycapture](auto msg) {
    mycapture.workWith(msg.data);
  });
Run Code Online (Sandbox Code Playgroud)


Mar*_*cka 6

单线:

sensor_msgs::PointCloud2 pcl;
auto sub = nh.subscribe<sensor_msgs::PointCloud2>("scan", 1, [&](const sensor_msgs::PointCloud2ConstPtr& msg){pcl=*msg;});
Run Code Online (Sandbox Code Playgroud)

或者使用 auto 类型的显式多行,它可以为您节省大量的回调:

auto cb = [&](const sensor_msgs::PointCloud2ConstPtr& msg) {
  pcl=*msg;
};
auto sub = nh.subscribe<sensor_msgs::PointCloud2>("scan", 1, cb);
Run Code Online (Sandbox Code Playgroud)


Ros*_*oss 5

我能够通过捕获来实现这一点。

T obj;
boost::function<void (const sensor_msgs::PointCloud2&)> callback = 
    [obj] (const sensor_msgs::PointCloud2& msg) {
    // Do something here 
    }
auto sub = ros_nh.subscribe<sensor_msgs::PointCloud>(topic, 1, callback);
Run Code Online (Sandbox Code Playgroud)

ROS 版本:靛蓝
C++14


jc2*_*211 1

设法让 lambda 正常工作。但找不到捕捉的方法。相反,我将对象作为参数传入。

auto *callback = static_cast<void (*)(const sensor_msgs::PointCloud2::ConstPtr &, CustomObject&)>([](const sensor_msgs::PointCloud2::ConstPtr &msg, CustomObject &o) {
                                                    ROS_INFO_STREAM("Received: \n"<<msg->header);
                                                });

ros_node.subscribe<sensor_msgs::PointCloud2>(topic, 1, boost::bind(callback, _1, custom_object))
Run Code Online (Sandbox Code Playgroud)