mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-22 22:46:36 +00:00
220 lines
8.7 KiB
Markdown
220 lines
8.7 KiB
Markdown
# GPS-Denied Onboard
|
|
|
|
Сервіс геолокалізації знімків БПЛА в умовах відсутності GPS-сигналу.
|
|
|
|
Система використовує візуальну одометрію (VO), співставлення з супутниковими картами (cross-view matching) та оптимізацію траєкторії через фактор-графи для визначення координат дрона в реальному часі.
|
|
|
|
---
|
|
|
|
## Архітектура
|
|
|
|
```
|
|
UAV Frames ──▷ ImageInputPipeline (F05) ──▷ ImageRotationManager (F06)
|
|
│
|
|
┌─────────────────────┼─────────────────────┐
|
|
▼ ▼ ▼
|
|
SequentialVO (F07) GlobalPlaceRecog (F08) SatelliteData (F04)
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
FactorGraphOptim (F10) ◂── MetricRefinement (F09) ◂── CoordTransform (F13)
|
|
│
|
|
┌─────────┴─────────┐
|
|
▼ ▼
|
|
RouteChunkManager (F12) FailureRecovery (F11)
|
|
│
|
|
▼
|
|
SSE Event Streamer ──▷ Ground Station
|
|
```
|
|
|
|
**State Machine** (`process_frame`):
|
|
```
|
|
NORMAL ──(VO fail)──▷ LOST ──▷ RECOVERY ──(GPR+Metric ok)──▷ NORMAL
|
|
```
|
|
|
|
---
|
|
|
|
## Стек
|
|
|
|
| Підсистема | Технологія |
|
|
|-----------|------------|
|
|
| **API** | FastAPI + Pydantic v2, SSE (sse-starlette) |
|
|
| **БД** | SQLite + SQLAlchemy 2 (asyncio) |
|
|
| **CV** | OpenCV (Essential Matrix, RANSAC, recoverPose) |
|
|
| **Оптимізація** | GTSAM 4.3 (iSAM2, Huber kernel) |
|
|
| **Моделі** | Mock engines: SuperPoint, LightGlue, DINOv2, LiteSAM |
|
|
| **Кеш** | diskcache (супутникові тайли) |
|
|
| **HTTP** | httpx (Google Maps Static Tiles) |
|
|
| **Тести** | pytest + pytest-asyncio (80 тестів) |
|
|
|
|
---
|
|
|
|
## Швидкий старт
|
|
|
|
### Вимоги
|
|
|
|
- Python ≥ 3.11
|
|
- pip / venv
|
|
- ~500 MB дискового простору (GTSAM wheel)
|
|
|
|
### Встановлення
|
|
|
|
```bash
|
|
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]"
|
|
```
|
|
|
|
### Конфігурація `.env`
|
|
|
|
```env
|
|
# Опціонально — для реальних супутникових тайлів
|
|
GOOGLE_MAPS_API_KEY=<your_key>
|
|
GOOGLE_MAPS_SESSION_TOKEN=<your_token>
|
|
|
|
# Налаштування серверу (за замовчуванням)
|
|
GPS_DENIED_HOST=127.0.0.1
|
|
GPS_DENIED_PORT=8000
|
|
GPS_DENIED_DB_URL=sqlite+aiosqlite:///./gps_denied.db
|
|
```
|
|
|
|
### Запуск серверу
|
|
|
|
```bash
|
|
python -m gps_denied
|
|
```
|
|
|
|
Сервер стартує на `http://127.0.0.1:8000`.
|
|
|
|
| Endpoint | Метод | Опис |
|
|
|----------|-------|------|
|
|
| `/health` | GET | Health check |
|
|
| `/flights` | POST | Створити новий політ |
|
|
| `/flights/{id}` | GET | Деталі польоту |
|
|
| `/flights/{id}` | DELETE | Видалити політ |
|
|
| `/flights/{id}/images/batch` | POST | Завантажити батч зображень |
|
|
| `/flights/{id}/fix` | POST | Надати GPS-якір (user fix) |
|
|
| `/flights/{id}/status` | GET | Статус обробки |
|
|
| `/flights/{id}/events` | GET | SSE стрім подій |
|
|
| `/flights/{id}/object-gps` | POST | Pixel → GPS координата |
|
|
|
|
---
|
|
|
|
## Тести
|
|
|
|
```bash
|
|
# Усі тести (80 шт, ~23с)
|
|
python -m pytest tests/ -v
|
|
|
|
# Тільки acceptance
|
|
python -m pytest tests/test_acceptance.py -v
|
|
|
|
# Тільки конкретний модуль
|
|
python -m pytest tests/test_graph.py -v
|
|
```
|
|
|
|
### Покриття тестами
|
|
|
|
| Файл тесту | Компонент | Кількість |
|
|
|-------------|-----------|-----------|
|
|
| `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_satellite.py` | Тайли + Mercator | 5 |
|
|
| `test_coordinates.py` | ENU / GPS конвертері | 4 |
|
|
| `test_pipeline.py` | Image queue | 3 |
|
|
| `test_rotation.py` | 360° ротації | 4 |
|
|
| `test_models.py` | Mock engines | 3 |
|
|
| `test_vo.py` | Visual Odometry | 5 |
|
|
| `test_gpr.py` | Place Recognition | 3 |
|
|
| `test_metric.py` | Metric Refinement | 3 |
|
|
| `test_graph.py` | Factor Graph | 4 |
|
|
| `test_chunk_manager.py` | Chunk lifecycle | 3 |
|
|
| `test_recovery.py` | Recovery coordinator | 2 |
|
|
| `test_processor_full.py` | State Machine | 4 |
|
|
| `test_acceptance.py` | AC сценарії + perf | 6 |
|
|
| | **Всього** | **80** |
|
|
|
|
---
|
|
|
|
## Структура проєкту
|
|
|
|
```
|
|
gps-denied-onboard/
|
|
├── src/gps_denied/
|
|
│ ├── __init__.py
|
|
│ ├── __main__.py # Entry point (uvicorn)
|
|
│ ├── app.py # FastAPI application
|
|
│ ├── config.py # Pydantic Settings (.env)
|
|
│ ├── api/
|
|
│ │ └── flights.py # REST endpoints
|
|
│ ├── core/
|
|
│ │ ├── processor.py # FlightProcessor + process_frame (State Machine)
|
|
│ │ ├── vo.py # Sequential Visual Odometry (F07)
|
|
│ │ ├── gpr.py # Global Place Recognition (F08)
|
|
│ │ ├── metric.py # Metric Refinement (F09)
|
|
│ │ ├── graph.py # Factor Graph Optimizer (F10, GTSAM)
|
|
│ │ ├── recovery.py # Failure Recovery Coordinator (F11)
|
|
│ │ ├── chunk_manager.py # Route Chunk Manager (F12)
|
|
│ │ ├── coordinates.py # Coordinate Transformer (F13)
|
|
│ │ ├── models.py # Model Manager (F16)
|
|
│ │ ├── satellite.py # Satellite Data Manager (F04)
|
|
│ │ ├── pipeline.py # Image Input Pipeline (F05)
|
|
│ │ ├── rotation.py # Image Rotation Manager (F06)
|
|
│ │ ├── sse.py # SSE Event Streamer
|
|
│ │ └── results.py # Result Manager
|
|
│ ├── db/
|
|
│ │ ├── database.py # Async engine + session
|
|
│ │ ├── models.py # SQLAlchemy ORM models
|
|
│ │ └── repository.py # FlightRepository (CRUD)
|
|
│ ├── schemas/
|
|
│ │ ├── __init__.py # Re-exports
|
|
│ │ ├── flight.py # Flight, Waypoint, GPS, Camera schemas
|
|
│ │ ├── events.py # SSE event models
|
|
│ │ ├── image.py # ImageBatch, ProcessingStatus
|
|
│ │ ├── rotation.py # RotationResult, HeadingHistory
|
|
│ │ ├── model.py # InferenceEngine, ModelConfig
|
|
│ │ ├── vo.py # Features, Matches, RelativePose
|
|
│ │ ├── gpr.py # TileCandidate, DatabaseMatch
|
|
│ │ ├── metric.py # AlignmentResult, Sim3Transform
|
|
│ │ ├── graph.py # Pose, OptimizationResult
|
|
│ │ ├── chunk.py # ChunkHandle, ChunkStatus
|
|
│ │ └── satellite.py # TileCoords, TileBounds
|
|
│ └── utils/
|
|
│ └── mercator.py # Web Mercator utilities
|
|
├── tests/ # 17 test modules (80 tests)
|
|
├── docs/ # Архітектурні специфікації
|
|
├── docs-Lokal/ # Локальний план та рішення
|
|
├── pyproject.toml # Залежності та конфігурація
|
|
└── .gitignore
|
|
```
|
|
|
|
---
|
|
|
|
## Компоненти (F-індексація)
|
|
|
|
| ID | Назва | Файл | Статус |
|
|
|----|-------|------|--------|
|
|
| F04 | Satellite Data Manager | `core/satellite.py` | ✅ Mock |
|
|
| F05 | Image Input Pipeline | `core/pipeline.py` | ✅ |
|
|
| F06 | Image Rotation Manager | `core/rotation.py` | ✅ |
|
|
| F07 | Sequential Visual Odometry | `core/vo.py` | ✅ Mock engines |
|
|
| F08 | Global Place Recognition | `core/gpr.py` | ✅ Mock Faiss |
|
|
| F09 | Metric Refinement | `core/metric.py` | ✅ Mock LiteSAM |
|
|
| F10 | Factor Graph Optimizer | `core/graph.py` | ✅ GTSAM wrapper |
|
|
| F11 | Failure Recovery Coordinator | `core/recovery.py` | ✅ |
|
|
| F12 | Route Chunk Manager | `core/chunk_manager.py` | ✅ |
|
|
| F13 | Coordinate Transformer | `core/coordinates.py` | ✅ |
|
|
| F16 | Model Manager | `core/models.py` | ✅ Mock/Fallback |
|
|
|
|
---
|
|
|
|
## Ліцензія
|
|
|
|
Приватний репозиторій. Усі права захищено.
|