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

Revision history [back]

In addition what abacas said about using a global pointer, you can also use boost::bind to to pass additional parameters to your callback.

#include <boost/bind.hpp>

void joyCallback(ros::NodeHandle &node_handle, const std_msgs::String::ConstPtr& msg) {
...
}

...

int main(int argc, char *argv[]) {
...
  ros::Subscriber sub = n.subscribe<std_msgs::String>("joy_vel_output", 10000,
      boost::bind(&joyCallback, boost::ref(n), _1));
...
}

Note: the boost::ref is necessary because we want to pass a reference to the node handle, not a copy.

A few important notes on your code: passing a NodeHandle to the subscriber callback to read parameters is fine. Using it for creating publishers might be a problem because publishers take a while until all network connections to the subscribers are up. That can have the effect that nothing reaches the subscribers because the publisher is shut down at the end of the subscription callback, before the subscribers connected. The same holds for a TransformBroadcaster.

I'm not aware of any case where running an infinite loop inside a callback is a good idea. The problem is that callbacks are run from the thread that called spin. Now, if the callback blocks the spin loop is blocked, too. That will break ROS communication until the spin thread runs again.

I believe, in your case you actually want to have a few globals (or even better, put eveything in a class), e.g the transform you want to publish. In the callback, you just set the current transform. In the main function, you then have your loop that always publishes the current tf and calls ros::spinOnce.