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

spin with threads

asked 2013-07-05 12:55:47 -0600

Verane gravatar image

updated 2013-07-05 23:37:08 -0600

Hi. I'm having problems with spin and multiples subscriptions. I want to subscribe to two topic and going on with my program. Something like:

X_callback(){something};
Y_callback(){something};


int main(){
thread(subscribe to topic X with callback X_callback)
thread(subscribe to topic Y_callback)
more things to do...
}

I don't know what to do with spin() if I've threads. I've used Multithread spin but doesn't work. Doing something like:

MultiThreadSping s(4);

X_callback(){s.spin()};
Y_callback(){s.spin()};

int main(){
some code
}

EDIT. This was my first idea:

void alivesCallback(const std_msgs::String::ConstPtr &msg){
    //control new connection
}

void temperatureCallback(const std_msgs::String::ConstPtr &msg){
    temperature = msg->data;
}


void subscriptionAliveTopic(){
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("alive", 1000, alivesCallback);
    ros::spin();
}


void subscriptionTemperatureTopic(){
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("temperature", 1000, temperatureCallback);
    ros::spin();
}


int main(){

    boos::thread t1(boost::bind(subscriptionAliveTopic));
    boos::thread t2(boost::bind(subscriptionTemperatureTopic));

    //more things to do
}
edit retag flag offensive close merge delete

Comments

Can you clarify your question a bit? Do you just want to subscribe to two topics? Is there a reason that you need threads, other than for the subscriptions?

Bill Smart gravatar image Bill Smart  ( 2013-07-05 13:12:02 -0600 )edit

Each thread is the subscription and the spin. I'm using threads beacuse I'm trying not to block the main program.

Verane gravatar image Verane  ( 2013-07-05 13:14:36 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
2

answered 2013-07-05 16:01:35 -0600

updated 2013-07-06 05:04:47 -0600

The easiest way to do what you're looking for is to call spinOnce in a loop. This is non-blocking, and allows you to do other operations in "parallel" with the callback processing. Note that this is not truly parallel, since this is a single-threaded model, but many applications are fine without truly multi-threaded operations.

See here for more discussion of various spinning methods.

Try something like this:

my_callback(){something};

int main(){
  sub = node.subscribe("topic", &my_callback);

  ros::Rate r(10); // 10 hz
  while (ros::ok())
  {
    do_callback_independent_processing();

    if (new_callback_data)
      do_callback_dependent_processing();

    ros::spinOnce();
    r.sleep();
  }
}

Edit:
If you don't like the idea of calling spinOnce in a loop, then probably the next-best choice is to use ASyncSpinner. Trying to use multiple threads and multiple calls to ros::spin() is messy, and probably won't work. ros::spin explicitly states that it is designed for single-threaded nodes only.

edit flag offensive delete link more
2

answered 2013-07-05 13:20:13 -0600

Bill Smart gravatar image

The subscriptions don't block the control flow in main(), so you don't need to put them in threads. All that they do is to register the callback with the callback manager (which will not fire then until you run spin()). So, the following should work

int main() {
  // These will not block.
  subscribe to topic X with callback X_callback
  subscribe to topic Y with callback Y_callback

  [other stuff]

  spin();
}
edit flag offensive delete link more

Comments

But below spin() I need to do more things. So if I put sping() and then some code, spin() would block it.

Verane gravatar image Verane  ( 2013-07-05 13:22:19 -0600 )edit

Below spin() I need to use the data obtained in the callbacks.

Verane gravatar image Verane  ( 2013-07-05 13:28:47 -0600 )edit

Is it possible to make the subscription to the two topics, then run a thread with spin() and continuing with the main execution?

Verane gravatar image Verane  ( 2013-07-05 13:37:28 -0600 )edit
1

ROS is inherently callback-driven, making what you describe a bit awkward. Can you put the code that needs to use the data from the callbacks in the callbacks themselves, or have it called from there? I might help to know what sort of things you want to do after the spin.

Bill Smart gravatar image Bill Smart  ( 2013-07-05 13:45:36 -0600 )edit

Edited my first comment.

Verane gravatar image Verane  ( 2013-07-05 23:37:45 -0600 )edit
0

answered 2013-07-07 02:09:17 -0600

noonv gravatar image

may be use spin in main() and over work in threads?

example

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-07-05 12:55:47 -0600

Seen: 1,088 times

Last updated: Jul 07 '13