c++rosros2rosbag

ROS2 reading bag files


I have got a bag file in db3 format and I was trying to read its messages, deserialise them and access their fields. I couldn't find any appropriate document or working example anywhere. I only managed to load the file and display all its message types using the rosbag2_cpp API as follows:

#include <rclcpp/rclcpp.hpp>
#include <tf2_msgs/msg/tf_message.hpp>
#include <ament_index_cpp/get_package_share_directory.hpp>
#include <rosbag2_cpp/readers/sequential_reader.hpp>
#include <rosbag2_cpp/converter_interfaces/serialization_format_converter.hpp>
#include <rosbag2_storage/storage_options.hpp>


int main(int argc, char** argv)
{
    (void) argc;
    (void) argv;

    rclcpp::init(argc, argv);

    rclcpp::Node node("test");

    rosbag2_storage::StorageOptions storage_options{};
    
    auto file_path = ament_index_cpp::get_package_share_directory("test")
        + "/data/rosbag_autoware_receiver_0.db3";
    storage_options.uri = file_path;
    storage_options.storage_id = "sqlite3";

    rosbag2_cpp::ConverterOptions converter_options{};
    converter_options.input_serialization_format = "cdr";
    converter_options.output_serialization_format = "cdr";

    rosbag2_cpp::readers::SequentialReader reader;
    reader.open(storage_options, converter_options);

    const auto topics = reader.get_all_topics_and_types();

    for (const auto topic : topics)
        RCLCPP_INFO(node.get_logger(), topic.name.c_str());

    return 0;
}

Any hint, help or guide on reading the actual messages and deserialising them is much appreciated.

Regards


Solution

  • What you're looking for is the has_next() property. Declare a msg variable of the type(s) you're looking for (such as sensor_msgs::msg::Image msg), and deserialize as following:

    while (reader.has_next())
    {
        // serialized data
        auto serialized_message = reader.read_next();
        rclcpp::SerializedMessage extracted_serialized_msg(*serialized_message->serialized_data);
        auto topic = serialized_message->topic_name;
        if (topic.find("whatever...") != std::string::npos)
        {
            serialization_info.deserialize_message(&extracted_serialized_msg, &msg);
        }
    }