ROS:在nodehandle.subscribe

时间:2017-07-27 02:10:34

标签: 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)

我不能让这个工作,因为订阅需要一个函数指针。我试图用ROS做的事情是什么?也就是说,我可以将带有捕获的lambda传递给subscribe方法吗?

6 个答案:

答案 0 :(得分:4)

单线:

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

或者利用自动类型的显式多行代码,这可以使您免于回调的麻烦:

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

答案 1 :(得分:2)

在没有静态演员的情况下,问题中的部分解决方案似乎更清晰。

此代码工作正常(也适用于计时器,服务等):

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

答案 2 :(得分:2)

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

props

ROS版本:靛蓝
C ++ 14

答案 3 :(得分:1)

管理让lambdas工作。但是找不到捕捉的方法。相反,我作为参数传递了对象。

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))

答案 4 :(得分:0)

定义一个lambda,捕获所需的所有obj引用,并将消息my_msg包装在参数列表中。

auto lambda = [&obj](const ros::MessageEvent< my_msg const >& msg) {
    auto const_ref_msg = *(msg.getConstMessage().get());
    obj.callback(const_ref_msg);
};

auto sub = nh.subscribe< my_msg >("/my_msg", 1, lambda);

注意事项:

  • 该邮件必须用ros::MessageEvent包装。
    • 如果声明lambda接受(my_msg msg),则编译器会抱怨:“ no known conversion for argument 1 from ‘const boost::shared_ptr<const my_msg_<std::allocator<void> > >’ to ‘my_msg {aka my_msg_<std::allocator<void> >}’
  • 确保您拥有auto subAck =,以使订阅服务器保留在堆栈框架上。否则,编译器可能会优化后一部分mmNode.subscribe< my_msg >(my_msg::TOPIC, subscribeQueueSize, lambdaAck)

答案 5 :(得分:0)

我在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

由于它是唯一具有两个模板参数的重载,因此可以通过显式指定这些参数来强制实施。

具体询问的问题,添加订户将如下所示(C ++ 14):

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