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

Confusion about AsyncSpinner

asked 2016-03-07 12:51:24 -0500

sterlingm gravatar image

updated 2016-03-09 15:52:52 -0500

Hi, I am confused about the behavior of AsyncSpinner.

My understanding is that AsyncSpinner would allow a node to process several callbacks in parallel. I am trying to test this, but I do not see this behavior. I made two simple nodes to test this. A subscriber node will print a lot of output in the callback - enough to take a long time to finish. The node will receive another msg before finishing the first callback. When using ros::spin(), the callbacks will be entirely sequential. With AsyncSpinner, they should occur in parallel once the 2nd msg gets published.

Subscriber:

#include <iostream>
#include "ros/ros.h"
#include <std_msgs/String.h>

int count=0;
void myCallback(const std_msgs::String& str)
{
  count++;
  ros::Duration d(1);
  printf("\nSubscriber %i is going to sleep\n", count);
  d.sleep();
  printf("\nSubscriber %i is waking up\n", count);   
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "subscriber");
  ros::NodeHandle handle;

  ros::Subscriber sub = handle.subscribe("chatter", 1000, myCallback); 

  ros::AsyncSpinner spinner(4);
  spinner.start();
  ros::waitForShutdown();

  return 0;
}

I want to publish the second message before the subscribing node can finish the first callback to make them happen in parallel. So I publish 2 msgs at 0.5 seconds apart. 0.5 seconds is not enough time for the subscribing node to print 25,000 lines to the console.

Publisher:

#include <iostream>
#include "ros/ros.h"
#include <std_msgs/String.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "publisher");
  ros::NodeHandle handle;

  ros::Publisher pub = handle.advertise<std_msgs::String>("chatter", 1000);

  std_msgs::String s;
  ros::Duration d(0.25);
  for(int i=0;i<2;i++)
  {
    pub.publish(s);
    d.sleep();
  }
  return 0;
}

Edit: I changed the subscriber node to simply sleep for a duration as Jackie suggested. I would expect my output to be:

Subscriber 1 is going to sleep

Subscriber 2 is going to sleep

Subscriber 1 is waking up

Subscriber 2 is waking up

However, my output is always:

Subscriber 1 is going to sleep

Subscriber 1 is waking up

Subscriber 2 is going to sleep

Subscriber 2 is waking up

Note that the sleep time is 1 second and the publish time is 0.25 seconds. That ensures that the second msg will always be published while the first subscriber sleeps.

If anyone can help clear up my confusion about the purpose of AsyncSpinner, please do. I do not understand why I am not seeing my expected output.

edit retag flag offensive close merge delete

Comments

Can someone confirm that the expected output is correct? Is the AsyncSpinner meant to process several service requests in parallel or is it only to have a non-blocking spin call for the main thread?

sterlingm gravatar image sterlingm  ( 2016-03-11 14:08:07 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2016-03-07 15:11:54 -0500

jackie gravatar image

I don't think that your subscriptions callbacks are guaranteed to overlap. How did you choose 25,000 lines, and have you timed the callback to see if it actually takes longer than 0.5 seconds?

I would try rewriting your subscription callback as such:

void myCallback(const std_msgs::String& str)
{
  count++;
  ros::Duration d(0.6);
  printf("\nSubscriber %i is going to sleep\n", count);
  d.sleep();
 printf("\nSubscriber %i is waking up\n", count);
}

This way you know that the subscription callbacks are slower than your publish calls. You should then expect to see the subscription process print something like:

Subscriber 0 is going to sleep
Subscriber 1 is going to sleep
Subscriber 0 is waking up

etc...

edit flag offensive delete link more

Comments

I chose 25k because it's large enough to take longer than 0.5s to print out. But I think that sleeping is a better way to test this. I changed the callback to sleep for 1 second, but I get the same result - subscriber 0 wakes up before subscriber 1 goes to sleep. I edited my question to reflect this

sterlingm gravatar image sterlingm  ( 2016-03-07 15:30:22 -0500 )edit

Question Tools

4 followers

Stats

Asked: 2016-03-07 12:51:24 -0500

Seen: 5,647 times

Last updated: Mar 09 '16