Building the ROS message synchronizer I need

To do this, I had to learn about the ROS message_filters and rosbag APIs.

For my purposes, I need to synchronize messages coming from three topics: sensor_msgs/Image from /cam0/image_raw, sensor_msgs/Image from /cam1/image_raw, and sensor_msgs/Imu from /imu0. The two Images should arrive synchronized: if there are \(n\) images from /cam0/image_raw, then there should be \(n \pm 1\) images from /cam1/image_raw (due to earlier startup/shutdown). The systems behavior is different in the first \(t_\mathrm{init}\) time since the initial message came in, as it’s an initialization phase.

Most of the times, you’d work with a ROS bag; a container for ROS messages that can be used to replay them over their ROS topics. When you have a ROS bag, you can use it in two ways:

I have decided to use the message_filters API, as it offers some synchronization functionality to build on. I’ve made a SynchroBuffer class that encapsulates everything that needs to be done: a message_filters::Subscriber for each of the three topics; message_filters::Synchronizer<sync_pol> sync that synchronizes all three; and callbacks registered on sync and on the Subscriber of the IMU topic. The IMU callback logs the messages to a std::deque, and calls SynchroBuffer::process_data(). sync’s callback stores all three data members, and also calls SynchroBuffer::process_data().

SynchroBuffer::process_data() checks if sync’s most recent IMU message also occurs in the std::deque of stored IMU data (it might be that either callback is behind a little bit on the other). If so, call the right ORB_SLAM2::System tracking function. An example can be found in this file; it’s a work-in-progress as it segfaults at this stage, but the structure should be clear.