ROS:在nodehandle.subscribe中使用lambda作为回调
ROS: Use lambda as callback in nodehandle.subscribe
我希望能够通过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 传递到订阅方法中吗?
单行:
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);
我在旋律中也遇到了这个问题。虽然具有显式强制转换以增强功能的解决方案有效,但它非常冗长。在后台,此解决方案归结为强制编译器选择需要两个模板参数的最后一个重载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);
});
我能够通过捕获来解决这个问题。
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);
ROS版本:靛蓝
C++14
问题中的部分解决方案似乎更干净一些,没有静态转换。
此代码工作正常(也适用于计时器、服务等(:
boost::function<void (const sensor_msgs::PointCloud2&, CustomObject&)> callback =
[] (const sensor_msgs::PointCloud2& msg, CustomObject& obj) {
// do something with msg and obj
}
ros::Subscriber = ros_nh.subscribe(topic, 1, boost::bind(callback, _1, obj));
设法让 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))
定义一个 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> >}’
- 如果 lambda 被声明接受
- 确保您具有
auto subAck =
,以便订阅服务器保留在堆栈帧上。否则编译器可能会优化后半部分mmNode.subscribe< my_msg >(my_msg::TOPIC, subscribeQueueSize, lambdaAck)
。
相关文章:
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 使用带有闭包的 lambda 的回调
- 通过实用程序 fn 将捕获的 lambda 传递给 C 样式回调 - 错误
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 如何成功地将函数对象(或lambda)传递给trackbar回调的第二个参数(void*)
- ROS:在nodehandle.subscribe中使用lambda作为回调
- 如何定义与将 Lambda 与捕获作为回调一起使用兼容的函数指针
- lambda回调中Android Cocos2D-X应用程序上的SEG故障
- 在库中的 C++17 中强制内联回调 (lambda)
- 如何使用C lambda将成员功能指针转换为普通功能指针,以用作回调
- std::函数,带有 SDL 事件回调的 lambda 错误
- 将lambda传递到lambda回调参数
- C lambda/回调弹出窗口
- C lambda回调为触发事件
- 允许 lambda/回调函数的多个签名作为模板参数
- 读取 Lambda 回调后的访问冲突
- 如何避免在调用异步函数进行 lambda 回调时出现额外的副本
- C++ VS 2013 中的 11 lambda 回调无法编译
- 不带Y Combinator的递归lambda回调
- 透明地配置std::function / lambda回调