This adds support for replaying multiple bags with ros2 bag play and the underlying classes (rosbag2_transport::Player/rosbag2_py::Player).
To replay multiple bags:
$ ros2 bag play -i bag1 -i bag2 -i bag3 [storage_id]
Messages are played in order, based on their recv_timestamp (recorder reception timestamp). rosbag2_transport::Player uses a simple implementation of a priority queue to select the "next" message from all input bags. This does assume that the messages in each bag are ordered by recv_timestamp.
Note that the priority queue implementation does require locking, but the "ordering" it does is very simple given the aforementioned ordering assumption. However, I did make it consider the trivial case where there's only 1 underlying queue (i.e., input bag), in which case there is no need to track priorities and thus no need for locking. Furthermore, this priority queue does not support actually ordering messages, e.g., to re-order an input bag's messages by send_timestamp.
Other notes:
Like ros2 bag convert, I added the -i, --input option that takes a bag URI and an optional explicit storage ID. This option can be used multiple times for multiple bags.
I kept the bag_path positional argument (but made it optional) because it is quite nice to be able to just do ros2 bag play my-bag. However, I deprecated the storage ID option (--storage); users will have to use -i, --input to specify an explicit storage ID for an input bag.
I had to change some APIs (mainly constructors) to support N input bags. I was planning to deprecate constructors that only take 1 input bag/storage options, but given the number of layers/classes involved, it became too annoying. We can consider deprecating some of them in another PR.
I did break rosbag2_transport::Player::get_storage_options() to make it return a std::vector<rosbag2_storage::StorageOptions>. This is apparently only used in tests. I also broke rosbag2_py::Player::play_impl(), but it apparently only protected (and not private) for testing purposes.
This adds support for replaying multiple bags with
ros2 bag play
and the underlying classes (rosbag2_transport::Player
/rosbag2_py::Player
).To replay multiple bags:
Messages are played in order, based on their
recv_timestamp
(recorder reception timestamp).rosbag2_transport::Player
uses a simple implementation of a priority queue to select the "next" message from all input bags. This does assume that the messages in each bag are ordered byrecv_timestamp
.Note that the priority queue implementation does require locking, but the "ordering" it does is very simple given the aforementioned ordering assumption. However, I did make it consider the trivial case where there's only 1 underlying queue (i.e., input bag), in which case there is no need to track priorities and thus no need for locking. Furthermore, this priority queue does not support actually ordering messages, e.g., to re-order an input bag's messages by
send_timestamp
.Other notes:
ros2 bag convert
, I added the-i, --input
option that takes a bag URI and an optional explicit storage ID. This option can be used multiple times for multiple bags.bag_path
positional argument (but made it optional) because it is quite nice to be able to just doros2 bag play my-bag
. However, I deprecated the storage ID option (--storage
); users will have to use-i, --input
to specify an explicit storage ID for an input bag.rosbag2_transport::Player::get_storage_options()
to make it return astd::vector<rosbag2_storage::StorageOptions>
. This is apparently only used in tests. I also brokerosbag2_py::Player::play_impl()
, but it apparently onlyprotected
(and notprivate
) for testing purposes.