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

The parameter arrangement of a simple done callback function for an action client

asked 2021-08-25 00:46:48 -0500

KhalidOwlWalid gravatar image

updated 2021-08-25 06:36:34 -0500

Mike Scheutzow gravatar image

What is really the difference between this:

void doneCallback(const ardrone_as::ArdroneResultConstPtr &result,
                      const actionlib::SimpleClientGoalState &state) {
      ROS_INFO("[State Result]: %s", state.toString().c_str());
      ROS_INFO("Done Callback called");
      ros::shutdown();
    }

and this?

 void doneCallback(const actionlib::SimpleClientGoalState &state,
                      const ardrone_as::ArdroneResultConstPtr &result) {
      ROS_INFO("[State Result]: %s", state.toString().c_str());
      ROS_INFO("The Action has been completed");
      ros::shutdown();
    }

I do notice the fact that the arrangement of the parameter for my doneCallback is different, but for the first doneCallback function, I am receiving this compiler error:

 error: invalid initialization of reference of type 'const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&' from expression of type 'const actionlib::SimpleClientGoalState'
  117 |           BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));

while the second one compiles just fine. I do not really understand the entire error message as it is a bit (maybe not a bit) too complicated for me to understand but what I do know is that I have issues with my const actionlib::SimpleClientGoalState. Can anyone explain to me why the arrangement matters?

Here is my whole code if you need it:

#include <actionlib/client/simple_action_client.h>
#include <ardrone_as/ArdroneAction.h>
#include <ros/ros.h>

// Compiler error
// void doneCallback(const ardrone_as::ArdroneResultConstPtr &result,
//                   const actionlib::SimpleClientGoalState &state) {
//   ROS_INFO("[State Result]: %s", state.toString().c_str());
//   ROS_INFO("Done Callback called");
//   ros::shutdown();
// }

int nImage = 0;

void doneCallback(const actionlib::SimpleClientGoalState &state,
                  const ardrone_as::ArdroneResultConstPtr &result) {
  ROS_INFO("[State Result]: %s", state.toString().c_str());
  ROS_INFO("The Action has been completed");
  ros::shutdown();
}

void activeCallback() { ROS_INFO("Active callback called"); }

void feedbackCallback(const ardrone_as::ArdroneFeedback::ConstPtr &feedback) {
  ROS_INFO("Feedback callback has been called");
}

int main(int argc, char **argv) {

  ros::init(argc, argv, "move_drone_node");

  actionlib::SimpleActionClient<ardrone_as::ArdroneAction> client(
      "ardrone_action_server", true);
  client.waitForServer();

  ardrone_as::ArdroneGoal goal;
  goal.nseconds = 10;

  client.sendGoal(goal, &doneCallback, &activeCallback, &feedbackCallback);

  ros::Rate loop_rate(2);
  actionlib::SimpleClientGoalState state_result = client.getState();

  while (state_result == actionlib::SimpleClientGoalState::ACTIVE ||
         state_result == actionlib::SimpleClientGoalState::PENDING) {
    ROS_INFO("Doing something");
    loop_rate.sleep();
    state_result = client.getState();
  }

  return 0;
}

This is the error if I use the first callback function:

T0, T1>::invoke(boost::detail::function::function_buffer&, T0, T1) [with FunctionPtr = void (*)(const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&, const actionlib::SimpleClientGoalState&); R = void; T0 = const actionlib::SimpleClientGoalState&; T1 = const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&]':
/usr/include/boost/function/function_template.hpp:931:38:   required from 'void boost::function2<R, T1, T2>::assign_to(Functor) [with Functor = void (*)(const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&, const actionlib::SimpleClientGoalState&); R = void; T0 =const actionlib::SimpleClientGoalState&; T1 = const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&]'
/usr/include/boost/function/function_template.hpp:720:7:   required from 'boost::function2<R, T1, T2>::function2(Functor, typename boost::enable_if_<(! boost::is_integral<T>::value), int>::type) [with Functor = void (*)(const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&, const actionlib::SimpleClientGoalState&); R = void; T0 = const actionlib::SimpleClientGoalState&; T1 = const boost::shared_ptr<const ardrone_as::ArdroneResult_<std::allocator<void> > >&; typename boost::enable_if_<(! boost::is_integral<T>::value), int>::type = int]'
/usr/include/boost/function/function_template.hpp:1068:16:   required from 'boost::function<R(T0, T1)>::function(Functor, typename boost::enable_if_<(! boost::is_integral<T>::value), int> ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-08-25 06:29:23 -0500

Mike Scheutzow gravatar image

updated 2021-08-25 06:30:20 -0500

The ArdoneAction class has defined what arguments it will pass to the callback function. Your code has to have the same argument types, and in the exact same order. The compiler checks this, and it complains if the function you provided does not match the function that ArdoneAction wants.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2021-08-25 00:46:48 -0500

Seen: 167 times

Last updated: Aug 25 '21