mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 00:26:36 +00:00
docs(tech-audit): OSS stack audit and sprint-1 technology decisions
Records architectural gap (cuVSLAM Mono has no metric scale), chosen path (Mono-Depth + barometer), and per-layer decisions for VO, ESKF, GTSAM, Place Recognition, and MAVLink. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
# Tech Audit — Open-Source Stack для GPS-Denied Navigation
|
||||
**Дата:** 2026-04-18
|
||||
**Горизонт:** 2–3 тижні (sprint 1)
|
||||
**Контекст:** Fixed-wing БПЛА, Jetson Orin Nano Super, nadir камера ADTI 20L V1, ArduPilot FC
|
||||
|
||||
---
|
||||
|
||||
## 1. Архітектурний розрив — головна знахідка
|
||||
|
||||
### Проблема з cuVSLAM Inertial mode
|
||||
|
||||
Поточна архітектура планує cuVSLAM у режимі "Inertial" (з IMU). Але:
|
||||
|
||||
- cuVSLAM Inertial/Visual-Inertial mode потребує **стерео камеру** (дві камери поряд, як очі)
|
||||
- У нас одна nadir камера — Mono режим
|
||||
- cuVSLAM Mono дає лише кут повороту, **без metric scale** (без відстані)
|
||||
- Без scale неможливо побудувати GPS_INPUT — це useless для ArduPilot
|
||||
|
||||
**Важливо:** камера пілота (вперед) + nadir камера (вниз) — це не stereo. Stereo = дві камери в одному напрямку на відстані 10–20 см.
|
||||
|
||||
### Чому це не критично для sprint 1
|
||||
|
||||
Scale для nadir камери над рівною місцевістю — **детермінований**:
|
||||
|
||||
```
|
||||
scale = altitude / focal_length
|
||||
```
|
||||
|
||||
Барометр дає висоту → ESKF рахує scale → VO потребує лише точний 2D planar tracking. Це і є перший шлях.
|
||||
|
||||
---
|
||||
|
||||
## 2. Вибрана архітектура (sprint 1)
|
||||
|
||||
### VO: cuVSLAM Mono-Depth + барометр
|
||||
|
||||
**Рішення:** cuVSLAM Mono-Depth режим, де барометрична висота подається як synthetic depth для відновлення metric scale.
|
||||
|
||||
**Точність між GPR корекціями:** ~0.3–0.5 м
|
||||
**Drift на маршруті:** обмежений — GPR скидає накопичену похибку
|
||||
|
||||
### Чому drift не критичний
|
||||
|
||||
Архітектура має три рівні корекції:
|
||||
|
||||
```
|
||||
VO (drift між кадрами)
|
||||
↓
|
||||
ESKF ← IMU (короткострокова стабілізація, ~ms)
|
||||
↓
|
||||
Place Recognition ← satellite tiles (глобальна корекція, ~сотні метрів)
|
||||
↓
|
||||
GTSAM loop closure (довгострокова консистентність)
|
||||
```
|
||||
|
||||
Якщо GPR впізнає місцевість кожні ~500 м → загальна похибка на 10 км маршруту: **1–5 м**. Це прийнятно для GPS-denied.
|
||||
|
||||
**Ризик GPR:** не спрацює при хмарах, однорідній місцевості (поле без орієнтирів), застарілих тайлах. В цих випадках drift накопичується до наступного успішного match.
|
||||
|
||||
---
|
||||
|
||||
## 3. Технологічний стек — рішення по шарах
|
||||
|
||||
### VO Layer
|
||||
|
||||
| Компонент | Dev/CI | Production (Jetson) | Статус |
|
||||
|---|---|---|---|
|
||||
| **Visual Odometry** | ORBVisualOdometry (OpenCV) | cuVSLAM Mono-Depth | Залишаємо, фіксуємо Mono-Depth |
|
||||
| **XFeat** | — | Satellite tile matching (майбутнє) | Не VO fallback, окремий трек |
|
||||
| **SuperPoint+LightGlue** | — | — | Відхилено: 15–33× повільніше за cuVSLAM |
|
||||
|
||||
**Відхилені альтернативи:**
|
||||
- ORB-SLAM3 Mono-Inertial (~0.08 м) — потребує IMU ≥100 Hz по MAVLink. Типово ArduPilot шле 50 Hz (SR*_RAW_SENS). Можна підняти до 200 Hz зміною одного параметра, але не пріоритет зараз.
|
||||
- cuVSLAM Stereo-Inertial (0.054 м) — потребує hardware зміни (друга камера). Довгостроково.
|
||||
|
||||
### ESKF
|
||||
|
||||
| Рішення | Обґрунтування |
|
||||
|---|---|
|
||||
| Залишаємо numpy 15-state ESKF | IMU preintegration не критичний на 5–10 Hz VO для повільного fixed-wing |
|
||||
| **Пінити `numpy==1.26.4`** | NumPy 2.0 ламає GTSAM Python bindings (issue #2264) — критично |
|
||||
| `manifpy` — опційно | pip-installable Lie group math, додати тільки якщо знайдемо баги в quaternion коді |
|
||||
|
||||
### Factor Graph (GTSAM)
|
||||
|
||||
**Рішення sprint 1: пропустити GTSAM, використовувати ESKF.**
|
||||
|
||||
ESKF достатній для Gaussian GPS_INPUT 5–10 Hz. Factor graph дає перевагу (~15 vs 34 см) лише при non-Gaussian noise з outliers — не наш сценарій зараз.
|
||||
|
||||
Коли повернутись: **GTSAM 4.2 stable** (не 4.3a1 alpha). miniSAM — стейл з 2019, g2o Python — experimental. Єдиний живий варіант.
|
||||
|
||||
### Place Recognition
|
||||
|
||||
| Компонент | Рішення | Обґрунтування |
|
||||
|---|---|---|
|
||||
| **Descriptor** | DINOv2-VLAD (AnyLoc) | 10–12 мс TRT FP16 на Jetson, offline-capable |
|
||||
| **Index** | Faiss GPU | Залишаємо |
|
||||
| **INT8 квантизація** | ❌ Не робити | Broken для ViT на Jetson (NVIDIA/TRT#4348, dinov2#489) |
|
||||
| **Довгостроково** | EigenPlaces (ICCV 2023) | Кращий ONNX export, viewpoint-robust |
|
||||
| **NetVLAD** | ❌ Deprecated | DINOv2-VLAD краще на 2.4% R@1 (MSLS 2024) |
|
||||
| **Satellite tiles** | MapTiler offline MBTiles | Україна zoom 0–13, JPEG, offline |
|
||||
|
||||
**Перевірити:** [aero-vloc](https://github.com/prime-slam/aero-vloc) — benchmark на aerial nadir imagery до того як фіксувати Faiss index дизайн.
|
||||
|
||||
### MAVLink / ArduPilot
|
||||
|
||||
| Рішення | Обґрунтування |
|
||||
|---|---|
|
||||
| **pymavlink** залишаємо | MAVSDK-Python не підтримує GPS_INPUT (PX4-first) |
|
||||
| Reference impl | `MAVProxy/modules/mavproxy_GPSInput.py` — точне кодування GPS_INPUT (#232) |
|
||||
| Частота injection | 5–10 Hz (не 20 Hz — timing jitter при вищих rate) |
|
||||
| Yaw extension field | Не використовувати — ArduPilot 4.x ігнорує |
|
||||
|
||||
---
|
||||
|
||||
## 4. Критичні перевірки перед кодом
|
||||
|
||||
Три речі, які треба знати до того як писати будь-який код:
|
||||
|
||||
### 4.1 Процесор Flight Controller
|
||||
- **H743** — підтримує GPS_INPUT over serial ✅
|
||||
- **F405** — мовчки ігнорує GPS_INPUT ❌ (втрата днів на дебаг)
|
||||
- Перевірити: Mission Planner → Help → About (показує назву FC), або питати у постачальника дрона
|
||||
|
||||
### 4.2 IMU rate по MAVLink
|
||||
- За замовчуванням ArduPilot: **50 Hz**
|
||||
- Для ORB-SLAM3 Mono-Inertial потрібно: **≥100 Hz**
|
||||
- Параметр для зміни: `SR2_RAW_SENS` (або SR0/SR1 залежно від порту)
|
||||
- Для sprint 1 (cuVSLAM Mono-Depth) — не критично
|
||||
|
||||
### 4.3 numpy версія
|
||||
- Зафіксувати `numpy==1.26.4` в `pyproject.toml` негайно
|
||||
- NumPy 2.0 ламає GTSAM silently — важко дебажити
|
||||
|
||||
---
|
||||
|
||||
## 5. Пріоритети на 2–3 тижні
|
||||
|
||||
### Тиждень 1
|
||||
- [ ] Зафіксувати `numpy==1.26.4` в pyproject.toml
|
||||
- [ ] Перевірити FC processor (H743 vs F405)
|
||||
- [ ] Перевірити поточний IMU rate по MAVLink
|
||||
- [ ] Prototype cuVSLAM Mono-Depth з барометром як synthetic depth
|
||||
- [ ] Запустити aero-vloc на наших nadir кадрах
|
||||
|
||||
### Тиждень 2
|
||||
- [ ] cuVSLAM Mono-Depth інтеграція в E2EHarness
|
||||
- [ ] Порівняти ATE: ORB (поточний baseline) vs cuVSLAM Mono-Depth
|
||||
- [ ] AnyLoc offline setup + перший тест на satellite tiles
|
||||
|
||||
### Тиждень 3
|
||||
- [ ] XFeat TRT export для satellite matching (окремий трек від VO)
|
||||
- [ ] MAVLink GPS_INPUT injection тест на SITL (Software-in-the-Loop)
|
||||
- [ ] Визначити чи варто піднімати IMU rate для майбутнього Mono-Inertial
|
||||
|
||||
---
|
||||
|
||||
## 6. Аналоги нашої системи
|
||||
|
||||
Для розуміння де ми знаходимось відносно SOTA:
|
||||
|
||||
| Система | VO | Fusion | Scale | Статус |
|
||||
|---|---|---|---|---|
|
||||
| **Наша** | cuVSLAM Mono | ESKF | Барометр | Sprint 1 |
|
||||
| **VINS-Fusion** | Mono-Inertial | Factor graph | IMU | Open-source, ROS |
|
||||
| **OpenVINS** | MSCKF Mono | EKF | IMU | Open-source, ~0.08м EuRoC |
|
||||
| **PX4 EKF2** | — | UKF | GPS | Вбудований в PX4 |
|
||||
| **ArduPilot EKF3** | — | EKF | GPS | Вбудований в ArduPilot |
|
||||
|
||||
Наша архітектура унікальна тим що **замінює GPS через Place Recognition** (satellite matching) — не просто VIO, а VIO + global anchor. Це правильний підхід для тривалих маршрутів.
|
||||
|
||||
---
|
||||
|
||||
## 7. Відкриті питання
|
||||
|
||||
1. Якість cuVSLAM Mono-Depth на feature-poor nadir terrain (рівне поле, ліс) — потребує льотних тестів
|
||||
2. Частота та надійність GPR match в реальних умовах України
|
||||
3. Чи достатньо барометра для scale recovery при різких змінах висоти (маневри, вітер)
|
||||
4. Перехід на Stereo-Inertial (hardware) — коли і чи потрібен взагалі
|
||||
Reference in New Issue
Block a user