ROS 2 Agent
The ros2-reduct-agent is a ROS 2 node that records selected topics as MCAP files and stores them in ReductStore.
Key features:
- Continuous recording of ROS 2 topics as MCAP files into ReductStore
- File rotation by duration or size to avoid large, hard-to-use files
- Topic grouping into separate pipelines, each writing its own file sequence
- Per-pipeline topic selection, compression, and chunking

System Requirementsβ
| Component | Version |
|---|---|
| ROS 2 | Jazzy Jalisco |
| OS | Ubuntu 24.04 (Noble) |
| Python | β₯ 3.12 |
Start a local ReductStore instance:
docker run -p 8383:8383 -v ${PWD}/data:/data reduct/store:latest
For more details on running ReductStore, see the Getting Started guide.
Installationβ
The ReductStore ROS 2 Agent can be installed using one of the following methods:
- Snap package (recommended) β production deployments and Ubuntu Core
- Build from source β development and debugging
Install via Snap (Recommended)β
This method is recommended for production deployments and Ubuntu Core systems.
# Install snapcraft if not already installed
sudo snap install snapcraft --classic
# Build the snap
snapcraft pack
# Install locally (for testing)
sudo snap install --dangerous reductstore-agent_*.snap
Or install directly from the store (edge channel for now):
sudo snap install reductstore-agent --edge
Build from Sourceβ
This installation method is intended for contributors and advanced users who want to modify or debug the agent. It is not required for normal operation.
## Clone into your ROS 2 workspace
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/reductstore/ros2-reduct-agent.git
cd ..
## Install dependencies and build
rosdep install --from-paths src --ignore-src -r -y
colcon build --packages-select ros2_reduct_agent
## Run with your config
source install/local_setup.bash
ros2 run ros2_reduct_agent recorder --ros-args --params-file ./config.yaml
Configuration Referenceβ
The agent is configured using a standard ROS 2 YAML file with two sections: storage and pipelines. For example:
/**/*:
ros__parameters:
storage: # local ReductStore instance
url: "http://localhost:8383"
api_token: "access_token"
bucket: "ros_data"
quota_type: "FIFO"
quota_size: "200GB"
pipelines:
telemetry:
filename_mode: "timestamp"
include_topics:
- "/camera/.*"
exclude_topics:
- "/camera/ignore"
static_labels:
source: telemetry
robot: alpha
split:
max_duration_s: 3600
max_size_bytes: 10000
downsample:
downsampling_mode: stride
stride_n: 5
Configuration overviewβ
The agent requires the following configuration sections to start:
storageβ specifies the ReductStore instance where data is written- Pipeline configuration β defines what data is recorded, provided either:
- locally via
pipelines, or - remotely via a configuration reference in
remote
- locally via
If any required configuration is missing, the agent will fail to start.
Storage Sectionβ
The storage section configures the connection to ReductStore.
| Parameter | Type | Description |
|---|---|---|
url | string | ReductStore endpoint (e.g., http://localhost:8383) (required) |
bucket | string | Target bucket (auto-created if missing) (required) |
api_token | string | API token with write permission |
Remote Config Sectionβ
The remote section specifies where the agent should fetch a pipeline
configuration YAML file from in a ReductStore instance.
It does not define pipelines itself.
| Parameter | Type | Description |
|---|---|---|
remote.url | string | Base URL of the ReductStore instance where the pipeline configuration is stored (required) |
remote.api_token | string | API token used to authenticate when accessing the remote configuration (required) |
remote.bucket | string | Bucket containing the pipeline configuration YAML file (required) |
remote.entry | string | Entry name under which the pipeline configuration YAML file is stored (required) |
remote.pull_frequency_s | int | Poll interval (in seconds) for reloading the remote configuration (default: 60) |
Notes
- Remote configuration is enabled only if all required parameters are provided.
- The referenced ReductStore entry must contain a YAML file.
- The YAML content must follow the same structure as the local
pipelinesconfiguration.
Remote configuration backupβ
When remote configuration is enabled, the agent automatically stores a local
backup of the fetched pipeline configuration as backup.yaml.
This backup is used as a fallback in the following cases:
- The agent restarts and the remote configuration is temporarily unavailable
- The remote configuration cannot be fetched at startup
- Periodic refresh fails while
remote.pull_frequency_sis enabled
If a valid backup.yaml is available, the agent will load the pipeline
configuration from the backup instead of failing immediately.
Pipeline Sectionβ
Each key under pipelines defines a separate recording pipeline, which results in a distinct entry in ReductStore. Each pipeline can be configured independently with its own topic filters, compression settings, and file-splitting behavior.
| Parameter | Type | Default | Description |
|---|---|---|---|
include_topics | string[] | β | List of ROS 2 topic names or regex patterns to record (required) |
exclude_topics | string[] | β | List of ROS 2 topic names or regex patterns to exclude |
filename_mode | enum | timestamp | File naming strategy: timestamp or incremental |
compression | enum | zstd | Compression algorithm: none, lz4, or zstd |
output_format | enum | mcap | Output format: mcap or cdr |
chunk_size_bytes | int | 1MB | Size of each MCAP chunk (1KBβ10MB) |
enable_crcs | bool | true | Append CRC checks to each chunk |
spool_max_size_bytes | int | 10MB | Maximum in-memory buffer before flushing (1KBβ1GB) |
split.max_duration_s | int | β | Split file after N seconds (1β3600) (required) |
split.max_size_bytes | int | β | Split file when size exceeds this limit (1KBβ1GB) |
downsample_mode | enum | none | Message downsampling mode: none, stride, max_rate |
downsample.stride_n | int | β | Record every Nth message. Must be n=>2 (required if stride) |
downsample.max_rate_hz | float | β | Maximum message frequency in Hz. Must be >0.0 (required if max_rate) |
static_labels | map | β | Static keyβvalue labels applied to all records |
labels.mode | enum | last | Dynamic label aggregation mode: last, first, or max |