diff --git a/README.md b/README.md index 9f754ff..40949b1 100644 --- a/README.md +++ b/README.md @@ -4,68 +4,216 @@ Система використовує візуальну одометрію (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 +``` + +--- + +## Стек + +| Підсистема | Технологія | |-----------|------------| -| **Core API** | FastAPI + Pydantic v2 (REST endpoints `POST /flights`, `POST /flights/{id}/images/batch`) | -| **Real-time стрім (SSE)** | `sse-starlette`, `asyncio.Queue` (Pub/Sub для live-трансляції уточнених поз на наземну станцію) | -| **Репозиторій (БД)** | `SQLite` + `SQLAlchemy 2` + `AsyncIO` + `Alembic`. Скеровує каскадні видалення та зберігає waypoint-результати. | -| **Супутникові тайли (F04)** | `httpx`, `diskcache`, інтеграція з Google Maps Static Tiles + утиліти Web Mercator | -| **Трансформація координат (F13)** | Зберігання локального ENU Origin, конвертація WGS84 ↔ Local ENU ↔ Pixels | -| **Вхідний пайплайн (F05)** | `cv2`, `asyncio.Queue`. Керує FIFO чергою батчів кадрів з БПЛА, здійснює базову валідацію послідовностей та збереження фотографій на диск. | -| **Менеджер ротацій (F06)** | Оберти 360° блоками по 30° для підбору орієнтації; трекінг історії курсу з виявленням різких поворотів (>45°). | -| **Model Manager (F16)** | Архітектура завантаження ML моделей (Mock/Fallback). | -| **Візуальна Одометрія (F07)** | Суперпоінт / LightGlue імітація. OpenCV (`findEssentialMat` + RANSAC + `recoverPose`) для розрахунку відносного руху між кадрами без відомого масштабу. | -| **Global Place Recognition (F08)** | Розпізнавання місцевості (DINOv2/AnyLoc мок), використання імпровізованого Faiss-індексу для ранжирування кандидатів. | -| **Metric Refinement (F09)** | Вимірювання абсолютної GPS-координати (LiteSAM мок) через гомографію з супутниковим знімком та bounds scaling. | -| **Граф поз (F10)** | GTSAM (Python Bindings). Реєстрація відносних та абсолютних факторів з iSAM2 оптимізацією. | -| **Recovery & Chunks (F11, F12)** | Координатор відновлення трекінгу та керування незалежними сабграфами-чанками (відривами) під час польоту. | -| **Повний цикл (Stage 10)** | `process_frame` оркестрація: VO → GPR → Metric → Graph → SSE. State Machine: NORMAL→LOST→RECOVERY→NORMAL. | -| **Тестування (Stage 11)** | 80 юніт та acceptance тестів. AC-сценарії: нормальний політ, втрата/відновлення, продуктивність, sustained throughput. | +| **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 -# Клонувати та перейти в гілку stage1 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= +GOOGLE_MAPS_SESSION_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`. Health check: `GET /health`. +Сервер стартує на `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/ # Основний пакет +├── src/gps_denied/ │ ├── __init__.py -│ ├── __main__.py # Entry point (uvicorn) -│ └── app.py # FastAPI application -├── tests/ # Тести -├── docs-Lokal/ # Локальна документація та план -├── _docs/ # Архітектурна документація -├── pyproject.toml # Залежності та конфігурація +│ ├── __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 | + +--- + ## Ліцензія Приватний репозиторій. Усі права захищено. diff --git a/docs-Lokal/LOCAL_EXECUTION_PLAN.md b/docs-Lokal/LOCAL_EXECUTION_PLAN.md index 91bda0b..869e754 100644 --- a/docs-Lokal/LOCAL_EXECUTION_PLAN.md +++ b/docs-Lokal/LOCAL_EXECUTION_PLAN.md @@ -106,8 +106,8 @@ - 6 AC-тестів: нормальний політ (20 кадрів), tracking loss/recovery, perf <5с/кадр, user anchor, sustained throughput (50 кадрів), graph convergence. - Усього 80 тестів проходять. -### Етап 12 — Локальна експлуатація -- Документація локального запуску, README.md. +### Етап 12 — Локальна експлуатація ✅ +- Деталізований README: архітектура, структура, endpoints, тести, компоненти, `.env`, розгортання. ---