ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

error in using boost::bind to pass parameter

asked 2018-05-23 11:16:13 -0500

ewjtx gravatar image

I'm new to ros and boost programming. From ros wiki and google, I know I can use boost::bind to transfer parameter to callback function. So I try to use it build a service server with parameter. But I keep meeting mismatching problem. When I try to find answer in ros community, I only find answers about subscriber. So i pose this question.

the code of bare function:

bool control_test(bebop_test::ControlSrv::Request &req, bebop_test::ControlSrv::Response &res, bebop_command *bebop_cmd){/**/}

code in main:

ros::ServiceServer bebop_server = nh.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2, &bebop_cmd) );

and the error:

>  Errors     << bebop_test:make
> /home/simon/parrot_ws/logs/bebop_test/build.make.008.log /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:
> In function ‘int main(int, char**)’:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> error: no matching function for call
> to
> ‘ros::NodeHandle::advertiseService(const
> char [10], boost::_bi::bind_t<bool,
> bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> >
> >)’
>      ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
>                                                                                                                                   ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
>                  from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:879:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool (T::*)(MReq&, MRes&),
> T*)    ServiceServer
> advertiseService(const std::string&
> service, bool(T::*srv_func)(MReq &,
> MRes &), T *obj)
>                  ^ /opt/ros/kinetic/include/ros/node_handle.h:879:17:
> note:   template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note:   mismatched types ‘bool
> (T::*)(MReq&, MRes&)’ and
> ‘boost::_bi::bind_t<bool, bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
>      ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
>                                                                                                                                   ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
>                  from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1:
> /opt/ros/kinetic/include/ros/node_handle.h:924:17:
> note: candidate: template<class T,
> class MReq, class MRes>
> ros::ServiceServer
> ros::NodeHandle::advertiseService(const
> string&, bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&), T*)    ServiceServer
> advertiseService(const std::string&
> service,
> bool(T::*srv_func)(ServiceEvent<MReq,
> MRes>&), T *obj)
>                  ^ /opt/ros/kinetic/include/ros/node_handle.h:924:17:
> note:   template argument
> deduction/substitution failed:
> /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:49:130:
> note:   mismatched types ‘bool
> (T::*)(ros::ServiceEvent<MReq,
> MRes>&)’ and ‘boost::_bi::bind_t<bool,
> bool
> (*)(bebop_test::ControlSrvRequest_<std::allocator<void>
> >&, bebop_test::ControlSrvResponse_<std::allocator<void>
> >&, bebop_command*), boost::_bi::list3<boost::arg<1>,
> boost::arg<2>,
> boost::_bi::value<bebop_command*> > >’
>      ros::ServiceServer bebop_server = bebop_cmd.nh_.advertiseService("bebop_srv", boost::bind(&control_test, _1, _2,
> &bebop_cmd) );
>                                                                                                                                   ^ In file included from
> /opt/ros/kinetic/include/ros/ros.h:45:0,
>                  from /home/simon/parrot_ws/src/bebop_test/src/bebop_server_re.cpp:1 ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
2

answered 2018-05-24 08:18:53 -0500

lucasw gravatar image

updated 2018-05-24 08:19:40 -0500

The template argument deduction fails for advertiseService when using boost::bind (see https://answers.ros.org/question/2335... ), so you need to be more explicit:

#include <ros/ros.h>
#include <std_srvs/SetBool.h>

bool test(std_srvs::SetBool::Request& req, std_srvs::SetBool::Response& resp)
{
  return true;
}

bool test2(std_srvs::SetBool::Request& req, std_srvs::SetBool::Response& resp,
    bool toggle)
{
  return true;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "node");
  ros::NodeHandle nh;
  // works without template parameters
  ros::ServiceServer service0 = nh.advertiseService("my_service0", test);
  // compile error: no matching function for call to ‘ros::NodeHandle::advertiseService...

  // ros::ServiceServer service1 = nh.advertiseService("my_service1",
  //    boost::bind(&test2, _1, _2, false));
  ros::ServiceServer service2 = nh.advertiseService<std_srvs::SetBool::Request,
      std_srvs::SetBool::Response>("my_service2",
      boost::bind(&test2, _1, _2, true));
  ros::spin();
  return 0;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-05-23 11:16:13 -0500

Seen: 892 times

Last updated: May 24 '18