【问题标题】:Error using boost::bind for subscribe callback使用 boost::bind 进行订阅回调时出错
【发布时间】:2017-07-25 17:03:23
【问题描述】:

我们收到此编译错误,随后出现更多错误,显示在使用 boost::bind 作为订阅回调时尝试将订阅参数与所有可能的候选函数匹配。

error: no matching function for call to ‘ros::NodeHandle::subscribe(const char [18], int, boost::_bi::bind_t<void, void (*)(const geometry_msgs::WrenchStamped_<std::allocator<void> >&, moveit::planning_interface::MoveGroup&), boost::_bi::list2<boost::arg<1>, boost::_bi::value<moveit::planning_interface::MoveGroup*> > >)’

我们的代码如下。注释行显示了在未传递 MoveGroup 上下文(对象指针)时工作的代码。

#include <stdio.h>
#include <boost/bind.hpp>
#include <geometry_msgs/WrenchStamped.h>
#include <moveit/move_group_interface/move_group.h>

using namespace Eigen;
using namespace std;

//void contact_callback(const geometry_msgs::WrenchStamped& msg) {
void contact_callback(const geometry_msgs::WrenchStamped& msg, moveit::planning_interface::MoveGroup &group){
    //if(msg.wrench.force.z > 5) group.stop();
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "get_stiffness");
    ros::NodeHandle node_handle; 
    ros::AsyncSpinner spinner(1);
    spinner.start();
    moveit::planning_interface::MoveGroup group("manipulator");
    ros::Subscriber contact_sub;
    //contact_sub = node_handle.subscribe("/finger1/nano17ft",1,contact_callback);
    contact_sub = node_handle.subscribe("/finger1/nano17ft",100,boost::bind(contact_callback,_1,&group));
    ros::waitForShutdown();
    return 0;
}

【问题讨论】:

  • 注意:C++ 标准提供std::bind 已经了。没有理由使用增强版。
  • @JesperJuhl 存在细微差别(表达式模板,例如否定谓词、绑定到成员函数的智能指针、boost::protect 等)
  • @sehe 好点。

标签: c++ boost ros boost-bind moveit


【解决方案1】:

处理程序接受一个 MoveGroup&,但您将地址传递给 group

改为使用ref(group):

boost::bind(contact_callback,_1,boost::ref(group))

或者,确实

std::bind(contact_callback,std::placeholders::_1,std::ref(group))

更新

您的回调不符合要求的签名:

void contact_callback(const geometry_msgs::WrenchStamped&, moveit::planning_interface::MoveGroup & group) {

必须

void contact_callback(const boost::shared_ptr<geometry_msgs::WrenchStamped const>, moveit::planning_interface::MoveGroup & group) {

在调用站点,您必须明确消息类型(它在不可推断的上下文中):

contact_sub = node_handle.subscribe<geometry_msgs::WrenchStamped>("/finger1/nano17ft", 100,
        boost::bind(contact_callback, _1, boost::ref(group)));

或者您可以简单地先明确地包装在 function&lt;&gt; 中:

boost::function<void(const boost::shared_ptr<geometry_msgs::WrenchStamped const>&)> callback =
    boost::bind(contact_callback, _1, boost::ref(group));
contact_sub = node_handle.subscribe("/finger1/nano17ft", 100, callback);

现场演示

所有 roscpp/Eigen 的东西都被剔除:

Live On Coliru

#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <iostream>

////////////////// STUBS STUBS STUBS //////
//#include <geometry_msgs/WrenchStamped.h>
namespace Eigen {}
namespace geometry_msgs {
struct WrenchStamped {}; }
namespace moveit { namespace planning_interface { struct MoveGroup { std::string name; MoveGroup(std::string s):name(s){} }; } }

namespace ros {
    void init(...) {}
    void waitForShutdown(...) {}
    struct Subscriber {};
    struct NodeHandle {
        using VoidConstPtr = void const *;
        enum class TransportHints {};
        template <typename M>
        Subscriber subscribe(const std::string &topic, uint32_t queue_size,
                const boost::function<void(const boost::shared_ptr<M const> &)> &callback,
                const VoidConstPtr &tracked_object = VoidConstPtr(),
                const TransportHints &transport_hints = TransportHints())
        { 
            (void)topic, (void)queue_size, void(tracked_object), void(transport_hints);
            callback({});
            return {};
        }
    };
    struct AsyncSpinner {
        AsyncSpinner(int) {}
        void start() {}
    };
};
//#include <moveit/move_group_interface/move_group.h>
////////////////// END STUBS END STUBS END STUBS //////

using namespace Eigen;

void contact_callback(const boost::shared_ptr<geometry_msgs::WrenchStamped const>, moveit::planning_interface::MoveGroup & group) {
    // if(msg.wrench.force.z > 5) group.stop();
    std::cout << "Invoked! " << group.name << "\n";
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "get_stiffness");
    ros::NodeHandle node_handle;
    ros::AsyncSpinner spinner(1);
    spinner.start();
    moveit::planning_interface::MoveGroup group("manipulator");
    ros::Subscriber contact_sub;

    contact_sub = node_handle.subscribe<geometry_msgs::WrenchStamped>("/finger1/nano17ft", 100,
            boost::bind(contact_callback, _1, boost::ref(group)));
    {
        boost::function<void(const boost::shared_ptr<geometry_msgs::WrenchStamped const>&)> callback =
            boost::bind(contact_callback, _1, boost::ref(group));
        contact_sub = node_handle.subscribe("/finger1/nano17ft", 100, callback);
    }
    ros::waitForShutdown();
}

打印

Invoked! manipulator
Invoked! manipulator

【讨论】:

  • 感谢您指出 @sehe 和 @JesperJuhl,我们现在收到此错误消息:error: no matching function for call to ‘ros::NodeHandle::subscribe(const char [18], int, boost::_bi::bind_t&lt;void, void (*)(const geometry_msgs::WrenchStamped_&lt;std::allocator&lt;void&gt; &gt;&amp;, moveit::planning_interface::MoveGroup&amp;), boost::_bi::list2&lt;boost::arg&lt;1&gt;, boost::reference_wrapper&lt;moveit::planning_interface::MoveGroup&gt; &gt; &gt;)’ 此处记录了订阅声明作为参考:docs.ros.org/indigo/api/roscpp/html/…
  • 好吧。下次,链接文档 :) 我目前没有安装任何东西,所以。用解决方案更新了我的答案。现场存根演示:coliru.stacked-crooked.com/a/9ad861abce3c8b60
  • 这太棒了!非常感谢您的帮助好心人:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多