mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-22 21:46:36 +00:00
094895b21b
Phase 2 — Visual Odometry: - ORBVisualOdometry (dev/CI), CuVSLAMVisualOdometry (Jetson) - TRTInferenceEngine (TensorRT FP16, conditional import) - create_vo_backend() factory Phase 3 — Satellite Matching + GPR: - SatelliteDataManager: local z/x/y tiles, ESKF ±3σ tile selection - GSD normalization (SAT-03), RANSAC inlier-ratio confidence (SAT-04) - GlobalPlaceRecognition: Faiss index + numpy fallback Phase 4 — MAVLink I/O: - MAVLinkBridge: GPS_INPUT 15+ fields, IMU callback, 1Hz telemetry - 3-consecutive-failure reloc request - MockMAVConnection for CI Phase 5 — Pipeline Wiring: - ESKF wired into process_frame: VO update → satellite update - CoordinateTransformer + SatelliteDataManager via DI - MAVLink state push per frame (PIPE-07) - Real pixel_to_gps via ray-ground projection (PIPE-06) - GTSAM ISAM2 update when available (PIPE-03) Phase 6 — Docker + CI: - Multi-stage Dockerfile (python:3.11-slim) - docker-compose.yml (dev), docker-compose.sitl.yml (ArduPilot SITL) - GitHub Actions: ci.yml (lint+pytest+docker smoke), sitl.yml (nightly) - tests/test_sitl_integration.py (8 tests, skip without SITL) Phase 7 — Accuracy Validation: - AccuracyBenchmark + SyntheticTrajectory - AC-PERF-1: 80% within 50m ✅ - AC-PERF-2: 60% within 20m ✅ - AC-PERF-3: p95 latency < 400ms ✅ - AC-PERF-4: VO drift 1km < 100m ✅ (actual ~11m) - scripts/benchmark_accuracy.py CLI Tests: 195 passed / 8 skipped Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
11 KiB
11 KiB
GPS-Denied Onboard
Бортова система GPS-denied навігації для фіксованого крила БПЛА на Jetson Orin Nano Super.
Замінює GPS-сигнал власною оцінкою позиції на основі відеопотоку (cuVSLAM), IMU та супутникових знімків. Позиція подається у польотний контролер ArduPilot у форматі GPS_INPUT через MAVLink при 5–10 Гц.
Архітектура
IMU (MAVLink RAW_IMU) ──────────────────────────────────────────▶ ESKF.predict()
│
ADTI 20L V1 ──▶ ImageInputPipeline ──▶ ImageRotationManager │
│ │
┌───────────────┼───────────────┐ │
▼ ▼ ▼ │
cuVSLAM/ORB VO GlobalPlaceRecog SatelliteData │
(F07) (F08/Faiss) (F04) │
│ │ │ │
▼ ▼ ▼ │
ESKF.update_vo() GSD norm MetricRefinement│
│ (F09) │
└──────────────────────▶ ESKF.update_sat()│
│
ESKF state ◀──┘
│
┌───────────────┼──────────────┐
▼ ▼ ▼
MAVLinkBridge FactorGraph SSE Stream
GPS_INPUT 5-10Hz (GTSAM ISAM2) → Ground Station
→ ArduPilot FC
State Machine (process_frame):
NORMAL ──(VO fail)──▶ LOST ──▶ RECOVERY ──(GPR+Metric ok)──▶ NORMAL
Стек
| Підсистема | 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 |
| MAVLink | MockMAVConnection | pymavlink over UART |
| ESKF | numpy (15-state) | numpy (15-state) |
| Factor Graph | Mock poses | GTSAM 4.3 ISAM2 |
| API | FastAPI + Pydantic v2 + SSE | FastAPI + Pydantic v2 + SSE |
| БД | SQLite + SQLAlchemy 2 async | SQLite |
| Тести | pytest + pytest-asyncio | — |
Швидкий старт
Вимоги
- Python ≥ 3.11
- ~500 MB дискового простору (GTSAM wheel)
Встановлення
git clone https://github.com/azaion/gps-denied-onboard.git
cd gps-denied-onboard
git checkout stage1
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Запуск
# Пряме запуск
python -m gps_denied
# Docker
docker compose up --build
Сервер: http://127.0.0.1:8000
Змінні середовища
GPS_DENIED_DB_PATH=/data/flights.db
GPS_DENIED_TILE_DIR=/data/satellite_tiles # локальні тайли z/x/y.png
GPS_DENIED_LOG_LEVEL=INFO
MAVLINK_CONNECTION=serial:/dev/ttyTHS1:57600 # UART на Jetson
API
| Endpoint | Метод | Опис |
|---|---|---|
/health |
GET | Health check |
/flights |
POST | Створити політ |
/flights/{id} |
GET | Деталі польоту |
/flights/{id} |
DELETE | Видалити політ |
/flights/{id}/images/batch |
POST | Батч зображень |
/flights/{id}/fix |
POST | GPS-якір від оператора |
/flights/{id}/status |
GET | Статус обробки |
/flights/{id}/events |
GET | SSE стрім (позиція + confidence) |
/flights/{id}/object-gps |
POST | Pixel → GPS (ray-ground проекція) |
Тести
# Всі тести
python -m pytest -q
# Конкретний модуль
python -m pytest tests/test_eskf.py -v
python -m pytest tests/test_mavlink.py -v
python -m pytest tests/test_accuracy.py -v
# SITL (потребує ArduPilot SITL)
docker compose -f docker-compose.sitl.yml up -d
ARDUPILOT_SITL_HOST=localhost pytest tests/test_sitl_integration.py -v
Покриття тестами (195 passed / 8 skipped)
| Файл тесту | Компонент | К-сть |
|---|---|---|
test_schemas.py |
Pydantic схеми | 12 |
test_database.py |
SQLAlchemy CRUD | 9 |
test_api_flights.py |
REST endpoints | 5 |
test_health.py |
Health check | 1 |
test_eskf.py |
ESKF 15-state | 17 |
test_coordinates.py |
ENU/GPS/pixel | 4 |
test_satellite.py |
Тайли + Mercator | 8 |
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_metric.py |
Metric Refinement + GSD | 6 |
test_graph.py |
Factor Graph (GTSAM) | 4 |
test_chunk_manager.py |
Chunk lifecycle | 3 |
test_recovery.py |
Recovery coordinator | 2 |
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_acceptance.py |
AC сценарії + perf | 6 |
test_accuracy.py |
Accuracy validation | 23 |
test_sitl_integration.py |
SITL (skip без ArduPilot) | 8 |
| Всього | 195+8 |
Benchmark валідації (Phase 7)
python scripts/benchmark_accuracy.py --frames 50
Результати на синтетичній траєкторії (20 м/с, 0.7 fps, шум VO 0.3 м, супутник кожні 5 кадрів):
| Критерій | Результат | Ліміт |
|---|---|---|
| 80% кадрів ≤ 50 м | ✅ 100% | ≥ 80% |
| 60% кадрів ≤ 20 м | ✅ 100% | ≥ 60% |
| p95 затримка | ✅ ~9 мс | < 400 мс |
| VO дрейф за 1 км | ✅ ~11 м | < 100 м |
Структура проєкту
gps-denied-onboard/
├── src/gps_denied/
│ ├── app.py # FastAPI factory + lifespan
│ ├── config.py # Pydantic Settings
│ ├── api/routers/flights.py # REST + SSE endpoints
│ ├── core/
│ │ ├── eskf.py # 15-state ESKF (IMU+VO+satellite fusion)
│ │ ├── processor.py # FlightProcessor + process_frame
│ │ ├── vo.py # ORBVisualOdometry / CuVSLAMVisualOdometry
│ │ ├── mavlink.py # MAVLinkBridge → GPS_INPUT → ArduPilot
│ │ ├── satellite.py # SatelliteDataManager (local z/x/y tiles)
│ │ ├── gpr.py # GlobalPlaceRecognition (Faiss/numpy)
│ │ ├── metric.py # MetricRefinement (LiteSAM/XFeat + GSD)
│ │ ├── graph.py # FactorGraphOptimizer (GTSAM ISAM2)
│ │ ├── coordinates.py # CoordinateTransformer (ENU↔GPS↔pixel)
│ │ ├── models.py # ModelManager + TRTInferenceEngine
│ │ ├── benchmark.py # AccuracyBenchmark + SyntheticTrajectory
│ │ ├── pipeline.py # ImageInputPipeline
│ │ ├── rotation.py # ImageRotationManager
│ │ ├── recovery.py # FailureRecoveryCoordinator
│ │ └── chunk_manager.py # RouteChunkManager
│ ├── schemas/ # Pydantic схеми (eskf, mavlink, vo, ...)
│ ├── db/ # SQLAlchemy ORM + async repository
│ └── utils/mercator.py # Web Mercator tile utilities
├── tests/ # 22 test модулі
├── scripts/
│ └── benchmark_accuracy.py # CLI валідація точності
├── Dockerfile # Multi-stage Python 3.11 image
├── docker-compose.yml # Local dev
├── docker-compose.sitl.yml # ArduPilot SITL harness
├── .github/workflows/
│ ├── ci.yml # lint + pytest + docker smoke (кожен push)
│ └── sitl.yml # SITL integration (нічний / ручний)
└── pyproject.toml
Компоненти
| ID | Назва | Файл | Dev | Jetson |
|---|---|---|---|---|
| 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 |
| 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 |
| F11 | Failure Recovery | core/recovery.py |
✅ | ✅ |
| F12 | Route Chunk Manager | core/chunk_manager.py |
✅ | ✅ |
| F13 | Coordinate Transformer | core/coordinates.py |
✅ | ✅ |
| F16 | Model Manager | core/models.py |
Mock | TRT engines |
| F17 | ESKF Sensor Fusion | core/eskf.py |
✅ | ✅ |
| F18 | MAVLink I/O Bridge | core/mavlink.py |
Mock | pymavlink |
Що залишилось (on-device)
- Офлайн завантаження тайлів для зони місії →
{tile_dir}/z/x/y.png - Конвертація моделей: LiteSAM/XFeat PyTorch → ONNX → TRT FP16
- Запуск SITL:
docker compose -f docker-compose.sitl.yml up - Польотні дані: записати GPS + відео → порівняти ESKF-траєкторію з ground truth
- Калібрування: camera intrinsics + IMU noise density для конкретного апарату
Ліцензія
Приватний репозиторій. Усі права захищено.