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

Doubt in callbacks.

asked 2013-10-02 20:48:48 -0600

Sphenops gravatar image

updated 2013-10-04 00:58:39 -0600

As per my understanding, in a single threaded spinning the Subscriber waits for seeing a message and after seeing, puts it in the callback queue and simultaneously the ros::spin processes the callbacks sequentially in the queue. For example if only a Kinect callback(CBK) is there, then the queueing will be as follows: CBK1 || CBK2 || CBK3 || ... and so on. And these will be processed one at a time by ros::spin(). Am I right?

Provided that the above understanding is right, if we have multiple callbacks. For example one callback for a kinect data(CBK) and one for a laser data(CBL) and since the messages from laser are received faster than kinect, we would have a queueing somewhat similar to : CBL1 ||CBL2 ||CBL3 ||CBK1 ||CBL4 ||CBL5 ||CBL6 ||CBK2 ||CBL7 ||CBL8 ||CBL9 ||CBK3 ||CBL10 || ... and so on. Does ros::spin(), process this as well in the same manner as above?

Can someone help me debug why I am not able to use the customized queues? The following are my two callbacks:

  MainThread::MainThread(ros::NodeHandle& nh) : nh(nh)
  {
      this->sub_person_data = this->nh.subscribe("/persondetector/person_data", 1,   &MainThread::personDetectCallback, this);
      this->sub_laser_person_data = this->nh.subscribe("/laserpersondetector/person_data", 1, &MainThread::personDetectLaserCallback, this);
  }

Callback Definition:

   void MainThread::personDetectCallback(persondetector_kinect::PersonData data)
   {
       if(kinect_data_cb_queue.isEnabled())
       {
           std::cout<< "Kinect Data received "<<std::endl;
           kinect_data_cb_queue.callAvailable();
           this->personData_ = data;
           if(kinect_data_cb_queue.isEmpty())
              std::cout<<"The kinect data queue is empty"<<std::endl;
           else
              std::cout<<"The kinect data queue is used now"<<std::endl;
        }
   }

   void MainThread::personDetectLaserCallback(persondetector_kinect::PersonData data)
   {
      nh.setCallbackQueue(&laser_data_cb_queue);
      if(laser_data_cb_queue.isEnabled())
      {
         std::cout<< "Laser Data received "<<std::endl;
         this->laserPersonData_ = data;
         laser_data_cb_queue.callAvailable();
      }
   }

Now, in the main I make use of the multi-threaded spinner:

 int main (int argc, char** argv)
 {
     // Initialize ROS
     ros::init (argc, argv, "simple_tracker");
     ros::NodeHandle nh("~");
     // Declaration of kinect and laser data call back queue
     ros::CallbackQueue kinect_data_cb_queue;
     ros::CallbackQueue laser_data_cb_queue;
     simpletracker::MainThread main(nh);
     nh.setCallbackQueue(&(main.kinect_data_cb_queue));
/*ros::MultiThreadedSpinner laser_callback_queue_spinner(2);
  laser_callback_queue_spinner.spin(&(main.laser_data_cb_queue));*/

/*ros::AsyncSpinner kinect_callback_queue_spinner(0, &(main.kinect_data_cb_queue));
       kinect_callback_queue_spinner.start();*/

      main.work();
      ros::MultiThreadedSpinner kinect_callback_queue_spinner(1);
      kinect_callback_queue_spinner.spin(&(main.kinect_data_cb_queue));
      ros::spin();
      return 0;
}

Even if the rosbag is running and the messages are available, it says "The kinect data queue is empty"

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2013-10-03 00:20:21 -0600

Thomas gravatar image

There is no guarantee regarding the order in which the callbacks are called AFAIK and you should not make any assumption on this. Beside, all callbacks will use the same callback queue so it will be more likely:

LASER1 | LASER2 | LASER3 | KINECT1 | LASER4 | LASER5 | KINECT 2 | LASER6 | etc.
edit flag offensive delete link more

Comments

Thank you for your reply, Thomas. By what you say I understand that the callback may be queued depending on the order of the received messages. Right? Coming to the processing when the ros::spin is called how are these callbacks processed? Is it sequential or parallel?

Sphenops gravatar image Sphenops  ( 2013-10-03 00:34:13 -0600 )edit

See for instance my answer here: http://answers.ros.org/question/53055/ros-callbacks-threads-and-spinning/ It may or it may not. What you happen to see is the simplified interface the tutorials introduce and which are enough usually. But classes are modular and this will break your expectations ;)

Thomas gravatar image Thomas  ( 2013-10-03 05:30:25 -0600 )edit

Thanks a lot for the inputs Thomas. The discussion in the link was really very useful :-)

Sphenops gravatar image Sphenops  ( 2013-10-03 17:31:12 -0600 )edit

Does ROS allow to use multiple queues in a single node apart from the global queue and use all of them at the same time?

Sphenops gravatar image Sphenops  ( 2013-10-03 17:51:41 -0600 )edit

Yes, this is the goal of the complete API. You will have to create also additional spinners to handle the extra queues.

Thomas gravatar image Thomas  ( 2013-10-03 23:08:45 -0600 )edit

Question Tools

Stats

Asked: 2013-10-02 20:48:48 -0600

Seen: 361 times

Last updated: Oct 04 '13