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>
9.3 KiB
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 — 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. Відкриті питання
- Якість cuVSLAM Mono-Depth на feature-poor nadir terrain (рівне поле, ліс) — потребує льотних тестів
- Частота та надійність GPR match в реальних умовах України
- Чи достатньо барометра для scale recovery при різких змінах висоти (маневри, вітер)
- Перехід на Stereo-Inertial (hardware) — коли і чи потрібен взагалі