Files
gps-denied-onboard/next_steps.md
T
Yuzviak 1bf8b2a684 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>
2026-04-17 17:52:06 +03:00

98 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Next Steps — дорожня карта
Живий документ. Галочки заповнюються у міру виконання. Коментарі в квадратних дужках `[decision: …]` фіксують рішення, щоб через місяць можна було зрозуміти *чому* ми зробили саме так.
---
## 1. Аудит відповідності солюшну
Весь девелопмент зроблений не з цільового `_docs/01_solution/solution.md`, а з сукупності документів у `_docs/01_solution/`. Треба звірити імплементацію саме з цільовим солюшном.
- [ ] Порівняти поточну імплементацію з `_docs/01_solution/solution.md` (не з усією текою)
- [ ] **VO треба зробити на cuVSLAM** (якщо не буде явних перепон)
- Rationale: SP+LG (SuperPoint+LightGlue) rejection: 1533× повільніше за cuVSLAM. Немає built-in IMU fusion, loop closure, tracking-failure detection. Побудова цих фіч навколо SP+LG — значний час, і все одно повільніше. XFeat (~30–50 мс) — кращий fallback для VO якщо cuVSLAM не зайде на nadir-камеру.
- [ ] Прогнати cuVSLAM через e2e-харнес (див. пункт 3) — перевірити що VO+ESKF разом дають адекватну точність на EuRoC/VPAIR
- [ ] Якщо cuVSLAM підходить → видалити SP+LG з кодбейса. Залишити XFeat як fallback
**Цей крок треба робити ПІД захистом e2e-харнеса**, не до нього, щоб відразу бачити регресії (див. пункт 3).
---
## 2. Реструктуризація коду
Весь код у `src/gps_denied/`, але весь проект і так про gps_denied — зайвий рівень неймспейсу.
- [ ] `git mv src/gps_denied/* src/` (або через rename imports, що чистіше)
- [ ] Оновити імпорти у всіх файлах (`from gps_denied.X``from X` чи залишити як неймспейс, вирішити)
- [ ] Оновити `pyproject.toml`: `[tool.setuptools.packages.find]`
- [ ] Прогнати повну test suite — має бути зелено
- [ ] Оновити CI скрипти, Docker, docs
**Робити під захистом e2e-харнеса** — одна велика рефакторинг-зміна з багатьма PR → легко поламати щось непомітно. Зелений e2e (на тих самих числах що до рефакторингу) — sign-off.
---
## 3. Autopilot existing-code flow — e2e-харнес
Всі проекти в azaion приводяться до механізму девелопменту з `.cursor/skills/autopilot` (`flows/existing-code` для існуючого коду, `flows/greenfield` для нового).
Коротко алгоритм: питаємо вимоги до e2e-тестів і даних → рефакторимо для можливості e2e-покриття → пишемо e2e-підсистему що запускає продукт як black-box → переконуємось що працює → **тоді** ітеративно рефакторимо під захистом e2e.
### Статус виконання
**Design** (локально, gitignored): `.planning/brainstorms/2026-04-16-e2e-datasets-design.md`
**Plan** (локально, gitignored): `.planning/brainstorms/2026-04-16-e2e-datasets-plan.md`
**In-repo docs**: [src/gps_denied/testing/README.md](src/gps_denied/testing/README.md) (harness architecture), [_docs/01_solution/decisions/0001-e2e-dataset-strategy.md](_docs/01_solution/decisions/0001-e2e-dataset-strategy.md) (ADR — selection rationale)
[decision 2026-04-16: замість збору власних даних з Mavic-а — використати публічні UAV датасети. Причина: блокер на проприєтарні дані (Денис, мавікісти), а нам треба рухатись вже зараз. Public датасети: VPAIR (fixed-wing, downward, 300400 м) + EuRoC (indoor MAV, IMU+GT, індустрійний benchmark) + MARS-LVIG (rotary, featureless сіквенси як stress-test). Деталі — у ADR 0001.]
- [x] Побудувати `DatasetAdapter` ABC + capability flags (has_raw_imu, has_rtk_gt, platform_class) — `src/gps_denied/testing/datasets/base.py`
- [x] `SyntheticAdapter` для harness self-test (`synthetic.py`)
- [x] Trajectory метрики — RMSE, ATE, RPE (`metrics.py`)
- [x] `E2EHarness` — жене адаптер через `FlightProcessor`, збирає estimated positions, порівнює з GT (`harness.py`)
- [x] SHA256-verified dataset downloader + registry (`download.py`, `scripts/download_dataset.py`)
- [x] `EuRoCAdapter` + unit-тести з fabricated fixture
- [x] `VPAIRAdapter` + unit-тести з fabricated fixture (**реальний формат**: poses_query.txt, ECEF xyz, Euler rad)
- [x] `MARSLVIGAdapter` + unit-тести (очікує pre-extracted layout з ROS bag)
- [x] `coord.py` helpers: ECEF→WGS84 (Heikkinen closed-form), Euler→quaternion (ZYX aerospace)
- [x] Integration тести з skip-when-absent fixtures (EuRoC, VPAIR, MARS-LVIG)
- [x] Pytest markers `e2e`, `e2e_slow`, `needs_dataset` у pyproject.toml
- [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.]
- [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`**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)
---
## 4. Збір реальних UAV-даних
[decision 2026-04-16: **деприйорити** цей пункт на користь пункту 3 (публічні датасети). Причина: публічні датасети вже є, дають реальний fixed-wing сценарій, не вимагають координації людей. Повернемось до цього коли:
- (а) потрібно буде валідувати на *нашому* конкретному дроні (intrinsics, спектр вібрації IMU, camera model відрізняються від VPAIR/EuRoC);
- (б) готовий буде VO+ESKF-тюнінг і захочеться "фінальний" датасет саме під envelope tactical fixed-wing 200-1500 м.]
- [ ] Денис Попов — логи Mavic (камера вниз, висока висота). *Призупинено.*
- [ ] Штатні мавікісти — пара тестових вильотів з nadir-камерою. *Призупинено, потребує переконати.*
- [ ] DJI Mavic флайт у `/home/yuzviak/Azaion/Data/` (MP4 + SRT + Airdata CSV)
- [decision 2026-04-16: НЕ інтегруємо зараз. Причини: (1) DJI не публікує raw IMU, є лише attitude/speeds (результат фʼюжену) — ESKF-шлях не активується; (2) потрібні camera intrinsics конкретної моделі; (3) sync SRT@30Hz + CSV@5Hz потребує окремого alignment-кроку. Залишаємо як qualitative demo пізніше, коли інфраструктура стабілізується.]
---
## Хронологія рішень
- **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`.