ros2/rosbag2

Feature request: rosbag2 reader that automatically detects if the bagfile is compressed or not

Rayman opened this issue · 6 comments

Description

At the moment there are two readers:

  1. rosbag2_cpp::Reader
  2. rosbag2_compression::SequentialCompressionReader

If I use the normal reader on a compressed message bagfile I get this error:

'rmw_serialize: invalid data size, at ./src/rmw_node.cpp:1910'

If I use the compression reader on an uncompressed bagfile I get this

  what():  SequentialCompressionReader should not be initialized with NONE compression mode.

So that means I need to pick which reader based on the compression used in the bagfile.
But the bagfile contains the compression used, so there could be a reader that figures this out automatically.

Related Issues

Completion Criteria

A single reader interface that can read both compressed and uncompressed rosbags.

Implementation Notes / Suggestions

Testing Notes / Suggestions

Hi @Rayman, There is the only one robust way to detect whether the bag is compressed or not is to look into the metadata.yaml file and see what is inside the compression_format field.
And we have already do this in the ReaderWriterFactory::make_reader(storage_options) api

namespace rosbag2_transport
{
std::unique_ptr<rosbag2_cpp::Reader> ReaderWriterFactory::make_reader(
const rosbag2_storage::StorageOptions & storage_options)
{
rosbag2_storage::MetadataIo metadata_io;
std::unique_ptr<rosbag2_cpp::reader_interfaces::BaseReaderInterface> reader_impl;
if (metadata_io.metadata_file_exists(storage_options.uri)) {
auto metadata = metadata_io.read_metadata(storage_options.uri);
if (!metadata.compression_format.empty()) {
reader_impl = std::make_unique<rosbag2_compression::SequentialCompressionReader>();
}
}
if (!reader_impl) {
reader_impl = std::make_unique<rosbag2_cpp::readers::SequentialReader>();
}
return std::make_unique<rosbag2_cpp::Reader>(std::move(reader_impl));
}

I would encourage you to use this factory method as well.

Ah nice, I was looking for something like that.

Is it a good idea to update the tutorials to make use of this API? I can open a PR for that

https://docs.ros.org/en/rolling/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-CPP.html
https://docs.ros.org/en/iron/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.html

Hmm, for recording, we also have a factory method for creating the Writer. However, it relies on the recorder options.
IMO, it will overcomplicate the tutorial.
Although for the https://docs.ros.org/en/iron/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.html it does make sense to show how to use factory method. I would appreciate a PR for that.

I've updated the documentation, so I'll close this issue

@Rayman Thanks for updating the documentation.
Now I think we need to consider moving the ReaderWriterFactory to the rosbag2_cpp layer.

Yes, it makes sense to have single Reader class that can be used in all circumstances (like in ROS1). And there could be an UncompressedReader and a CompressedReader underneath to do the actual work.