Use the SQLite3 storage plugin for rosbag2
rollingrosbag2_storage_sqlite3 plugin provides a storage backend for rosbag2 that uses SQLite3 .db3 files. It is used to record and play back ROS 2 data using the SQLite3 format.repository·rolling·Indexed 19 days ago
https://github.com/ros2/rosbag2The 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.
rosbag2_storage_sqlite3 plugin provides a storage backend for rosbag2 that uses SQLite3 .db3 files. It is used to record and play back ROS 2 data using the SQLite3 format.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.
rosbag2_storage::get_default_storage_id(). Currently, the default is mcap.--storage flag during recording or reading.--storage option on any ros2 bag verb.$ ros2 bag record --storage <storage_id>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:
--max-cache-size 0 --max-cache-duration <seconds>--max-cache-size <bytes> --max-cache-duration 0Note: 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/SnapshotStorage 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.
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:
= characters.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;
};
};
};The ros2msg encoding uses human-readable .msg and .srv formats concatenated with a specific delimiter.
Structure:
= characters.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_floatRosbag2 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.
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:
These features allow developers to assess recording quality and identify if data loss is happening due to transport issues (DDS) or writer bottlenecks.
When controlling playback time in rosbag2, the system manages two distinct time streams:
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.
When recording an action, rosbag2 captures five related components to ensure full state reproduction:
[NameSpace/]ActionName/_action/send_goal (and its service event topic .../_service_event)[NameSpace/]ActionName/_action/get_result (and its service event topic .../_service_event)[NameSpace/]ActionName/_action/cancel_goal (and its service event topic .../_service_event)[NameSpace/]ActionName/_action/status[NameSpace/]ActionName/_action/feedbackRosbag2 playback operates in three distinct time modes depending on how time is sourced and controlled:
/clock topic. This is used for standard real-time playback./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./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.
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.
/events/rosbag2_messages_lostrosbag2_interfaces::msg::MessagesLostEventMessage 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.