mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-22 22:46:36 +00:00
2dd60a0e37
7 structured documents covering stack, integrations, architecture, structure, conventions, testing, and concerns. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 KiB
12 KiB
Codebase Structure
Analysis Date: 2026-04-01
Directory Layout
gps-denied-onboard/
├── src/
│ └── gps_denied/ # Main package
│ ├── __init__.py # Package version
│ ├── __main__.py # Entry point (uvicorn runner)
│ ├── app.py # FastAPI app factory + lifespan
│ ├── config.py # Pydantic-settings configuration classes
│ ├── api/
│ │ ├── __init__.py
│ │ ├── deps.py # FastAPI dependency providers (singletons)
│ │ └── routers/
│ │ ├── __init__.py
│ │ └── flights.py # All /flights/* endpoints
│ ├── core/
│ │ ├── processor.py # FlightProcessor — main orchestrator
│ │ ├── pipeline.py # ImageInputPipeline — image ingestion/queuing
│ │ ├── vo.py # SequentialVisualOdometry (SuperPoint+LightGlue)
│ │ ├── satellite.py # SatelliteDataManager (tile fetch/cache)
│ │ ├── gpr.py # GlobalPlaceRecognition (AnyLoc/DINOv2)
│ │ ├── metric.py # MetricRefinement (LiteSAM homography alignment)
│ │ ├── graph.py # FactorGraphOptimizer (GTSAM/mock pose graph)
│ │ ├── chunk_manager.py # RouteChunkManager (disconnected segments)
│ │ ├── recovery.py # FailureRecoveryCoordinator (tracking loss handling)
│ │ ├── rotation.py # ImageRotationManager (360° sweep, heading tracking)
│ │ ├── coordinates.py # CoordinateTransformer (ENU↔GPS, pixel→GPS)
│ │ ├── models.py # ModelManager + MockInferenceEngine
│ │ ├── results.py # ResultManager (DB + SSE publish)
│ │ └── sse.py # SSEEventStreamer (per-flight async queues)
│ ├── db/
│ │ ├── __init__.py
│ │ ├── engine.py # Async SQLAlchemy engine + session factory
│ │ ├── models.py # ORM table definitions (8 tables)
│ │ └── repository.py # FlightRepository DAO (all SQL operations)
│ ├── schemas/
│ │ ├── __init__.py # GPSPoint, CameraParameters, Polygon, Geofences
│ │ ├── flight.py # Flight CRUD request/response schemas
│ │ ├── image.py # ImageBatch, ImageData, ProcessedBatch schemas
│ │ ├── vo.py # Features, Matches, Motion, RelativePose
│ │ ├── gpr.py # TileCandidate, DatabaseMatch
│ │ ├── metric.py # AlignmentResult, ChunkAlignmentResult, Sim3Transform
│ │ ├── satellite.py # TileCoords, TileBounds
│ │ ├── graph.py # Pose, OptimizationResult, FactorGraphConfig
│ │ ├── chunk.py # ChunkHandle, ChunkStatus enum
│ │ ├── rotation.py # RotationResult, HeadingHistory
│ │ ├── model.py # InferenceEngine base schema
│ │ └── events.py # SSEMessage, SSEEventType, FrameProcessedEvent, etc.
│ └── utils/
│ └── mercator.py # Slippy map tile math (lat/lon↔tile x/y/bounds)
├── _docs/
│ ├── _autopilot_state.md # GSD planning state tracker
│ ├── 01_solution/
│ │ └── solution.md # Master architecture document (finalized draft 06)
│ └── 02_document/
│ └── tests/ # Test scenario specifications (43 scenarios)
├── .planning/
│ └── codebase/ # GSD mapping documents (this directory)
├── .venv/ # Python virtual environment (committed or local)
├── pyproject.toml # Project metadata and dependencies
└── flight_data.db # SQLite DB (runtime artifact, not committed)
Directory Purposes
src/gps_denied/:
- Purpose: Top-level Python package; everything importable from here
- Key files:
app.py(create_app factory),config.py(all settings),__main__.py(entrypoint)
src/gps_denied/api/:
- Purpose: HTTP API surface only — routing, request/response handling, dependency injection
- Contains: One router (
flights.py) with 9 endpoints,deps.pywith 3 singleton providers - Key files:
routers/flights.py(all endpoints),deps.py(ProcessorDep, SessionDep, RepoDep)
src/gps_denied/core/:
- Purpose: All processing logic — state machines, algorithms, pipeline components
- Module count: 14 files
- Key files:
processor.py(orchestrator),models.py(inference abstraction),graph.py(pose graph) - Note: Each component has a matching
I*ABC interface defined in the same file
src/gps_denied/db/:
- Purpose: Database access only — no business logic
- Contains: Engine setup, ORM models, one repository class
- Key files:
models.py(8 ORM tables),repository.py(all DB operations)
src/gps_denied/schemas/:
- Purpose: Pydantic data contracts; shared across API, core, and DB layers
- Contains: 12 schema files covering every domain concept
- Key files:
__init__.py(GPSPoint, CameraParameters — imported everywhere),flight.py(largest — all REST schemas)
src/gps_denied/utils/:
- Purpose: Pure utility functions with no side effects
- Contains:
mercator.py— Mercator projection math for tile coordinate conversion - Used by:
satellite.pyexclusively
_docs/:
- Purpose: Architecture documentation and planning artifacts — not source code
- Key files:
01_solution/solution.md(the authoritative design doc),_autopilot_state.md(GSD planning tracker)
Key File Locations
Entry Points:
src/gps_denied/__main__.py: Invoked bypython -m gps_denied; starts uvicornsrc/gps_denied/app.py:create_app()factory;appmodule-level instance used by uvicorn
Configuration:
src/gps_denied/config.py: All settings viapydantic-settings; reads from.envand env varsDB_URL→ SQLAlchemy connection string (default: SQLite)TILES_ZOOM_LEVEL,TILES_CACHE_DIR,TILES_API_KEY→ satellite tile providerMODEL_WEIGHTS_DIR,MODEL_SUPERPOINT_PATH, etc. → model file pathsRECOVERY_*,ROTATION_*→ algorithm thresholds
Core Orchestration:
src/gps_denied/core/processor.py:FlightProcessor— only class that calls other pipeline components
Dependency Wiring:
src/gps_denied/api/deps.py: Single location where singletons (FlightProcessor,SSEEventStreamer) are created and wired;ProcessorDeptype alias used in all routers
Database Schema:
src/gps_denied/db/models.py: All 8 ORM tables with cascade deletes; ground truth for DB schema
Pydantic Contracts:
src/gps_denied/schemas/__init__.py:GPSPointandCameraParameters— imported by nearly every module
Naming Conventions
Files:
snake_case.pythroughout- Core components named after their function:
vo.py,gpr.py,metric.py,graph.py - Interfaces co-located with implementation in the same file (
ISequentialVisualOdometryandSequentialVisualOdometryboth invo.py)
Classes:
- Implementation classes:
PascalCasenoun phrases (FlightProcessor,RouteChunkManager) - Interfaces:
Iprefix + implementation name (IRouteChunkManager) - ORM models: suffixed with
Row(FlightRow,WaypointRow) - Pydantic models: suffixed with
Request/Responsefor API schemas; bare names for internal data
Functions:
snake_case- Async functions throughout API and DB layers; sync in core (except
process_framewhich is async)
Constants/Enums:
TrackingState:str, Enumwith lowercase values ("normal","lost","recovery")SSEEventType:str, Enumwith snake_case valuesChunkStatus:str, Enum
Where to Add New Code
New API endpoint:
- Add route function to
src/gps_denied/api/routers/flights.py - Add request/response Pydantic models to
src/gps_denied/schemas/flight.py - Add business logic method to
src/gps_denied/core/processor.py - If new router prefix needed: create
src/gps_denied/api/routers/{name}.pyand register inapp.py
New pipeline component:
- Create
src/gps_denied/core/{component_name}.py - Define
I{ComponentName}(ABC)interface and{ComponentName}implementation in same file - Add schemas to
src/gps_denied/schemas/{component_name}.py - Add component instantiation to
app.pylifespan block - Inject via
FlightProcessor.attach_components()and call fromprocess_frame()
New database table:
- Add
{Name}Row(Base)tosrc/gps_denied/db/models.py - Add CRUD methods to
src/gps_denied/db/repository.py - Add foreign key + relationship to
FlightRowif flight-scoped
New configuration setting:
- Add field to the appropriate
BaseSettingssubclass insrc/gps_denied/config.py - Use
ENV_PREFIX__FIELD_NAMEenv var pattern
New schema type:
- Add to
src/gps_denied/schemas/{relevant_file}.pyor create new file - If broadly shared (like
GPSPoint), add tosrc/gps_denied/schemas/__init__.py
Utility functions:
- Add to
src/gps_denied/utils/mercator.pyif geospatial math - Create
src/gps_denied/utils/{name}.pyfor other pure utilities
Special Directories
.venv/:
- Purpose: Python virtual environment
- Generated: Yes (via
python -m venvor uv) - Committed: Present in tree (check
.gitignore)
_docs/:
- Purpose: Architecture docs, test specs, GSD planning artifacts
- Generated: No (hand-authored)
- Committed: Yes
.planning/:
- Purpose: GSD (Get Stuff Done) planning system — phase plans, codebase maps
- Generated: By GSD commands
- Committed: Yes (used by CI/planning tools)
.image_storage/ (runtime):
- Purpose: Disk storage for uploaded UAV images per flight
- Created by:
ImageInputPipeline.store_images() - Path: Relative to process CWD; configurable via
ImageInputPipeline(storage_dir=...)
.satellite_cache/ (runtime):
- Purpose: diskcache directory for satellite tiles
- Created by:
SatelliteDataManager.__init__() - Size limit: 10GB default
Module Dependency Graph (simplified)
api/routers/flights.py
→ api/deps.py
→ core/processor.py
→ core/pipeline.py (image ingestion)
→ core/results.py (DB + SSE publish)
→ core/sse.py (event streaming)
→ [via attach_components]
→ core/vo.py → core/models.py
→ core/gpr.py → core/models.py
→ core/metric.py → core/models.py
→ core/graph.py (optional: gtsam)
→ core/chunk_manager.py → core/graph.py
→ core/recovery.py → core/chunk_manager.py
→ core/gpr.py
→ core/metric.py
→ core/rotation.py
→ db/repository.py
→ db/models.py
→ core/sse.py
→ db/engine.py
core/satellite.py (standalone — not wired into processor yet)
core/coordinates.py (standalone — not wired into processor yet)
utils/mercator.py → only used by core/satellite.py
schemas/* → imported by all layers (no internal imports)
config.py → imported by db/engine.py, and anywhere settings needed
Notably standalone (not connected to processor):
src/gps_denied/core/satellite.py:SatelliteDataManager— instantiated nowhere inapp.pyorprocessor.py; satellite tiles fetched inline with mock inprocessor.pysrc/gps_denied/core/coordinates.py:CoordinateTransformer— not instantiated in the pipeline;convert_object_to_gpsin processor returns a hardcoded stub (GPSPoint(lat=48.0, lon=37.0))
Structure analysis: 2026-04-01