0
$\begingroup$

Rosanswers logo

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"


Originally posted by Sphenops on ROS Answers with karma: 5 on 2013-10-02

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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.

Originally posted by Thomas with karma: 4478 on 2013-10-03

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by Sphenops on 2013-10-03:
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?

Comment by Thomas on 2013-10-03:
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 ;)

Comment by Sphenops on 2013-10-03:
Thanks a lot for the inputs Thomas. The discussion in the link was really very useful :-)

Comment by Sphenops on 2013-10-03:
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?

Comment by Thomas on 2013-10-03:
Yes, this is the goal of the complete API. You will have to create also additional spinners to handle the extra queues.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.