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.
Files changed (44) hide show
  1. bagx-0.1.0/LICENSE +21 -0
  2. bagx-0.1.0/PKG-INFO +590 -0
  3. bagx-0.1.0/README.md +554 -0
  4. bagx-0.1.0/bagx/__init__.py +3 -0
  5. bagx-0.1.0/bagx/anomaly.py +359 -0
  6. bagx-0.1.0/bagx/ask.py +182 -0
  7. bagx-0.1.0/bagx/batch.py +202 -0
  8. bagx-0.1.0/bagx/cli.py +406 -0
  9. bagx-0.1.0/bagx/compare.py +190 -0
  10. bagx-0.1.0/bagx/eval.py +501 -0
  11. bagx-0.1.0/bagx/export.py +204 -0
  12. bagx-0.1.0/bagx/py.typed +0 -0
  13. bagx-0.1.0/bagx/reader.py +813 -0
  14. bagx-0.1.0/bagx/scenario.py +429 -0
  15. bagx-0.1.0/bagx/scene.py +437 -0
  16. bagx-0.1.0/bagx/schema.py +75 -0
  17. bagx-0.1.0/bagx/sync.py +215 -0
  18. bagx-0.1.0/bagx.egg-info/PKG-INFO +590 -0
  19. bagx-0.1.0/bagx.egg-info/SOURCES.txt +42 -0
  20. bagx-0.1.0/bagx.egg-info/dependency_links.txt +1 -0
  21. bagx-0.1.0/bagx.egg-info/entry_points.txt +2 -0
  22. bagx-0.1.0/bagx.egg-info/requires.txt +21 -0
  23. bagx-0.1.0/bagx.egg-info/top_level.txt +1 -0
  24. bagx-0.1.0/pyproject.toml +75 -0
  25. bagx-0.1.0/setup.cfg +4 -0
  26. bagx-0.1.0/tests/test_anomaly.py +189 -0
  27. bagx-0.1.0/tests/test_ask.py +158 -0
  28. bagx-0.1.0/tests/test_batch.py +181 -0
  29. bagx-0.1.0/tests/test_cdr_parsers.py +258 -0
  30. bagx-0.1.0/tests/test_cli.py +96 -0
  31. bagx-0.1.0/tests/test_compare.py +63 -0
  32. bagx-0.1.0/tests/test_edge_cases.py +517 -0
  33. bagx-0.1.0/tests/test_endianness.py +177 -0
  34. bagx-0.1.0/tests/test_eval.py +158 -0
  35. bagx-0.1.0/tests/test_export.py +122 -0
  36. bagx-0.1.0/tests/test_logging.py +77 -0
  37. bagx-0.1.0/tests/test_mcap.py +285 -0
  38. bagx-0.1.0/tests/test_multi_segment.py +198 -0
  39. bagx-0.1.0/tests/test_reader.py +92 -0
  40. bagx-0.1.0/tests/test_readme_examples.py +377 -0
  41. bagx-0.1.0/tests/test_scenario.py +235 -0
  42. bagx-0.1.0/tests/test_scene.py +270 -0
  43. bagx-0.1.0/tests/test_schema.py +79 -0
  44. 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 -->