bagx 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bagx-0.1.0/LICENSE +21 -0
- bagx-0.1.0/PKG-INFO +590 -0
- bagx-0.1.0/README.md +554 -0
- bagx-0.1.0/bagx/__init__.py +3 -0
- bagx-0.1.0/bagx/anomaly.py +359 -0
- bagx-0.1.0/bagx/ask.py +182 -0
- bagx-0.1.0/bagx/batch.py +202 -0
- bagx-0.1.0/bagx/cli.py +406 -0
- bagx-0.1.0/bagx/compare.py +190 -0
- bagx-0.1.0/bagx/eval.py +501 -0
- bagx-0.1.0/bagx/export.py +204 -0
- bagx-0.1.0/bagx/py.typed +0 -0
- bagx-0.1.0/bagx/reader.py +813 -0
- bagx-0.1.0/bagx/scenario.py +429 -0
- bagx-0.1.0/bagx/scene.py +437 -0
- bagx-0.1.0/bagx/schema.py +75 -0
- bagx-0.1.0/bagx/sync.py +215 -0
- bagx-0.1.0/bagx.egg-info/PKG-INFO +590 -0
- bagx-0.1.0/bagx.egg-info/SOURCES.txt +42 -0
- bagx-0.1.0/bagx.egg-info/dependency_links.txt +1 -0
- bagx-0.1.0/bagx.egg-info/entry_points.txt +2 -0
- bagx-0.1.0/bagx.egg-info/requires.txt +21 -0
- bagx-0.1.0/bagx.egg-info/top_level.txt +1 -0
- bagx-0.1.0/pyproject.toml +75 -0
- bagx-0.1.0/setup.cfg +4 -0
- bagx-0.1.0/tests/test_anomaly.py +189 -0
- bagx-0.1.0/tests/test_ask.py +158 -0
- bagx-0.1.0/tests/test_batch.py +181 -0
- bagx-0.1.0/tests/test_cdr_parsers.py +258 -0
- bagx-0.1.0/tests/test_cli.py +96 -0
- bagx-0.1.0/tests/test_compare.py +63 -0
- bagx-0.1.0/tests/test_edge_cases.py +517 -0
- bagx-0.1.0/tests/test_endianness.py +177 -0
- bagx-0.1.0/tests/test_eval.py +158 -0
- bagx-0.1.0/tests/test_export.py +122 -0
- bagx-0.1.0/tests/test_logging.py +77 -0
- bagx-0.1.0/tests/test_mcap.py +285 -0
- bagx-0.1.0/tests/test_multi_segment.py +198 -0
- bagx-0.1.0/tests/test_reader.py +92 -0
- bagx-0.1.0/tests/test_readme_examples.py +377 -0
- bagx-0.1.0/tests/test_scenario.py +235 -0
- bagx-0.1.0/tests/test_scene.py +270 -0
- bagx-0.1.0/tests/test_schema.py +79 -0
- bagx-0.1.0/tests/test_sync.py +76 -0
bagx-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 bagx contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bagx-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: bagx
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Post-processing analysis engine for ROS2 rosbag data
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/rsasaki0109/bagx
|
|
7
|
+
Project-URL: Repository, https://github.com/rsasaki0109/bagx
|
|
8
|
+
Project-URL: Issues, https://github.com/rsasaki0109/bagx/issues
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: typer>=0.9.0
|
|
20
|
+
Requires-Dist: rich>=13.0.0
|
|
21
|
+
Requires-Dist: numpy>=1.24.0
|
|
22
|
+
Requires-Dist: pandas>=2.0.0
|
|
23
|
+
Requires-Dist: pyarrow>=14.0.0
|
|
24
|
+
Provides-Extra: ros
|
|
25
|
+
Requires-Dist: rosbag2_py; extra == "ros"
|
|
26
|
+
Provides-Extra: mcap
|
|
27
|
+
Requires-Dist: mcap>=1.0.0; extra == "mcap"
|
|
28
|
+
Requires-Dist: mcap-ros2-support>=0.5.0; extra == "mcap"
|
|
29
|
+
Provides-Extra: llm
|
|
30
|
+
Requires-Dist: anthropic>=0.30.0; extra == "llm"
|
|
31
|
+
Requires-Dist: openai>=1.30.0; extra == "llm"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# bagx
|
|
38
|
+
|
|
39
|
+
Post-processing analysis engine for ROS2 rosbag data.
|
|
40
|
+
|
|
41
|
+
> **bagx is not a replacement for ros2 bag.**
|
|
42
|
+
> ros2 bag handles recording & playback (I/O). bagx handles evaluation, understanding & comparison (Analysis).
|
|
43
|
+
|
|
44
|
+
## What can you do with bagx?
|
|
45
|
+
|
|
46
|
+
**Before a test drive** — check sensor readiness:
|
|
47
|
+
```bash
|
|
48
|
+
bagx eval pre_drive.db3
|
|
49
|
+
# → GNSS fix rate 98%, HDOP 1.2, IMU 200Hz, Score: 87/100 ✓
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**After a test drive** — compare two runs:
|
|
53
|
+
```bash
|
|
54
|
+
bagx compare run_A.db3 run_B.db3
|
|
55
|
+
# → GNSS Fix Rate: A=95% B=72% (degraded)
|
|
56
|
+
# → IMU Noise: A=0.04 B=0.03 (improved)
|
|
57
|
+
# → Winner: A
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Debugging sensor issues** — find anomalies:
|
|
61
|
+
```bash
|
|
62
|
+
bagx anomaly recording.db3
|
|
63
|
+
# → [12.3s] /gnss: position_jump (47.2m, severity: high)
|
|
64
|
+
# → [45.1s] /imu: accel_spike (23.4 m/s², severity: high)
|
|
65
|
+
# → [78.9s] /lidar: rate_gap (850ms, severity: medium)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Checking time sync** — are sensors synchronized?
|
|
69
|
+
```bash
|
|
70
|
+
bagx sync recording.db3 /camera /lidar
|
|
71
|
+
# → Mean: 3.2ms | Max: 12.1ms | P95: 8.4ms | Outliers: 0.2%
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Extracting dangerous scenes** — for safety review:
|
|
75
|
+
```bash
|
|
76
|
+
bagx scenario recording.db3
|
|
77
|
+
# → [10.5s–14.2s] gnss_lost (3.7s, severity: high)
|
|
78
|
+
# → [32.1s–32.8s] high_dynamics (brake, 18.3 m/s²)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Preparing data for ML** — export to Parquet:
|
|
82
|
+
```bash
|
|
83
|
+
bagx export recording.db3 --ai --format parquet
|
|
84
|
+
# → gnss.parquet (142 KB), imu.parquet (891 KB), lidar.parquet (2.3 MB)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Asking questions in plain English**:
|
|
88
|
+
```bash
|
|
89
|
+
bagx ask recording.db3 "Is this bag suitable for SLAM evaluation?"
|
|
90
|
+
# → The bag contains LiDAR at 10Hz and IMU at 200Hz with good sync (3ms).
|
|
91
|
+
# GNSS fix rate is 95%. Suitable for outdoor SLAM evaluation.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Batch evaluation** — score an entire dataset:
|
|
95
|
+
```bash
|
|
96
|
+
bagx batch eval ./recordings/*.db3 --csv summary.csv
|
|
97
|
+
# → 12 bags evaluated, scores: 34–91, mean: 72.4
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Real-world evaluation results
|
|
101
|
+
|
|
102
|
+
Evaluated on public LiDAR SLAM datasets to demonstrate what bagx can tell you about your data.
|
|
103
|
+
|
|
104
|
+
### Batch scoring across datasets
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
$ bagx batch eval ./slam_datasets/
|
|
108
|
+
|
|
109
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━┓
|
|
110
|
+
┃ Bag ┃ Duration (s) ┃ Messages ┃ GNSS ┃ IMU ┃ Sync ┃ Overall ┃
|
|
111
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━┩
|
|
112
|
+
│ Livox MID-360 │ 277.2 │ 58,217 │ N/A │ 97.3 │ 70.0 │ 83.7 │
|
|
113
|
+
│ Ouster OS0-32 │ 47.3 │ 5,208 │ N/A │ 79.6 │ 73.6 │ 76.6 │
|
|
114
|
+
│ Newer College (handheld) │ 193.0 │ 225,758 │ N/A │ 84.5 │ 100.0 │ 92.3 │
|
|
115
|
+
│ NTU VIRAL (drone) │ 583.6 │ 1,248,476 │ 80.0 │ 59.5 │ 100.0 │ 79.8 │
|
|
116
|
+
└──────────────────────────┴──────────────┴───────────┴──────┴───────┴───────┴─────────┘
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**What this tells you:**
|
|
120
|
+
|
|
121
|
+
- **Newer College** scores highest (92.3) — excellent sensor sync across 4 cameras + 2 IMUs + LiDAR, low IMU noise. Ideal for LiDAR SLAM.
|
|
122
|
+
- **Livox MID-360** has the best IMU (97.3) but 25ms sync delay between IMU and LiDAR — tightly-coupled SLAM should compensate for this latency.
|
|
123
|
+
- **NTU VIRAL** has perfect GNSS (100% fix) and sync, but IMU scores lower (59.5) due to noisier drone-mounted sensors.
|
|
124
|
+
- **Ouster OS0-32** internal IMU is usable (79.6) but not great — consider adding an external IMU for better SLAM performance.
|
|
125
|
+
|
|
126
|
+
### Detailed evaluation (NTU VIRAL drone dataset)
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
$ bagx eval ntu_viral_tnp_01.db3
|
|
130
|
+
|
|
131
|
+
Duration: 583.6s | Messages: 1,248,476 | Topics: 19
|
|
132
|
+
|
|
133
|
+
GNSS Quality
|
|
134
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
|
|
135
|
+
┃ Metric ┃ Value ┃
|
|
136
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
|
|
137
|
+
│ Messages │ 28975 │
|
|
138
|
+
│ Fix Rate │ 100.0% │
|
|
139
|
+
│ Altitude (mean±std) │ 76.5±2.4 │
|
|
140
|
+
│ Score │ 80.0/100 │
|
|
141
|
+
└───────────────────────┴────────────┘
|
|
142
|
+
IMU Quality
|
|
143
|
+
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
144
|
+
┃ Metric ┃ Value ┃
|
|
145
|
+
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
|
|
146
|
+
│ Messages │ 225142 │
|
|
147
|
+
│ Accel Noise (xyz) │ 0.3049, 0.3180, 0.6054 │
|
|
148
|
+
│ Gyro Noise (xyz) │ 0.009956, 0.014712, 0.004014 │
|
|
149
|
+
│ Accel Bias Stability │ 0.0321 │
|
|
150
|
+
│ Score │ 59.5/100 │
|
|
151
|
+
└──────────────────────┴──────────────────────────────┘
|
|
152
|
+
Topic Sync Quality
|
|
153
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┓
|
|
154
|
+
┃ Topic Pair ┃ Mean (ms) ┃ Max (ms) ┃
|
|
155
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━┩
|
|
156
|
+
│ /dji_sdk/imu ↔ /imu/imu │ 1.3 │ 21.9 │
|
|
157
|
+
│ /dji_sdk/gps_position ↔ /dji_sdk/imu │ 1.6 │ 31.5 │
|
|
158
|
+
│ Score │ 100.0/100 │ │
|
|
159
|
+
└────────────────────────────────────────────┴───────────┴──────────┘
|
|
160
|
+
|
|
161
|
+
Overall Score: 79.8/100
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Cross-IMU sync analysis
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
$ bagx sync ntu_viral.db3 /dji_sdk/imu /os1_cloud_node1/imu
|
|
168
|
+
|
|
169
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
|
|
170
|
+
┃ Topic Pair ┃ Count ┃ Mean ms ┃ Max ms ┃ P95 ms ┃ Outlier ┃
|
|
171
|
+
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩
|
|
172
|
+
│ /dji_sdk/imu ↔ /os1_cloud_node1/imu │ 231793 │ 2.50 │ 10.14 │ 4.75 │ 0.0% │
|
|
173
|
+
└──────────────────────────────────────┴────────┴─────────┴─────────┴─────────┴─────────┘
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
→ DJI onboard IMU and Ouster LiDAR IMU are synchronized within 2.5ms on average, with zero outliers. Suitable for multi-IMU fusion.
|
|
177
|
+
|
|
178
|
+
### Datasets used
|
|
179
|
+
|
|
180
|
+
- [NTU VIRAL](https://ntu-aris.github.io/ntu_viral_dataset/) — Drone with GNSS, 4 IMUs, 2 LiDARs, cameras, UWB
|
|
181
|
+
- [Newer College Dataset](https://ori-drs.github.io/newer-college-dataset/) — Handheld with Ouster LiDAR, Alphasense cameras + IMU
|
|
182
|
+
- [glim](https://koide3.github.io/glim/) — Indoor/outdoor with Livox MID-360
|
|
183
|
+
- [Koide LiDAR-Camera Calibration](https://koide3.github.io/direct_visual_lidar_calibration/) — Static calibration bags with Livox
|
|
184
|
+
|
|
185
|
+
## Install
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
pip install -e .
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
With ROS2 installed, full message deserialization via `rosbag2_py` is available.
|
|
192
|
+
Without ROS2, basic analysis of `.db3` files still works (SQLite fallback with built-in CDR parsers).
|
|
193
|
+
|
|
194
|
+
Optional extras:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pip install -e ".[mcap]" # .mcap file support
|
|
198
|
+
pip install -e ".[llm]" # LLM-powered ask command (Anthropic / OpenAI)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Commands
|
|
202
|
+
|
|
203
|
+
### `bagx info` — Bag summary
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
bagx info recording.db3
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### `bagx eval` — Quality evaluation
|
|
210
|
+
|
|
211
|
+
Evaluate a single bag and produce a composite quality score.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
bagx eval recording.db3
|
|
215
|
+
bagx eval recording.db3 --json report.json
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Metrics:
|
|
219
|
+
- **GNSS**: Fix rate, HDOP statistics
|
|
220
|
+
- **IMU**: Accel/gyro noise, bias stability, frequency
|
|
221
|
+
- **SYNC**: Inter-topic mean/max delay
|
|
222
|
+
- **Overall score**: 0–100
|
|
223
|
+
|
|
224
|
+
### `bagx compare` — Compare two bags
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
bagx compare A.db3 B.db3
|
|
228
|
+
bagx compare A.db3 B.db3 --json diff.json
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Output:
|
|
232
|
+
- Per-metric A/B values and diff
|
|
233
|
+
- improved / degraded / unchanged verdict
|
|
234
|
+
- Overall winner
|
|
235
|
+
|
|
236
|
+
### `bagx sync` — Inter-topic sync analysis
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
bagx sync recording.db3 /gnss /lidar
|
|
240
|
+
bagx sync recording.db3 /imu /camera --json sync.json
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Output:
|
|
244
|
+
- Mean, max, median, P95 delay
|
|
245
|
+
- Standard deviation, outlier rate
|
|
246
|
+
|
|
247
|
+
### `bagx export` — Export to AI/analytics formats
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Parquet (default)
|
|
251
|
+
bagx export recording.db3
|
|
252
|
+
|
|
253
|
+
# AI-friendly mode (relative timestamps, normalized)
|
|
254
|
+
bagx export recording.db3 --ai --format parquet
|
|
255
|
+
|
|
256
|
+
# JSON, specific topics only
|
|
257
|
+
bagx export recording.db3 --format json --topics /gnss,/imu
|
|
258
|
+
|
|
259
|
+
# No flattening
|
|
260
|
+
bagx export recording.db3 --no-flatten
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### `bagx anomaly` — Anomaly detection
|
|
264
|
+
|
|
265
|
+
Automatically detect anomalies and outliers in sensor data.
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
bagx anomaly recording.db3
|
|
269
|
+
bagx anomaly recording.db3 --topic /gnss
|
|
270
|
+
bagx anomaly recording.db3 --json anomalies.json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Detects:
|
|
274
|
+
- **GNSS**: Position jumps, sudden fix loss, HDOP spikes
|
|
275
|
+
- **IMU**: Accel/gyro spikes (N*σ), frequency drops
|
|
276
|
+
- **General**: Message rate gaps (>3x median interval)
|
|
277
|
+
|
|
278
|
+
### `bagx scenario` — Dangerous scene extraction
|
|
279
|
+
|
|
280
|
+
Extract time segments where notable or dangerous scenarios occur.
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
bagx scenario recording.db3
|
|
284
|
+
bagx scenario recording.db3 --json scenarios.json
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Rules:
|
|
288
|
+
- **GNSS lost**: Consecutive no-fix exceeding threshold duration
|
|
289
|
+
- **Sensor dropout**: Topic stops publishing beyond threshold
|
|
290
|
+
- **High dynamics**: IMU acceleration magnitude exceeds threshold (hard braking, sharp turns)
|
|
291
|
+
- **Sync degraded**: Sustained inter-topic delay above threshold
|
|
292
|
+
|
|
293
|
+
### `bagx ask` — Natural language queries
|
|
294
|
+
|
|
295
|
+
Ask questions about a bag file, answered by an LLM.
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
bagx ask recording.db3 "What sensors are in this bag?"
|
|
299
|
+
bagx ask recording.db3 "Is the GNSS quality good?" --provider openai
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Requires `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` environment variable.
|
|
303
|
+
|
|
304
|
+
### `bagx scene` — 3D state extraction
|
|
305
|
+
|
|
306
|
+
Extract position, orientation, and velocity time series.
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
bagx scene recording.db3
|
|
310
|
+
bagx scene recording.db3 --csv scene.csv
|
|
311
|
+
bagx scene recording.db3 --topics /odom,/imu
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Auto-detects PoseStamped, Odometry, Imu, NavSatFix, and TFMessage topics.
|
|
315
|
+
|
|
316
|
+
### `bagx batch` — Batch processing
|
|
317
|
+
|
|
318
|
+
Evaluate or analyze multiple bags at once.
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
bagx batch eval *.db3 --csv summary.csv
|
|
322
|
+
bagx batch eval ./recordings/
|
|
323
|
+
bagx batch anomaly *.db3 --json anomalies.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Design
|
|
327
|
+
|
|
328
|
+
- **CLI-first**: Commands are the primary interface
|
|
329
|
+
- **Reproducible & scriptable**: Designed for batch processing and CI/CD
|
|
330
|
+
- **Data output**: Numbers, JSON, Parquet, CSV — no GUI
|
|
331
|
+
- **Modular**: Each command is an independent module
|
|
332
|
+
- **ROS2-optional**: Works without ROS2 via SQLite + CDR fallback
|
|
333
|
+
|
|
334
|
+
## Project structure
|
|
335
|
+
|
|
336
|
+
```
|
|
337
|
+
bagx/
|
|
338
|
+
cli.py # typer-based CLI entry point
|
|
339
|
+
reader.py # Bag reading (rosbag2_py / mcap / SQLite fallback)
|
|
340
|
+
eval.py # Quality evaluation engine
|
|
341
|
+
compare.py # Two-bag comparison
|
|
342
|
+
sync.py # Inter-topic sync analysis
|
|
343
|
+
export.py # Parquet / JSON export
|
|
344
|
+
anomaly.py # Anomaly detection
|
|
345
|
+
scenario.py # Dangerous scene extraction
|
|
346
|
+
ask.py # LLM-powered natural language queries
|
|
347
|
+
scene.py # 3D state extraction
|
|
348
|
+
batch.py # Batch processing
|
|
349
|
+
schema.py # Schema inference & normalization
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Tech stack
|
|
353
|
+
|
|
354
|
+
- **typer** + **rich**: CLI & display
|
|
355
|
+
- **rosbag2_py**: ROS2 bag reading (optional)
|
|
356
|
+
- **mcap** + **mcap-ros2-support**: MCAP format support (optional)
|
|
357
|
+
- **numpy / pandas**: Numerical analysis
|
|
358
|
+
- **pyarrow**: Parquet output
|
|
359
|
+
- **anthropic / openai**: LLM integration (optional)
|
|
360
|
+
|
|
361
|
+
<!-- CLI_REFERENCE_START -->
|
|
362
|
+
|
|
363
|
+
## CLI Reference
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
Usage: bagx [OPTIONS] COMMAND [ARGS]...
|
|
367
|
+
|
|
368
|
+
Post-processing analysis engine for ROS2 rosbag data.
|
|
369
|
+
|
|
370
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
371
|
+
│ --install-completion Install completion for the current shell. │
|
|
372
|
+
│ --show-completion Show completion for the current shell, to copy │
|
|
373
|
+
│ it or customize the installation. │
|
|
374
|
+
│ --help Show this message and exit. │
|
|
375
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
376
|
+
╭─ Commands ───────────────────────────────────────────────────────────────────╮
|
|
377
|
+
│ eval Evaluate quality of a single bag file. │
|
|
378
|
+
│ compare Compare quality metrics of two bag files. │
|
|
379
|
+
│ sync Analyze time synchronization between two topics. │
|
|
380
|
+
│ export Export bag data to AI/analytics-friendly formats. │
|
|
381
|
+
│ anomaly Detect anomalies and outliers in sensor data. │
|
|
382
|
+
│ scenario Identify and extract dangerous or interesting scenarios. │
|
|
383
|
+
│ ask Ask a natural language question about a bag file, answered by an │
|
|
384
|
+
│ LLM. │
|
|
385
|
+
│ scene Extract 3D state (position, orientation, velocity) time series. │
|
|
386
|
+
│ info Show bag file summary information. │
|
|
387
|
+
│ batch Batch operations on multiple bags │
|
|
388
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### `bagx eval`
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
Usage: bagx eval [OPTIONS] BAG
|
|
395
|
+
|
|
396
|
+
Evaluate quality of a single bag file.
|
|
397
|
+
|
|
398
|
+
Analyzes GNSS fix rate/HDOP, IMU noise/bias, and inter-topic sync,
|
|
399
|
+
producing a composite quality score.
|
|
400
|
+
|
|
401
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
402
|
+
│ * bag TEXT Path to the bag file (.db3 or directory) [required] │
|
|
403
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
404
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
405
|
+
│ --json -j TEXT Output JSON report to file │
|
|
406
|
+
│ --help Show this message and exit. │
|
|
407
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### `bagx compare`
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
Usage: bagx compare [OPTIONS] BAG_A BAG_B
|
|
414
|
+
|
|
415
|
+
Compare quality metrics of two bag files.
|
|
416
|
+
|
|
417
|
+
Evaluates both bags and reports per-metric differences,
|
|
418
|
+
indicating which bag is better overall.
|
|
419
|
+
|
|
420
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
421
|
+
│ * bag_a TEXT Path to the first bag file [required] │
|
|
422
|
+
│ * bag_b TEXT Path to the second bag file [required] │
|
|
423
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
424
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
425
|
+
│ --json -j TEXT Output JSON report to file │
|
|
426
|
+
│ --help Show this message and exit. │
|
|
427
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### `bagx sync`
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
Usage: bagx sync [OPTIONS] BAG TOPIC_A TOPIC_B
|
|
434
|
+
|
|
435
|
+
Analyze time synchronization between two topics.
|
|
436
|
+
|
|
437
|
+
Reports mean/max/median delay, variance, P95, and outlier rate.
|
|
438
|
+
|
|
439
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
440
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
441
|
+
│ * topic_a TEXT First topic name [required] │
|
|
442
|
+
│ * topic_b TEXT Second topic name [required] │
|
|
443
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
444
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
445
|
+
│ --json -j TEXT Output JSON report to file │
|
|
446
|
+
│ --help Show this message and exit. │
|
|
447
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### `bagx export`
|
|
451
|
+
|
|
452
|
+
```
|
|
453
|
+
Usage: bagx export [OPTIONS] BAG
|
|
454
|
+
|
|
455
|
+
Export bag data to AI/analytics-friendly formats.
|
|
456
|
+
|
|
457
|
+
Outputs one file per topic in JSON or Parquet format,
|
|
458
|
+
with optional timestamp normalization and field flattening.
|
|
459
|
+
|
|
460
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
461
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
462
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
463
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
464
|
+
│ --output -o TEXT Output directory [default: ./export] │
|
|
465
|
+
│ --format -f TEXT Output format: parquet or json │
|
|
466
|
+
│ [default: parquet] │
|
|
467
|
+
│ --topics -t TEXT Comma-separated topic names (default: │
|
|
468
|
+
│ all) │
|
|
469
|
+
│ --ai Enable AI-friendly mode (relative │
|
|
470
|
+
│ timestamps, normalized) │
|
|
471
|
+
│ --flatten --no-flatten Flatten nested message fields │
|
|
472
|
+
│ [default: flatten] │
|
|
473
|
+
│ --help Show this message and exit. │
|
|
474
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### `bagx anomaly`
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
Usage: bagx anomaly [OPTIONS] BAG
|
|
481
|
+
|
|
482
|
+
Detect anomalies and outliers in sensor data.
|
|
483
|
+
|
|
484
|
+
Finds GNSS position jumps, IMU spikes, message rate gaps,
|
|
485
|
+
and other anomalous events in the bag file.
|
|
486
|
+
|
|
487
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
488
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
489
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
490
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
491
|
+
│ --topic -t TEXT Analyze only this topic │
|
|
492
|
+
│ --json -j TEXT Output JSON report to file │
|
|
493
|
+
│ --help Show this message and exit. │
|
|
494
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### `bagx scenario`
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
Usage: bagx scenario [OPTIONS] BAG
|
|
501
|
+
|
|
502
|
+
Identify and extract dangerous or interesting scenarios.
|
|
503
|
+
|
|
504
|
+
Detects GNSS loss, sensor dropouts, high dynamics events,
|
|
505
|
+
and sync degradation periods.
|
|
506
|
+
|
|
507
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
508
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
509
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
510
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
511
|
+
│ --json -j TEXT Output JSON report to file │
|
|
512
|
+
│ --help Show this message and exit. │
|
|
513
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### `bagx ask`
|
|
517
|
+
|
|
518
|
+
```
|
|
519
|
+
Usage: bagx ask [OPTIONS] BAG QUESTION
|
|
520
|
+
|
|
521
|
+
Ask a natural language question about a bag file, answered by an LLM.
|
|
522
|
+
|
|
523
|
+
Gathers bag context (summary, eval, message samples) and sends it
|
|
524
|
+
along with your question to an LLM for analysis.
|
|
525
|
+
|
|
526
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
527
|
+
│ * bag TEXT Path to the bag file (.db3 or directory) [required] │
|
|
528
|
+
│ * question TEXT Natural language question about the bag [required] │
|
|
529
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
530
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
531
|
+
│ --provider -p TEXT LLM provider: 'anthropic' or 'openai' │
|
|
532
|
+
│ [default: anthropic] │
|
|
533
|
+
│ --help Show this message and exit. │
|
|
534
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### `bagx scene`
|
|
538
|
+
|
|
539
|
+
```
|
|
540
|
+
Usage: bagx scene [OPTIONS] BAG
|
|
541
|
+
|
|
542
|
+
Extract 3D state (position, orientation, velocity) time series.
|
|
543
|
+
|
|
544
|
+
Auto-detects topics with scene-relevant message types (PoseStamped,
|
|
545
|
+
Odometry, Imu, NavSatFix, TFMessage) unless specific topics are given.
|
|
546
|
+
|
|
547
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
548
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
549
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
550
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
551
|
+
│ --csv -c TEXT Export scene states to CSV file │
|
|
552
|
+
│ --json -j TEXT Output JSON report to file │
|
|
553
|
+
│ --topics -t TEXT Comma-separated topic names (default: auto-detect) │
|
|
554
|
+
│ --help Show this message and exit. │
|
|
555
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### `bagx info`
|
|
559
|
+
|
|
560
|
+
```
|
|
561
|
+
Usage: bagx info [OPTIONS] BAG
|
|
562
|
+
|
|
563
|
+
Show bag file summary information.
|
|
564
|
+
|
|
565
|
+
╭─ Arguments ──────────────────────────────────────────────────────────────────╮
|
|
566
|
+
│ * bag TEXT Path to the bag file [required] │
|
|
567
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
568
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
569
|
+
│ --help Show this message and exit. │
|
|
570
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### `bagx batch`
|
|
574
|
+
|
|
575
|
+
```
|
|
576
|
+
Usage: bagx batch [OPTIONS] COMMAND [ARGS]...
|
|
577
|
+
|
|
578
|
+
Batch operations on multiple bags
|
|
579
|
+
|
|
580
|
+
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
|
581
|
+
│ --help Show this message and exit. │
|
|
582
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
583
|
+
╭─ Commands ───────────────────────────────────────────────────────────────────╮
|
|
584
|
+
│ eval Evaluate quality of multiple bag files. │
|
|
585
|
+
│ anomaly Run anomaly detection on multiple bag files. │
|
|
586
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
<!-- CLI_REFERENCE_END -->
|