Ask Your Question

How to invoke callback functions sequentially [closed]

asked 2015-01-03 03:54:47 -0500

pronik gravatar image

updated 2015-01-03 04:01:39 -0500

This is how my main looks like:

ros::NodeHandle n1; 
ros::NodeHandle n2;

image_transport::ImageTransport it(n1);
image_transport::ImageTransport it1(n2);

image_transport::Subscriber sub1 = it1.subscribe("camera/rgb/image_color", 1, imageCallback);
image_transport::Subscriber sub2 = it.subscribe("camera/depth/image", 1, depthCallback);

ros::Rate r(10);


I need to first invoke imageCallback and use data it generates in depthCallback function. But ros::spinOnce() calls them in a random order. How do I call them sequentially, in the order listed, first imageCallback then depthCallback?

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by pronik
close date 2015-01-04 14:10:46.740095

2 Answers

Sort by » oldest newest most voted

answered 2015-01-03 10:43:00 -0500

kramer gravatar image

Technically, I don't think the callbacks are actually random; rather, they occur in the order in which messages are received...even though that may appear to be random. I mention that because it indicates a fundamental misunderstanding of the mechanism: you do not call the callbacks, the callbacks are event-driven, ordered by message reception.

With that said, you want to impose some kind of message reception synchronization. Perhaps something in the message_filters package will do? Specifically, it seems to me that ApproximateTime would work for you.

If not, off the top of my head, a simple solution would be to use the callbacks to store message values then call a common method. The common method short-circuits unless both message values are filled, otherwise processing the stored values in the order you specify.

It's important to note that the callback mechanism already imposes per-message synchronization (unless you're multi-threading); that is, only one callback executes at any time, and does so to completion. So implementation is straightforward -- you can simply have a boolean flag for each message type, only performing full processing when both are true.

One final (unrelated) point: you do not need two NodeHandle objects, as they are reference-counted copies of a global object. See NodeHandle Overview or, for more detail, the NodeHandle API (specifically the default constructor).

edit flag offensive delete link more


Thanks for the tip. I used callbacks to store message values and then calling a common method. It worked.

pronik gravatar image pronik  ( 2015-01-03 10:47:35 -0500 )edit

You're welcome, glad you figured it out. If you think the answer is adequate, please accept it and close the question.

kramer gravatar image kramer  ( 2015-01-03 10:56:50 -0500 )edit

answered 2015-01-03 10:06:25 -0500

gvdhoorn gravatar image

You could consider using message_filters - Time Synchronizer for this. You wouldn't be using two callbacks, but I think you actually want to process synchronised pairs of rgb and depth images, am I right?

edit flag offensive delete link more


No. My doubt was in general but message filters could be a way to do this. Thanks.

pronik gravatar image pronik  ( 2015-01-03 11:03:38 -0500 )edit

Question Tools



Asked: 2015-01-03 03:54:47 -0500

Seen: 1,333 times

Last updated: Jan 03 '15