From 1bf8b2a6845d5e22d1117fdaaf5744018cb551ec Mon Sep 17 00:00:00 2001 From: Yuzviak Date: Fri, 17 Apr 2026 17:48:16 +0300 Subject: [PATCH] docs: record EuRoC MH_01 real-run baseline across all doc surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- README.md | 16 +++++++++++----- .../decisions/0001-e2e-dataset-strategy.md | 7 ++++++- next_steps.md | 16 ++++++++++------ src/gps_denied/testing/README.md | 7 ++++--- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 0213ee7..1bc72e8 100644 --- a/README.md +++ b/README.md @@ -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_slow -v # nightly-tier (VPAIR sample, MARS-LVIG stress) -# Завантажити датасет (EuRoC MH_01 — CI-tier; URL у `src/gps_denied/testing/download.py`) -python scripts/download_dataset.py euroc_mh01 # у datasets/euroc/MH_01/ +# EuRoC Machine Hall bundle — 12.6 GB, DOI 10.3929/ethz-b-000690084 +# Завантажити вручну (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 # Розпакувати так, щоб datasets/vpair/sample/poses_query.txt існував -# SHA256 зашитий у DATASET_REGISTRY для верифікації відомого артефакту +# SHA256 зашитий у DATASET_REGISTRY ("vpair_sample") для верифікації + +# Для автоматизованих entry (коли з'являться) — той самий CLI: +python scripts/download_dataset.py ``` 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-знімки високої висоти. -- **EuRoC MH_01**, **MARS-LVIG** — тести скіпаються (датасети не завантажені локально). +- **VPAIR sample** (200 кадрів fixed-wing 300-400 м над Bonn/Eifel): пайплайн завершується, ATE RMSE ~1770 км → xfail. Причина: VPAIR не ship raw IMU → ESKF-шлях не активний; VO-самостійно розходиться. +- **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 — окремо) diff --git a/_docs/01_solution/decisions/0001-e2e-dataset-strategy.md b/_docs/01_solution/decisions/0001-e2e-dataset-strategy.md index 97a82df..0404033 100644 --- a/_docs/01_solution/decisions/0001-e2e-dataset-strategy.md +++ b/_docs/01_solution/decisions/0001-e2e-dataset-strategy.md @@ -47,7 +47,12 @@ All adapters share a single `DatasetAdapter` interface (`src/gps_denied/testing/ - Altitude envelope of public datasets (indoor EuRoC, 80–130 m MARS-LVIG, 300–400 m VPAIR) undershoots the target 200–1500 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. -**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 diff --git a/next_steps.md b/next_steps.md index a9d52f0..acd7ba8 100644 --- a/next_steps.md +++ b/next_steps.md @@ -60,16 +60,19 @@ - [x] **Перший реальний e2e-прогін на VPAIR sample** (200 кадрів fixed-wing, 300-400 м над Bonn/Eifel) - Результат: пайплайн завершується без падінь, **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.] -- [ ] Запустити EuRoC MH_01 через e2e (потребує `machine_hall.zip` — 12 GB bundle; завтра) - - [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 локально, пушимо тільки конфігурацію.] -- [ ] Замінити xfail на strict-assert у VPAIR тесті (коли VO+GPR почнуть давати притомні числа) +- [x] **Перший реальний e2e-прогін на EuRoC MH_01** (перші 100 кадрів indoor MAV, ASL формат) + - Результат: пайплайн завершується за ~30 с, **ATE RMSE ~10 871 м** → xfail за ceiling 5 м + - [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 треба так чи інакше, але це паралельна гілка роботи. ### Патерн гілок для e2e-роботи -- `feat/e2e-vpair` — сьогоднішня робота (VPAIR адаптер під реальний формат + coord helpers + registry). **Поточний статус**: 4 коміти, пушнуто, PR у stage1 відкритий -- `feat/e2e-euroc` — завтра (EuRoC MH_01 реальний прогін) -- Інтеграція у stage1 через послідовні PR-и (VPAIR → stage1, потім EuRoC branch off з оновленого stage1) +- `feat/e2e-vpair` — **merged** у stage1 через PR #1 (2026-04-16, rebase) +- `feat/e2e-euroc` — поточна робота (2026-04-17): harness `max_frames`, перший реальний прогін EuRoC MH_01, реєстр перейменовано на `euroc_machine_hall` +- Інтеграція у 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 день**: Реалізовано 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-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`. diff --git a/src/gps_denied/testing/README.md b/src/gps_denied/testing/README.md index 1b51be8..32d8a55 100644 --- a/src/gps_denied/testing/README.md +++ b/src/gps_denied/testing/README.md @@ -97,8 +97,9 @@ pytest tests/e2e/ -m "e2e and not e2e_slow" -v # Nightly tier: VPAIR, MARS-LVIG, other long runs pytest tests/e2e/ -m e2e_slow -v -# Download a dataset registered in DATASET_REGISTRY with a URL -python scripts/download_dataset.py euroc_mh01 +# Inspect the registry / trigger a manual-instruction printout +python scripts/download_dataset.py # exits 3 and prints fetch steps + # if the entry has an empty URL ``` 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 | |---|---|---|---|---| | `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 | | `MARSLVIGAdapter` | rotary (DJI M300 RTK) | yes | RTK | pending (requires pre-extracted ROS bag) |