Post-processing analysis engine for ROS2 rosbag data
Project description
bagx
A readiness checker for recorded ROS2 bags.
bagx answers a practical question: can this bag be used for SLAM, navigation, perception, manipulation, Autoware validation, or your custom robot stack?
pip install bagx
bagx eval your_bag.db3
bagx checks topic presence, rates, gaps, sensor sync, approximate pipeline latency, workflow outcomes, and domain-specific readiness signals:
- SLAM readiness: IMU noise, GNSS quality, LiDAR↔IMU sync, and whether LIO is a bad idea
- Navigation/control readiness: odom / scan / costmap rates, goal observability, and
plan → cmd_vellatency - Workflow outcome visibility: action/service success rate, terminal failures, and top failure reasons when those topics are recorded
- Perception dataset readiness: RGB / depth / infra rates, camera calibration presence, and reusable export structure
- Manipulation readiness: joint-state rate, planner visibility, and
planned_path → arm executionlatency - Custom stack support: user-defined rules on topic names/types/rates/latencies for custom messages, loaded from files or plugins
- Repeatability: manifest-driven benchmark suites you can rerun across public and private bags
What bagx answers
When a rosbag is not for SLAM, the value is usually one of these:
- "Can I trust this bag for navigation debugging?" →
bagx evalchecks odom, scan, costmap, plan, and control-loop timing - "Did my Autoware recording include the sensing and vehicle topics I actually need?" → bagx verifies camera, LiDAR, GNSS,
/vehicle/status/*, and whether planning/control topics are present - "Is this RGB-D bag usable for perception work, or did I forget camera_info / depth / infra?" → bagx flags stream rates, calibration topics, and RGB-D coverage
- "Did MoveIt record just planning, or also execution?" → bagx checks
joint_states, action topics, and controller activity - "We use custom messages, can bagx still help?" →
bagx eval --rules warehouse_botor--rules rules.jsonadds custom domains and checks without needing message decode - "Which of these bags should become my regression benchmark?" →
bagx benchmarkandbagx batch evalmake that repeatable
Example: catching a real problem
$ bagx eval ouster_os0-32.db3
Overall Score: 76.6/100
Recommendations:
✔ IMU accel noise 0.087 m/s² — good for LIO, set imu_acc_noise_density to 0.087
⚠ IMU gyro noise 0.022 rad/s — consider lowering IMU integration weight
⚠ IMU rate 50Hz is low — 200Hz+ recommended for tightly-coupled LIO
⚠ LiDAR↔IMU sync delay 23ms — enable per-point deskew in SLAM
Without bagx, you'd discover these issues after hours of failed SLAM runs.
For non-SLAM bags, the same workflow answers different questions:
$ bagx eval nav2_robot.db3
Recommendations:
Nav2 topics detected
✔ Odometry (/robot/odom) at 50Hz — good for Nav2
✔ LaserScan (/robot/scan) at 12Hz — good for costmap
✔ Pipeline plan → cmd_vel onset: 11ms median, 76ms P95 (3 samples)
$ bagx eval r2b_galileo2
Recommendations:
Perception topics detected
✔ Depth image (/camera/realsense_splitter_node/output/depth) at 30Hz — good for RGB-D perception
✔ Infra stereo streams are both recorded — depth debugging is possible
✔ Camera calibration topics are recorded — exported perception data is reusable
Install
pip install bagx
Works without ROS2 — reads .db3 files directly via SQLite.
Commands
| Command | One-liner |
|---|---|
bagx eval bag.db3 |
Is this bag ready? Auto-detects SLAM / Nav2 / Autoware / MoveIt / Perception / Control |
bagx compare A.db3 B.db3 |
Which sensor config is better? |
bagx sync bag.db3 /imu /lidar |
Are my sensors synchronized? |
bagx anomaly bag.db3 |
Where did sensor quality drop? |
bagx scenario bag.db3 |
Find GNSS-lost and high-dynamics segments |
bagx export bag.db3 --ai |
Export to Parquet/JSON for ML |
bagx batch eval *.db3 --csv |
Rank an entire dataset |
bagx ask bag.db3 "question" |
Ask questions via LLM |
bagx benchmark suite.json |
Re-run a curated benchmark suite and fail CI on regressions |
bagx eval bag.db3 --rules rules.json |
Apply custom topic/type/rate/latency rules for your stack |
bagx eval bag.db3 --badge badge.json |
Emit a shields.io readiness badge you can show in a README |
bagx rules list |
List discoverable built-in and installed custom-rule plugins |
Representative results
| Dataset | Domain | Score | What bagx tells you |
|---|---|---|---|
| Newer College | SLAM | 92 | LiDAR+IMU quality is strong enough for SLAM benchmarking |
| Ouster OS0-32 | SLAM | 77 | IMU is too slow and sync is weak, so deskew / sensor changes are needed |
driving_20_kmh_2022_06_10-16_01_55_compressed |
Autoware sensing/control | 99 | LiDAR packets and /vehicle/status/velocity_status are present and healthy |
r2b_galileo |
Multi-camera perception | 90.5 | Eight compressed camera streams, IMU, and chassis odom are recorded and time-aligned |
r2b_whitetunnel |
Multi-camera perception | 91.3 | Eight compressed camera streams plus IMU are recorded; bagx flags noisy accel and still validates perception coverage |
r2b_galileo2 |
Camera perception | 97.5 | RGB-D + infra + camera_info are all recorded, so the bag is reusable for perception work |
r2b_robotarm |
Manipulation perception | 96.0 | RGB-D + joint_states make it suitable for robot-arm perception benchmarking |
nav2-deep-final-20260324-185315 |
Navigation/control | 100 | Nav2 plan, costmap, and plan → cmd_vel loop are all observable |
moveit-exec-final-20260324-185315 |
Motion planning/control | 100 | MoveIt planning and arm execution are both recorded end-to-end |
Auto-detects your framework
bagx recognizes topic patterns and gives framework-specific advice:
Namespaced topics are supported too, so real bags like /robot/odom,
/sensing/lidar/top/pointcloud_raw_ex, or /move_group/display_planned_path
are detected without renaming topics first.
$ bagx eval nav2_robot.db3
Nav2 topics detected
✔ Odometry (/robot/odom) at 50Hz — good for Nav2
✔ LaserScan (/robot/scan) at 12Hz — good for costmap
✔ Global plan (/plan) recorded 3 times — planner output is visible
✔ NavigateToPose status (/navigate_to_pose/_action/status) recorded
✔ Pipeline scan → cmd_vel (full loop): 41ms median, 81ms P95
✔ Pipeline plan → cmd_vel onset: 11ms median, 76ms P95 (3 samples)
$ bagx eval autoware_vehicle.db3
Autoware topics detected
✔ LiDAR (/sensing/lidar/top/pointcloud_raw_ex) at 10Hz
✔ Camera (/sensing/camera/front/image_raw/compressed) at 30Hz
✔ GNSS (/sensing/gnss/ublox/nav_sat_fix)
ℹ Sensing/localization-only Autoware bag — skipping planning/control checks
$ bagx eval moveit_arm.db3
MoveIt topics detected
✔ JointState (/joint_states) at 115Hz — good for motion planning
✔ MoveGroup action activity recorded on /move_action/_action/status
✔ Joint trajectory controller activity recorded on /panda_arm_controller/follow_joint_trajectory/_action/status
✔ Pipeline joint_states → planned_path: 6ms median, 6ms P95 (1 sample)
✔ Pipeline planned_path → arm execution: 5ms median, 5ms P95 (1 sample)
$ bagx eval r2b_galileo2
Perception topics detected
✔ RGB image (/camera/color/image_raw) at 15Hz — good for camera-based perception
✔ Depth image (/camera/realsense_splitter_node/output/depth) at 30Hz — good for RGB-D perception
✔ Infra stereo streams are both recorded — depth debugging is possible
✔ Camera calibration topics are recorded — exported perception data is reusable
$ bagx eval control_loop.db3
Planning/control topics detected
✔ State feedback (/base/state/odom) at 25Hz — good for closed-loop control
✔ Control command (/drive/cmd_vel) at 20Hz — good for control-loop observability
✔ Planner output (/planner/path) recorded 6 times — upstream planning is visible
✔ Pipeline planner → command onset: 15ms median, 15ms P95
✔ Action result (/mission/result): 8/8 results succeeded
✔ Service responses (/planner/compute_path/_service_event): 8/8 requests have responses
$ bagx rules list
warehouse_bot builtin:warehouse_bot Wheel odom + controller command + mission path/result checks...
$ bagx eval warehouse_bag.db3 --rules warehouse_bot
WarehouseBot custom rules matched
✔ Wheel odometry (/warehouse_bot/wheel_odom) at 50Hz — custom rule satisfied
✔ Controller command (/warehouse_bot/controller_cmd) at 25Hz — custom rule satisfied
✔ Mission result (/warehouse_bot/mission/result) recorded — custom rule matched
✔ Pipeline mission path → controller: 10ms median, 10ms P95
Dogfooding
bagx is dogfooded against:
- Autoware real bags, including the official
all-sensors-bag4dataset from the Autoware documentation datasets page - Nav2 simulator bags captured with
scripts/run_ros_dogfood.py nav2-gazebo - MoveIt simulator bags captured with
scripts/run_ros_dogfood.py moveit-demo
Recent dogfood runs:
nav2-deep-final-20260324-185315:Overall 100.0/100,LaserScan 13Hz,plan → cmd_vel onset 11ms medianmoveit-exec-final-20260324-185315:Overall 100.0/100,JointState 115Hz,planned_path → arm execution 5ms medianautoware_isuzu_all_sensors_bag4: real bag,Overall 72.2/100, plus a sensing-only note when planning/control topics are absentdriving_20_kmh_2022_06_10-16_01_55_compressed: official Autoware open-data bag,Overall 99.0/100, LiDAR packet sync and/vehicle/status/velocity_statuscapturedr2b_galileo: official NVIDIA open-data MCAP,Overall 90.5/100, eight compressed camera streams plus IMU and chassis odomr2b_whitetunnel: official NVIDIA open-data MCAP,Overall 91.3/100, eight compressed camera streams plus IMU and camera calibration coverager2b_robotarm: official NVIDIA open-data MCAP,Overall 96.0/100, RGB-D + joint-state manipulation perception checksr2b_galileo2: official NVIDIA open-data MCAP,Overall 95.3/100, camera-only RGB-D perception checks without SLAM-specific false advice
Benchmark suites
bagx now supports manifest-driven benchmark suites so public bags can become repeatable regression tests instead of one-off dogfood runs.
The repository includes benchmarks/open_data_suite.json, which covers:
- Autoware official
all-sensors-bag4 - Autoware official
driving_20_kmh_2022_06_10-16_01_55_compressed - NVIDIA official
r2b_robotarm - NVIDIA official
r2b_galileo - NVIDIA official
r2b_whitetunnel - NVIDIA official
r2b_galileo2
It also includes benchmarks/non_slam_suite.json, which focuses on non-SLAM value:
- NVIDIA official
r2b_galileo2camera-only perception - NVIDIA official
r2b_whitetunnelmulti-camera perception - NVIDIA official
r2b_robotarmmanipulation perception - Local Nav2 dogfood bags under
.cache/dogfood/ - Local MoveIt dogfood bags under
.cache/dogfood/
Typical usage:
export BAGX_REALBAGS=/tmp/bagx_realbags
bagx benchmark benchmarks/open_data_suite.json
bagx benchmark benchmarks/open_data_suite.json --json benchmark-report.json
bagx benchmark benchmarks/non_slam_suite.json
bagx rules list
bagx eval my_custom_stack.db3 --rules warehouse_bot
JSON outputs now include schema_version, report_type, bagx_version, and structured
findings, so they are easier to gate in CI and compare across releases without depending
on human-facing recommendation text.
Readiness badge
Turn any eval into a README badge with --badge:
bagx eval my_bag.db3 --badge bag-badge.json
This writes a shields.io endpoint payload:
{ "schemaVersion": 1, "label": "Nav2 readiness", "message": "76.6/100", "color": "green" }
Host the file (raw GitHub, GitHub Pages, an artifact store) and reference it:

The label folds in the detected stack (e.g. Nav2 readiness); override it with
--badge-label. The colour tracks the composite score — green when a bag is fit
for its declared stack, red when it is not — so the badge tells the whole story at
a glance.
Typical local workflow:
# Assumes the ROS overlay is already installed at .cache/ros_overlay_nav2_test
python3 scripts/run_ros_dogfood.py nav2-gazebo \
--duration 40 \
--record-dir .cache/dogfood/nav2-deep-final
bagx eval .cache/dogfood/nav2-deep-final
python3 scripts/run_ros_dogfood.py moveit-demo \
--duration 40 \
--record-dir .cache/dogfood/moveit-exec-final
bagx eval .cache/dogfood/moveit-exec-final
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bagx-0.4.0.tar.gz.
File metadata
- Download URL: bagx-0.4.0.tar.gz
- Upload date:
- Size: 140.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e86413129b91869fb8f5fc9550cca1d847f54bb1608dfb523c957282d3ae244f
|
|
| MD5 |
fef91c33c9cfe3764470b036ab067e10
|
|
| BLAKE2b-256 |
1db4d85c955cec77ea70dae82b03493aff166fa365e2d4c71dd547baf59757d4
|
Provenance
The following attestation bundles were made for bagx-0.4.0.tar.gz:
Publisher:
publish.yml on rsasaki0109/bagx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bagx-0.4.0.tar.gz -
Subject digest:
e86413129b91869fb8f5fc9550cca1d847f54bb1608dfb523c957282d3ae244f - Sigstore transparency entry: 1774014487
- Sigstore integration time:
-
Permalink:
rsasaki0109/bagx@63b7abaf61a81245805f3cced2eedd81402daded -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/rsasaki0109
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@63b7abaf61a81245805f3cced2eedd81402daded -
Trigger Event:
push
-
Statement type:
File details
Details for the file bagx-0.4.0-py3-none-any.whl.
File metadata
- Download URL: bagx-0.4.0-py3-none-any.whl
- Upload date:
- Size: 98.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55767b81cb5d490f75f6d504406e8c5a43305c2bf3743ee2c0a3768775f3b02a
|
|
| MD5 |
0d3c792d9d5b6121f3ee5d8751b14375
|
|
| BLAKE2b-256 |
6b424ee72f6f742603b93d389470e3a0d8ead1b1773b2d321b1c698c817a9518
|
Provenance
The following attestation bundles were made for bagx-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on rsasaki0109/bagx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bagx-0.4.0-py3-none-any.whl -
Subject digest:
55767b81cb5d490f75f6d504406e8c5a43305c2bf3743ee2c0a3768775f3b02a - Sigstore transparency entry: 1774014596
- Sigstore integration time:
-
Permalink:
rsasaki0109/bagx@63b7abaf61a81245805f3cced2eedd81402daded -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/rsasaki0109
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@63b7abaf61a81245805f3cced2eedd81402daded -
Trigger Event:
push
-
Statement type: