rosbag2

repository·rolling·Indexed 19 days ago

https://github.com/ros2/rosbag2

The ROS 2 successor to the original rosbag, providing tools for efficient recording and playback of timestamped communications. It features a plugin architecture for storage formats (e.g., mcap, sqlite3) and serialization formats (e.g., cdr). Key capabilities include splitting bag files by size or duration, compression via zstd, event-based recording using snapshot mode, and the ability to merge or convert bags using the `ros2 bag convert` tool.

Tokens
24.9K
Snippets
74
Records
103
Agent score
65%

What's inside rosbag2

  1. How storage format plugins work in Rosbag2

    rolling

    Rosbag2 uses a plugin architecture to support multiple storage formats (e.g., mcap, sqlite3). This allows the system to adapt to different use cases for how data is persisted to disk.

    • Default Storage: The default storage plugin is determined by rosbag2_storage::get_default_storage_id(). Currently, the default is mcap.
    • Specifying Storage: You can specify a non-default storage format using the --storage flag during recording or reading.
    • Automatic Detection: Bag reading commands typically detect the storage plugin automatically from the bag metadata, but you can force a specific plugin using the --storage option on any ros2 bag verb.
    $ ros2 bag record --storage <storage_id>
  2. Use Snapshot Mode for event-based recording

    rolling

    Snapshot mode (--snapshot-mode) avoids writing messages to disk immediately. Instead, it maintains an in-memory circular buffer bounded by --max-cache-size (bytes) and/or --max-cache-duration (seconds). The buffer is dumped to disk only when the ~/snapshot service is called.

    Buffering configurations:

    • Time-only: --max-cache-size 0 --max-cache-duration <seconds>
    • Size-only: --max-cache-size <bytes> --max-cache-duration 0
    • Both: Set both to positive values.

    Note: The cache uses double buffering; memory usage can reach up to 2 × --max-cache-size.

    # Snapshot mode, time-and-size bounded (keep last 10 seconds, max 50 MB)
    ros2 bag record -a --snapshot-mode --max-cache-size 50000000 --max-cache-duration 10
    
    # Trigger the snapshot via service
    ros2 service call /rosbag2_recorder/snapshot rosbag2_interfaces/srv/Snapshot
  3. Provide plugin-specific configuration via file

    rolling

    Storage plugins can accept custom configuration parameters via a file. Users can pass the path to this file using the --storage-config-file CLI argument.

    Rosbag2 passes the file path directly to the plugin. The plugin is responsible for defining and parsing the format of this file. It is recommended that plugins document their expected configuration format for users.

  4. Use `ros2idl` encoding for message definitions

    rolling

    The ros2idl encoding stores IDL (Interface Definition Language) definitions for a type and all its dependencies. Unlike ros2msg, definitions in ros2idl can be stored in any order.

    Structure: Every definition must be preceded by a two-line delimiter:

    • A line of exactly 80 = characters.
    • A line containing IDL: <package resource name> (e.g., IDL: my_msgs/msg/ComplexMsg). The space after IDL: is mandatory and the resource name must not include a file extension.

    This format relies on the OMG IDL 4.2 specification to ensure that bags recorded today remain parseable in the future without format migrations.

    ================================================================================
    IDL: my_msgs/msg/ComplexMsg
    #include "my_msgs/msg/BasicMsg.idl"
    
    module my_msgs {
      module msg {
        struct ComplexMsg {
          my_msgs::msg::BasicMsg my_basic_field;
        };
      };
    };
    ================================================================================
    IDL: my_msgs/msg/BasicMsg
    module my_msgs {
      module msg {
        struct BasicMsg {
          float my_float;
        };
      };
    };
  5. Use `ros2msg` encoding for message definitions

    rolling

    The ros2msg encoding uses human-readable .msg and .srv formats concatenated with a specific delimiter.

    Structure:

    1. The top-level message definition appears first (no delimiter).
    2. All dependent definitions follow, each preceded by a two-line delimiter:
      • A line of exactly 80 = characters.
      • A line containing MSG: <package resource name> (e.g., MSG: my_msgs/msg/BasicMsg). Note that the space after MSG: is mandatory and the resource name must not include a file extension.

    This format is used to ensure long-term parseability using well-known ROS 2 message specifications.

    # Top-level definition
    my_msgs/BasicMsg my_basic_field
    ================================================================================
    MSG: my_msgs/msg/BasicMsg
    # Dependent definition
    float32 my_float
  6. How converter plugins are selected at runtime

    rolling

    Rosbag2 automatically selects a converter plugin based on the storage format specified in the bagfile or by the user.

    To ensure your plugin is selected, the <class name> defined in your plugin_description.xml must follow the naming convention: <rmw storage format>_converter.

    For example, the default plugin for CDR (the general serialization format for DDS) is named cdr_converter.

  7. Understanding message loss statistics in rosbag2

    rolling

    By default, rosbag2 only logs message drops that occur within the writer itself (when the internal buffer is full). It does not natively track or report messages lost at the DDS transport layer.

    To address this, new design proposals aim to provide:

    1. Real-time monitoring: Accessing overall statistics (lost messages and bytes written per topic) via service requests, and receiving incremental statistics via a dedicated topic when losses occur.
    2. Post-processing metadata: Saving per-topic statistics (lost messages and bytes written) into the bag file's metadata upon completion of a recording.

    These features allow developers to assess recording quality and identify if data loss is happening due to transport issues (DDS) or writer bottlenecks.

  8. Understand the difference between ROS time and Steady time in rosbag2

    rolling

    When controlling playback time in rosbag2, the system manages two distinct time streams:

    1. ROS time: The time associated with the messages inside the bag. This time is subject to playback controls and can speed up, slow down, pause, or jump based on user actions or external time sources.
    2. Steady time: The real-world time experienced by the user. This time always moves forward at a constant, monotonic rate.

    To perform operations like now() -> ROSTime or sleep_until(ROSTime until), the PlayerClock performs conversions between these two timelines. Whenever a time control operation (like a rate change, pause, or jump) occurs, the system takes a "snapshot" of the current ROS time (R_ref) and Steady time (S_ref) to ensure all subsequent conversions remain accurate.

  9. How ROS 2 actions are structured in rosbag2

    rolling

    When recording an action, rosbag2 captures five related components to ensure full state reproduction:

    1. Goal Service: [NameSpace/]ActionName/_action/send_goal (and its service event topic .../_service_event)
    2. Result Service: [NameSpace/]ActionName/_action/get_result (and its service event topic .../_service_event)
    3. Cancel Service: [NameSpace/]ActionName/_action/cancel_goal (and its service event topic .../_service_event)
    4. Status Topic: [NameSpace/]ActionName/_action/status
    5. Feedback Topic: [NameSpace/]ActionName/_action/feedback
  10. Understand Rosbag2 playback time modes

    rolling

    Rosbag2 playback operates in three distinct time modes depending on how time is sourced and controlled:

    1. Steady Time (Default): Rosbag2 maintains its own internal time using a monotonic system clock. It neither publishes to nor subscribes to the /clock topic. This is used for standard real-time playback.
    2. Rosbag2 as ROS Time Source: Rosbag2 publishes to the /clock topic. This is enabled using the --clock option in ros2 bag play. This allows other nodes in the system to synchronize their time with the playback.
    3. External ROS Time Source: Rosbag2 is driven by an external source (e.g., a Gazebo simulator) by subscribing to the /clock topic. This is enabled using the --use-sim-time argument. In this mode, Rosbag2 is a passive consumer and cannot use internal time-control features like manual pausing or rate changes.

    Warning: Ensure there is only one publisher on /clock. Rosbag2 will print a warning if multiple publishers are detected, but it will not de-conflict them.

  11. Monitor messages lost events via topic

    rolling

    The Rosbag2 recorder publishes incremental statistics about lost messages on a dedicated topic whenever loss occurs. This allows for real-time monitoring of transport or recorder-side drops.

    • Topic: /events/rosbag2_messages_lost
    • Message Type: rosbag2_interfaces::msg::MessagesLostEvent

    Message Fields:

    • node_name (string): The name of the recording node.
    • topic_name (string): The name of the topic where loss occurred.
    • messages_lost_in_transport (uint64_t): Messages lost since the last event on the DDS transport layer.
    • messages_lost_in_recorder (uint64_t): Messages lost since the last event in the Rosbag2 recorder.

    Note: To avoid excessive resource usage, events are published no more frequently than the user-specified update rate. Topics with zero lost messages are not included in these events.