docs: record EuRoC MH_01 real-run baseline across all doc surfaces

Updates README, testing/README, next_steps.md, and ADR 0001 with the
first real EuRoC MH_01 e2e run (100 frames, ~30s wall-time, ATE RMSE
~10.9 km → xfail). Places the EuRoC result alongside the prior VPAIR
baseline (~1770 km) so future-reader can see both failure modes at a
glance:

- VPAIR diverges because no raw IMU → ESKF never engages
- EuRoC diverges because indoor scene has no satellite anchor, so
  VO+ESKF drift without an external correction

Also records the branching policy (rename ``euroc_mh01`` →
``euroc_machine_hall``; empty URL due to DSpace UI gate; manual
fetch via DOI 10.3929/ethz-b-000690084).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yuzviak
2026-04-17 17:48:16 +03:00
committed by Maksym Yuzviak
parent b57187e1b8
commit 1bf8b2a684
4 changed files with 31 additions and 15 deletions
+11 -5
View File
@@ -151,19 +151,25 @@ pytest tests/e2e/ -q # unit + skip-when-absent (швидко)
pytest tests/e2e/ -m "e2e and not e2e_slow" -v # CI-tier з завантаженим датасетом pytest tests/e2e/ -m "e2e and not e2e_slow" -v # CI-tier з завантаженим датасетом
pytest tests/e2e/ -m e2e_slow -v # nightly-tier (VPAIR sample, MARS-LVIG stress) pytest tests/e2e/ -m e2e_slow -v # nightly-tier (VPAIR sample, MARS-LVIG stress)
# Завантажити датасет (EuRoC MH_01 — CI-tier; URL у `src/gps_denied/testing/download.py`) # EuRoC Machine Hall bundle — 12.6 GB, DOI 10.3929/ethz-b-000690084
python scripts/download_dataset.py euroc_mh01 # у datasets/euroc/MH_01/ # Завантажити вручну (DSpace UI без прямого URL), розпакувати внутрішній
# MH_0N_easy.zip у datasets/euroc/MH_0N/, щоб існував mav0/
# SHA256 зашитий у DATASET_REGISTRY ("euroc_machine_hall") для верифікації
# VPAIR sample (fixed-wing, downward, 300-400 м) — form-gated на Zenodo # VPAIR sample (fixed-wing, downward, 300-400 м) — form-gated на Zenodo
# Розпакувати так, щоб datasets/vpair/sample/poses_query.txt існував # Розпакувати так, щоб datasets/vpair/sample/poses_query.txt існував
# SHA256 зашитий у DATASET_REGISTRY для верифікації відомого артефакту # SHA256 зашитий у DATASET_REGISTRY ("vpair_sample") для верифікації
# Для автоматизованих entry (коли з'являться) — той самий CLI:
python scripts/download_dataset.py <dataset_name>
``` ```
E2E-харнес гонить `FlightProcessor` як black-box через спільний `DatasetAdapter` (`src/gps_denied/testing/`). Датасети лежать у `./datasets/` (gitignored), тести пропускаються (не фейляться) коли датасету немає. Детально — у локальному design doc `.planning/brainstorms/2026-04-16-e2e-datasets-design.md` та плані `2026-04-16-e2e-datasets-plan.md`. E2E-харнес гонить `FlightProcessor` як black-box через спільний `DatasetAdapter` (`src/gps_denied/testing/`). Датасети лежать у `./datasets/` (gitignored), тести пропускаються (не фейляться) коли датасету немає. Детально — у локальному design doc `.planning/brainstorms/2026-04-16-e2e-datasets-design.md` та плані `2026-04-16-e2e-datasets-plan.md`.
**Поточний статус реальних прогонів:** **Поточний статус реальних прогонів:**
- **VPAIR sample** (200 кадрів fixed-wing 300-400 м над Bonn/Eifel): пайплайн завершується без падінь, але ATE RMSE ~1770 км → xfail. Причина: VO без IMU/супутникового anchoring розходиться на fixed-wing траєкторії. Очікувано до тюнінгу VO+GPR під nadir-знімки високої висоти. - **VPAIR sample** (200 кадрів fixed-wing 300-400 м над Bonn/Eifel): пайплайн завершується, ATE RMSE ~1770 км → xfail. Причина: VPAIR не ship raw IMU → ESKF-шлях не активний; VO-самостійно розходиться.
- **EuRoC MH_01**, **MARS-LVIG** — тести скіпаються (датасети не завантажені локально). - **EuRoC MH_01** (перші 100 кадрів indoor MAV, ASL формат): пайплайн завершується за ~30 с, ATE RMSE ~10.9 км → xfail. Raw IMU є і ESKF активний, але satellite-anchoring для indoor сцени не релевантний, тому VO+ESKF без якоря дрейфує. Експерименти з більшою довжиною/тюнінгом — після стабілізації GPR+ESKF.
- **MARS-LVIG** — тести скіпаються (датасет не завантажений локально).
### Покриття тестами (195 passed / 8 skipped — unit/component; e2e — окремо) ### Покриття тестами (195 passed / 8 skipped — unit/component; e2e — окремо)
@@ -47,7 +47,12 @@ All adapters share a single `DatasetAdapter` interface (`src/gps_denied/testing/
- Altitude envelope of public datasets (indoor EuRoC, 80130 m MARS-LVIG, 300400 m VPAIR) undershoots the target 2001500 m tactical envelope. Extrapolating upward is a leap of faith; real-target-altitude validation stays on the roadmap. - Altitude envelope of public datasets (indoor EuRoC, 80130 m MARS-LVIG, 300400 m VPAIR) undershoots the target 2001500 m tactical envelope. Extrapolating upward is a leap of faith; real-target-altitude validation stays on the roadmap.
- Dataset formats vary wildly (EuRoC ASL, VPAIR ECEF+Euler text, MARS-LVIG ROS bags). Each adapter is custom. Mitigation: shared `coord.py` helpers (ECEF→WGS84, Euler→quaternion) and a small design contract enforced by the ABC. - Dataset formats vary wildly (EuRoC ASL, VPAIR ECEF+Euler text, MARS-LVIG ROS bags). Each adapter is custom. Mitigation: shared `coord.py` helpers (ECEF→WGS84, Euler→quaternion) and a small design contract enforced by the ABC.
**First real-run evidence** (VPAIR sample, 2026-04-16): pipeline completes on 200 fixed-wing nadir frames without crashing, but ATE RMSE ~1770 km — VO alone diverges catastrophically without IMU or satellite anchoring. This is the baseline. Expected improvement comes from EuRoC (has raw IMU → ESKF path works) and from tuning VO+GPR for high-altitude nadir imagery. **First real-run evidence**:
- **VPAIR sample** (2026-04-16, 200 fixed-wing nadir frames): pipeline completes without crashing, ATE RMSE ~1770 km — VO alone diverges because VPAIR ships poses only, no raw IMU, so ESKF never engages.
- **EuRoC MH_01** (2026-04-17, first 100 indoor MAV frames, ~30 s wall-time): pipeline completes, ATE RMSE ~10.9 km. Raw IMU is present (200 Hz ADIS16448) so ESKF *does* run, but the satellite-matching anchor never fires on an indoor scene. Still diverges — one order of magnitude less than VPAIR, and for a different underlying reason. Both are xfail-gated.
These are the starting measurements. Improvements will come from tuning VO+ESKF for each regime and wiring a substitute anchor (e.g. synthetic ArUco markers for indoor, GPR-against-satellite at the right resolution for VPAIR).
## Alternatives considered ## Alternatives considered
+10 -6
View File
@@ -60,16 +60,19 @@
- [x] **Перший реальний e2e-прогін на VPAIR sample** (200 кадрів fixed-wing, 300-400 м над Bonn/Eifel) - [x] **Перший реальний e2e-прогін на VPAIR sample** (200 кадрів fixed-wing, 300-400 м над Bonn/Eifel)
- Результат: пайплайн завершується без падінь, **ATE RMSE ~1 770 км** → xfail - Результат: пайплайн завершується без падінь, **ATE RMSE ~1 770 км** → xfail
- [decision 2026-04-16: це очікувано. VO сам по собі без IMU і без supплементарного supплутникового anchoring розходиться. VPAIR не має raw IMU → ESKF-шлях не активується. Xfail-branch документує цю deгадацію; перейде у strict-assert коли VO+GPR будуть тюновані для high-altitude nadir + знайдемо датасет з raw IMU.] - [decision 2026-04-16: це очікувано. VO сам по собі без IMU і без supплементарного supплутникового anchoring розходиться. VPAIR не має raw IMU → ESKF-шлях не активується. Xfail-branch документує цю deгадацію; перейде у strict-assert коли VO+GPR будуть тюновані для high-altitude nadir + знайдемо датасет з raw IMU.]
- [ ] Запустити EuRoC MH_01 через e2e (потребує `machine_hall.zip` — 12 GB bundle; завтра) - [x] **Перший реальний e2e-прогін на EuRoC MH_01** (перші 100 кадрів indoor MAV, ASL формат)
- [decision 2026-04-16: замість старого `robotics.ethz.ch` URL (TCP timeout) — новий ETH Research Collection DOI `10.3929/ethz-b-000690084`. Окремого `MH_01_easy.zip` там немає, лише bundle з усіма 5 MH-сіквенсами. Витягнемо MH_01 локально, пушимо тільки конфігурацію.] - Результат: пайплайн завершується за ~30 с, **ATE RMSE ~10 871 м** → xfail за ceiling 5 м
- [ ] Замінити xfail на strict-assert у VPAIR тесті (коли VO+GPR почнуть давати притомні числа) - [decision 2026-04-17: замість старого `robotics.ethz.ch` URL (TCP timeout) — новий ETH Research Collection DOI `10.3929/ethz-b-000690084`. Окремого `MH_01_easy.zip` там немає, лише 12.6 GB bundle з усіма 5 MH-сіквенсами. Витягнули тільки `MH_01_easy.zip` у `/home/yuzviak/Azaion/Data/machine_hall/MH_01/`, symlink з `datasets/euroc/MH_01/`. Registry entry перейменована на `euroc_machine_hall` (bundle-level SHA256).]
- [decision 2026-04-17: harness отримав параметр `max_frames` — CI-tier гонить 100 кадрів за ~30 с. Повна sequence (3682) — ~3 години, не CI-tier.]
- Pipeline diff vs VPAIR: raw IMU є → ESKF активний; але satellite-anchoring для indoor-сцени не релевантний, VO+ESKF без якоря дрейфує на кілометри.
- [ ] Замінити xfail на strict-assert у VPAIR і EuRoC тестах (коли VO+GPR+ESKF-anchoring почнуть давати притомні числа)
- [ ] **IMU з SITL для початку** — ArduPilot SITL може літати mission з waypoints, генерувати 200 Hz IMU через MAVLink. Для піднять пайплайну цього достатньо. Реальний IMU треба так чи інакше, але це паралельна гілка роботи. - [ ] **IMU з SITL для початку** — ArduPilot SITL може літати mission з waypoints, генерувати 200 Hz IMU через MAVLink. Для піднять пайплайну цього достатньо. Реальний IMU треба так чи інакше, але це паралельна гілка роботи.
### Патерн гілок для e2e-роботи ### Патерн гілок для e2e-роботи
- `feat/e2e-vpair`сьогоднішня робота (VPAIR адаптер під реальний формат + coord helpers + registry). **Поточний статус**: 4 коміти, пушнуто, PR у stage1 відкритий - `feat/e2e-vpair`**merged** у stage1 через PR #1 (2026-04-16, rebase)
- `feat/e2e-euroc`завтра (EuRoC MH_01 реальний прогін) - `feat/e2e-euroc`поточна робота (2026-04-17): harness `max_frames`, перший реальний прогін EuRoC MH_01, реєстр перейменовано на `euroc_machine_hall`
- Інтеграція у stage1 через послідовні PR-и (VPAIR → stage1, потім EuRoC branch off з оновленого stage1) - Інтеграція у stage1 через послідовні PR-и. Політика: наступні merge без `--delete-branch` (гілки лишаються на GitHub)
--- ---
@@ -91,3 +94,4 @@
- **2026-04-16 ранок**: Аудит інфраструктури, pull upstream, вирішили взяти публічні датасети замість чекати на Дениса. Brainstorm + spec + plan: VPAIR (Tier 1), MARS-LVIG (Tier 2), EuRoC (Tier 3 CI). - **2026-04-16 ранок**: Аудит інфраструктури, pull upstream, вирішили взяти публічні датасети замість чекати на Дениса. Brainstorm + spec + plan: VPAIR (Tier 1), MARS-LVIG (Tier 2), EuRoC (Tier 3 CI).
- **2026-04-16 день**: Реалізовано e2e-харнес з `DatasetAdapter` pattern. 12 комітів у stage1 (`a2620ae``0062323`), пушнуто. 233 passed, 13 skipped. - **2026-04-16 день**: Реалізовано e2e-харнес з `DatasetAdapter` pattern. 12 комітів у stage1 (`a2620ae``0062323`), пушнуто. 233 passed, 13 skipped.
- **2026-04-16 вечір**: Спробували скачати EuRoC MH_01 — старий URL лежить, знайшли новий DOI (12 GB bundle, завтра). Переключились на VPAIR (вже скачаний). Реальний формат відрізняється від припущеного: ECEF+Euler+no timestamps. Написали `coord.py` (ECEF→WGS84 Heikkinen + Euler→quat), переписали `VPAIRAdapter`. Гілка `feat/e2e-vpair`, 5 комітів. Перший реальний прогін: ATE ~1770 км (очікувано, задокументовано в xfail). - **2026-04-16 вечір**: Спробували скачати EuRoC MH_01 — старий URL лежить, знайшли новий DOI (12 GB bundle, завтра). Переключились на VPAIR (вже скачаний). Реальний формат відрізняється від припущеного: ECEF+Euler+no timestamps. Написали `coord.py` (ECEF→WGS84 Heikkinen + Euler→quat), переписали `VPAIRAdapter`. Гілка `feat/e2e-vpair`, 5 комітів. Перший реальний прогін: ATE ~1770 км (очікувано, задокументовано в xfail).
- **2026-04-17**: Завантажили 12.6 GB `machine_hall.zip`, витягли `MH_01` (2.6 GB). Додали `max_frames` у `E2EHarness` (TDD, 3 нових тести). Перший реальний прогін EuRoC MH_01 на 100 кадрах: пайплайн завершується за ~30 с, **ATE RMSE ~10.87 км → xfail**. Registry entry перейменовано `euroc_mh01``euroc_machine_hall` з реальним SHA256 `5ed7d07…`; URL порожній (ETH Research Collection не дає direct link, ручне завантаження). Гілка `feat/e2e-euroc`.
+4 -3
View File
@@ -97,8 +97,9 @@ pytest tests/e2e/ -m "e2e and not e2e_slow" -v
# Nightly tier: VPAIR, MARS-LVIG, other long runs # Nightly tier: VPAIR, MARS-LVIG, other long runs
pytest tests/e2e/ -m e2e_slow -v pytest tests/e2e/ -m e2e_slow -v
# Download a dataset registered in DATASET_REGISTRY with a URL # Inspect the registry / trigger a manual-instruction printout
python scripts/download_dataset.py euroc_mh01 python scripts/download_dataset.py <name> # exits 3 and prints fetch steps
# if the entry has an empty URL
``` ```
Markers (`e2e`, `e2e_slow`, `needs_dataset`) are registered in `pyproject.toml`. Markers (`e2e`, `e2e_slow`, `needs_dataset`) are registered in `pyproject.toml`.
@@ -108,7 +109,7 @@ Markers (`e2e`, `e2e_slow`, `needs_dataset`) are registered in `pyproject.toml`.
| Adapter | Platform | Raw IMU | GT | Real-run status | | Adapter | Platform | Raw IMU | GT | Real-run status |
|---|---|---|---|---| |---|---|---|---|---|
| `SyntheticAdapter` | — | yes (zero motion) | exact | smoke test only, always runs | | `SyntheticAdapter` | — | yes (zero motion) | exact | smoke test only, always runs |
| `EuRoCAdapter` | indoor MAV | 200 Hz ADIS16448 | Vicon | pending first real run (dataset download in progress) | | `EuRoCAdapter` | indoor MAV | 200 Hz ADIS16448 | Vicon | ran on first 100 frames — ATE ~10.9 km, xfail documented; VO+ESKF active but no satellite anchoring for indoor scene |
| `VPAIRAdapter` | fixed-wing light aircraft | no (pose-only) | GNSS/INS ~1 m | ran once — ATE ~1770 km, xfail documented; VO alone diverges without anchoring | | `VPAIRAdapter` | fixed-wing light aircraft | no (pose-only) | GNSS/INS ~1 m | ran once — ATE ~1770 km, xfail documented; VO alone diverges without anchoring |
| `MARSLVIGAdapter` | rotary (DJI M300 RTK) | yes | RTK | pending (requires pre-extracted ROS bag) | | `MARSLVIGAdapter` | rotary (DJI M300 RTK) | yes | RTK | pending (requires pre-extracted ROS bag) |