docs: update README and next_steps with sprint 1 VO migration results

README:
- Stack table: VO row shows CuVSLAMMonoDepthVisualOdometry (Mono-Depth mode)
- Test coverage: 195+8 → 216+8 (new mono_depth tests, AnyLoc markers, GPS_INPUT encoding)
- Added test_gps_input_encoding.py row
- F07 component table: dev/prod shows Mono-Depth variants
- "Next steps" rewritten: sprint 1 complete, sprint 2 queued

next_steps.md:
- New §5.1a documenting sprint 1 execution (7 commits, 3 decisions recorded)
- §5.3 week-1 marked numpy pin / Mono-Depth class / GPS_INPUT encoding as done
- Week-2 updated with harness wiring and CuVSLAMVisualOdometry deletion tasks

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yuzviak
2026-04-18 16:37:50 +03:00
parent 759766d737
commit 1618190105
2 changed files with 50 additions and 20 deletions
+29 -15
View File
@@ -43,12 +43,12 @@ NORMAL ──(VO fail)──▶ LOST ──▶ RECOVERY ──(GPR+Metric ok)─
| Підсистема | Dev/CI | Jetson (production) |
|-----------|--------|---------------------|
| **Visual Odometry** | ORBVisualOdometry (OpenCV) | CuVSLAMVisualOdometry (PyCuVSLAM v15) |
| **AI Inference** | MockInferenceEngine | TRTInferenceEngine (TensorRT FP16) |
| **Place Recognition** | numpy L2 fallback | Faiss GPU index |
| **Visual Odometry** | ORBVisualOdometry / CuVSLAMMonoDepthVisualOdometry (scaled ORB fallback) | CuVSLAMMonoDepthVisualOdometry (PyCuVSLAM v15 Mono-Depth — barometer as synthetic depth) |
| **AI Inference** | MockInferenceEngine | TRTInferenceEngine (TensorRT FP16; INT8 disabled — broken for ViT on Jetson) |
| **Place Recognition** | numpy L2 fallback (AnyLoc-VLAD-DINOv2 baseline) | Faiss GPU index + DINOv2-VLAD TRT FP16 |
| **MAVLink** | MockMAVConnection | pymavlink over UART |
| **ESKF** | numpy (15-state) | numpy (15-state) |
| **Factor Graph** | Mock poses | GTSAM 4.3 ISAM2 |
| **Factor Graph** | Mock poses | GTSAM 4.3 ISAM2 (sprint 2 — ESKF-only sufficient for sprint 1) |
| **API** | FastAPI + Pydantic v2 + SSE | FastAPI + Pydantic v2 + SSE |
| **БД** | SQLite + SQLAlchemy 2 async | SQLite |
| **Тести** | pytest + pytest-asyncio | — |
@@ -181,7 +181,7 @@ E2E-харнес гонить `FlightProcessor` як black-box через спі
EuRoC: `vo_success=99/100`, `eskf_initialized=100/100`. GPS estimate xfail — indoor, satellite tiles не релевантні.
VPAIR: ESKF не активний (немає raw IMU), VO без якоря розходиться. Outdoor — потенційно satellite matching допоможе.
### Покриття тестами (70 e2e passed / 1 skipped / 2 xfailed; 195 passed / 8 skipped — unit/component)
### Покриття тестами (216 passed / 8 skipped — unit/component; EuRoC MH_0105 e2e PASS)
| Файл тесту | Компонент | К-сть |
|-------------|-----------|-------|
@@ -195,8 +195,8 @@ VPAIR: ESKF не активний (немає raw IMU), VO без якоря р
| `test_pipeline.py` | Image queue | 5 |
| `test_rotation.py` | 360° ротації | 4 |
| `test_models.py` | Model Manager + TRT | 6 |
| `test_vo.py` | VO (ORB + cuVSLAM) | 8 |
| `test_gpr.py` | Place Recognition (Faiss) | 7 |
| `test_vo.py` | VO (ORB + cuVSLAM + Mono-Depth) | 16 |
| `test_gpr.py` | Place Recognition + AnyLoc markers | 9 |
| `test_metric.py` | Metric Refinement + GSD | 6 |
| `test_graph.py` | Factor Graph (GTSAM) | 4 |
| `test_chunk_manager.py` | Chunk lifecycle | 3 |
@@ -204,10 +204,11 @@ VPAIR: ESKF не активний (немає raw IMU), VO без якоря р
| `test_processor_full.py` | State Machine | 4 |
| `test_processor_pipe.py` | PIPE wiring (Phase 5) | 13 |
| `test_mavlink.py` | MAVLink I/O bridge | 19 |
| `test_gps_input_encoding.py` | GPS_INPUT field encoding (MAVLink #232) | 12 |
| `test_acceptance.py` | AC сценарії + perf | 6 |
| `test_accuracy.py` | Accuracy validation | 23 |
| `test_sitl_integration.py` | SITL (skip без ArduPilot) | 8 |
| | **Всього** | **195+8** |
| | **Всього** | **216+8** |
---
@@ -276,7 +277,7 @@ gps-denied-onboard/
| F04 | Satellite Data Manager | `core/satellite.py` | local tiles | local tiles |
| F05 | Image Input Pipeline | `core/pipeline.py` | ✅ | ✅ |
| F06 | Image Rotation Manager | `core/rotation.py` | ✅ | ✅ |
| F07 | Sequential Visual Odometry | `core/vo.py` | ORB | cuVSLAM |
| F07 | Sequential Visual Odometry | `core/vo.py` | ORB / Mono-Depth (scaled ORB) | cuVSLAM Mono-Depth |
| F08 | Global Place Recognition | `core/gpr.py` | numpy | Faiss GPU |
| F09 | Metric Refinement | `core/metric.py` | Mock | LiteSAM/XFeat TRT |
| F10 | Factor Graph Optimizer | `core/graph.py` | Mock | GTSAM ISAM2 |
@@ -291,12 +292,25 @@ gps-denied-onboard/
## Що залишилось (наступні кроки)
### Dev pipeline (захищений e2e-харнесом)
1. **cuVSLAM Mono-Depth** — замінити `ORBVisualOdometry` на cuVSLAM Mono + барометричний depth (`scale = altitude / focal_length`). Mono-Inertial потребує stereo hardware (нема). Mono-Depth — правильний шлях для одиничної nadir-камери. Research: `docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md`.
2. **DINOv2-VLAD (AnyLoc) для GPR** — замінити numpy L2 fallback. Satellite tiles через MapTiler MBTiles (offline). Fixed FP16, без INT8 (broken для ViT на Jetson).
3. **VPAIR unblock** — xfail (1770 км ATE) блокований відсутністю raw IMU + mock satellite index. Реальні MapTiler tiles **АБО** cuVSLAM Mono-Depth з GT-altitude розблокують.
4. **Аудит solution.md** — звірити імплементацію з `_docs/01_solution/solution.md`.
5. **Реструктуризація**`src/gps_denied/*``src/*` (зайвий неймспейс).
### Sprint 1 — виконано (2026-04-18)
Див. план `docs/superpowers/plans/2026-04-18-sprint1-vo-migration.md` і design doc `docs/superpowers/specs/2026-04-18-oss-stack-tech-audit-design.md`.
- [x] **numpy pin** `>=1.26,<2.0` — NumPy 2.0 silently breaks GTSAM bindings (issue #2264)
- [x] **CuVSLAMMonoDepthVisualOdometry** додано поряд з Inertial-варіантом. Dev/CI: ORB translation scaled by `depth_hint_m / 600.0`. Jetson: cuVSLAM Mono-Depth mode з barometric altitude як synthetic depth.
- [x] **GlobalPlaceRecognition** явно маркований як AnyLoc-VLAD-DINOv2 baseline з selection rationale в docstring
- [x] **GPS_INPUT encoding** покритий 12 unit-тестами проти `_eskf_to_gps_input` (degE7 lat/lon, ENU→NED velocity, ConfidenceTier → fix_type)
- [x] **E2E regression guard** на EuRoC MH_01 для Mono-Depth (ATE 0.2046м, baseline незмінний)
### Sprint 2 — далі (захищений e2e-харнесом)
1. **Wire CuVSLAMMonoDepthVisualOdometry через E2EHarness** — harness зараз хардкодить `ORBVisualOdometry()`; додати `vo_backend` параметр щоб прогнати Mono-Depth через pipeline
2. **Колапс дуплікатного коду з `CuVSLAMVisualOdometry`** (Inertial варіант) — видалити Inertial mode після Jetson validation
3. **VPAIR unblock** — xfail (1770 км ATE) блокований відсутністю raw IMU + mock satellite index. Реальні MapTiler tiles + Mono-Depth з GT-altitude розблокують.
4. **DINOv2-VLAD TRT FP16 engine** — реальний descriptor замість numpy L2 fallback. Satellite tiles через MapTiler MBTiles (offline).
5. **aero-vloc benchmark** на наших nadir кадрах — підтвердити R@1 DINOv2-VLAD перед фіксацією Faiss index design
6. **Аудит solution.md** — звірити `_docs/01_solution/solution.md` з реальним кодом (Inertial → Mono-Depth)
7. **Реструктуризація**`src/gps_denied/*``src/*`
### Критичні блокери (перевірити до наступного коду)
- **Flight Controller processor**: H743 ✅ / F405 ❌ (silently ignores GPS_INPUT). Запитати постачальника.