# ASTRAL-Next System Flows > **See also**: [System Flow Diagrams (Mermaid)](./system_flows_diagrams.md) for interactive visual diagrams. ## System Overview ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer matching (SuperPoint+LightGlue for VO, DINOv2 for place recognition, LiteSAM for cross-view matching) with an Atlas-style multi-map chunk architecture for robust tracking and recovery. ## Components Summary | ID | Component | Interface | Purpose | |----|-----------|-----------|---------| | F01 | Flight API | `IFlightAPI` | REST endpoints, SSE streaming | | F02.1 | Flight Lifecycle Manager | `IFlightLifecycleManager` | Flight CRUD, init, API delegation | | F02.2 | Flight Processing Engine | `IFlightProcessingEngine` | Processing loop, recovery orchestration | | F03 | Flight Database | `IFlightDatabase` | Persistence layer | | F04 | Satellite Data Manager | `ISatelliteDataManager` | Tile fetching, caching, progressive search | | F05 | Image Input Pipeline | `IImageInputPipeline` | Image ingestion, validation, storage | | F06 | Image Rotation Manager | `IImageRotationManager` | Rotation sweeps, heading tracking | | F07 | Sequential Visual Odometry | `ISequentialVisualOdometry` | Frame-to-frame VO (SuperPoint+LightGlue) | | F08 | Global Place Recognition | `IGlobalPlaceRecognition` | Coarse localization (DINOv2+VLAD) | | F09 | Metric Refinement | `IMetricRefinement` | Precise alignment (LiteSAM) | | F10 | Factor Graph Optimizer | `IFactorGraphOptimizer` | GTSAM-based trajectory optimization | | F11 | Failure Recovery Coordinator | `IFailureRecoveryCoordinator` | Recovery orchestration, chunk matching | | F12 | Route Chunk Manager | `IRouteChunkManager` | Chunk lifecycle management | | F13 | Coordinate Transformer | `ICoordinateTransformer` | Coordinate conversions (GPS↔ENU↔Pixel) | | F14 | Result Manager | `IResultManager` | Result tracking and publishing | | F15 | SSE Event Streamer | `ISSEEventStreamer` | Real-time event streaming | | F16 | Model Manager | `IModelManager` | ML model loading (TensorRT/ONNX) | | F17 | Configuration Manager | `IConfigurationManager` | System configuration | ### Helper Components | ID | Helper | Interface | Purpose | |----|--------|-----------|---------| | H01 | Camera Model | `ICameraModel` | Projection/unprojection | | H02 | GSD Calculator | `IGSDCalculator` | Ground sampling distance | | H03 | Robust Kernels | `IRobustKernels` | Huber/Cauchy loss functions | | H04 | Faiss Index Manager | `IFaissIndexManager` | Similarity search | | H05 | Performance Monitor | `IPerformanceMonitor` | Timing measurements | | H06 | Web Mercator Utils | `IWebMercatorUtils` | Tile coordinate calculations | | H07 | Image Rotation Utils | `IImageRotationUtils` | Image rotation operations | | H08 | Batch Validator | `IBatchValidator` | Image batch validation | --- ## Flow 1: System Initialization **Purpose**: Initialize all system components on startup. **Sequence**: ``` ┌─────────────────┐ │ System Start │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F17 load_config │ ← Load system configuration └────────┬────────┘ ▼ ┌─────────────────┐ │ F03 Initialize │ ← Establish DB connection pool │ connections │ └────────┬────────┘ ▼ ┌─────────────────────────────────────────┐ │ F16 load_model() × 4 │ │ ├─ SuperPoint (feature extraction) │ │ ├─ LightGlue (feature matching) │ │ ├─ DINOv2 (place recognition) │ │ └─ LiteSAM (cross-view matching) │ └────────┬────────────────────────────────┘ ▼ ┌─────────────────┐ │F04 Initialize │ ← Initialize tile cache │ cache │ └────────┬────────┘ ▼ ┌─────────────────────────────────────────┐ │ F08 load_index() │ │ ← Load pre-built Faiss index from │ │ satellite provider │ └────────┬────────────────────────────────┘ ▼ ┌─────────────────┐ │ F12 Initialize │ ← Initialize chunk state tracking └────────┬────────┘ ▼ ┌─────────────────┐ │ F02.1 Ready │ ← Ready to accept flights └────────┬────────┘ ▼ ┌─────────────────┐ │ F01 Start │ ← Start FastAPI/Uvicorn │ server │ └─────────────────┘ ``` **Duration**: ~30 seconds (dominated by model loading) --- ## Flow 2: Flight Creation **Purpose**: Create a new flight with initial configuration and prefetch satellite data. **Trigger**: `POST /flights` **Sequence**: ``` ┌──────────┐ POST /flights ┌─────┐ │ Client │ ───────────────────► │ F01 │ └──────────┘ └──┬──┘ │ create_flight() ▼ ┌─────────┐ │ F02.1 │ Flight Lifecycle Manager └────┬────┘ ┌────────────────────────┬─┴─┬────────────────────────┐ │ │ │ │ ▼ │ ▼ ▼ ┌───────────────┐ │ ┌───────────────┐ ┌───────────────┐ │F17 get_flight │ │ │F13 set_enu │ │F04 prefetch │ │ _config() │ │ │ _origin() │ │ _route │ └───────────────┘ │ └───────────────┘ │ _corridor() │ │ └───────┬───────┘ │ │ ▼ ▼ ┌─────────────┐ ┌─────────────────┐ │F03 insert │ │ Satellite │ │ _flight() │ │ Provider API │ └─────────────┘ │ GET tiles/batch │ └─────────────────┘ │ ┌──────┴──────┐ │ F14 │ │create_stream│ └─────────────┘ │ ┌──────┴──────┐ SSE Connection │ Client │ ◄─────────────────────────────│ GET stream │ └─────────────┘ ``` **Output**: `flight_id`, SSE stream established --- ## Flow 3: Image Upload **Purpose**: Upload batch of UAV images for processing. **Trigger**: `POST /flights/{flightId}/images/batch` **Sequence**: ``` ┌──────────┐ POST images/batch ┌─────┐ │ Client │ ──────────────────► │ F01 │ │ │ (10-50 images) └──┬──┘ └──────────┘ │ queue_batch() ▼ ┌─────────────┐ │ F05 │ Image Input Pipeline └──────┬──────┘ ┌───────────────┼───────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │H08 validate │ │ Store to │ │F03 save │ │ _batch() │ │ disk │ │ _image │ └─────────────┘ └─────────────┘ │ _metadata()│ └─────────────┘ ``` **Validation Rules**: - Batch size: 10-50 images - Naming convention: ADxxxxxx.jpg - Sequential numbering - Image dimensions: 640×480 to 6252×4168 --- ## Flow 4: Normal Frame Processing (Tracking Good) **Purpose**: Process a single frame when tracking quality is good. **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ F02.2 Flight Processing Engine │ │ │ │ ┌─────────────┐ │ │ │ get_next │◄───────────────────────────────────────────────────────┐│ │ │ _image() │ ││ │ └──────┬──────┘ ││ │ │ F05 ││ │ ▼ ││ │ ┌─────────────────────────────────────────────────────────────┐ ││ │ │ get_active_chunk() via F12 │ ││ │ └──────────────────────────────┬──────────────────────────────┘ ││ │ ▼ ││ │ ┌─────────────────────────────────────────────────────────────┐ ││ │ │ requires_rotation_sweep()? via F06 │ ││ │ │ ├─ YES → Flow 5 (First Frame/Sharp Turn) │ ││ │ │ └─ NO → Pre-rotate to current heading │ ││ │ └──────────────────────────────┬──────────────────────────────┘ ││ │ ▼ ││ │ ┌─────────────────────────────────────────────────────────────┐ ││ │ │ F07 compute_relative_pose() │ ││ │ │ ├─ SuperPoint extract (prev + curr) via F16 │ ││ │ │ └─ LightGlue match via F16 │ ││ │ └──────────────────────────────┬──────────────────────────────┘ ││ │ │ ││ │ ┌─────────────────┼─────────────────┐ ││ │ │ Tracking Good? │ Tracking Lost? │ ││ │ ▼ ▼ ▼ ││ │ ┌─────────────────┐ ┌─────────────────────────────────┐ ││ │ │F12 add_frame │ │ →Flow 6 (Tracking Loss/Recovery)│ ││ │ │ _to_chunk() │ └─────────────────────────────────┘ ││ │ └────────┬────────┘ ││ │ ▼ ││ │ ┌─────────────────────────────────────────────────────────────┐ ││ │ │ F04 fetch_tile() + compute_tile_bounds() │ ││ │ └──────────────────────────────┬──────────────────────────────┘ ││ │ ▼ ││ │ ┌─────────────────────────────────────────────────────────────┐ ││ │ │ F09 align_to_satellite(image, tile, tile_bounds) │ ││ │ │ └─ LiteSAM matching via F16 │ ││ │ └──────────────────────────────┬──────────────────────────────┘ ││ │ │ ││ │ ┌─────────────────┴─────────────────┐ ││ │ │ Match Found? │ ││ │ ▼ ▼ ││ │ ┌──────────────────────────────────┐ ┌─────────────────────────┐ ││ │ │F10 add_absolute_factor(flight_id,│ │ Skip absolute anchor │ ││ │ │ frame_id, gps, covariance, │ │ (VO-only frame) │ ││ │ │ is_user_anchor=False) │ └─────────────────────────┘ ││ │ │F06 update_heading() │ ││ │ └────────────┬─────────────────────┘ ││ │ │ ││ │ └─────────────────────┬───────────────────────────────────┘│ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ F10 optimize_chunk(flight_id, chunk_id, iterations) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ F13 enu_to_gps() → Convert ENU pose to GPS │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ F14 update_frame_result() + publish_waypoint_update() │ │ │ │ └─ F15 send_frame_result() → SSE "frame_processed" │ │ │ │ └─ F03 save_frame_result() │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` **Performance**: < 5 seconds per frame --- ## Flow 5: First Frame / Sharp Turn (Rotation Sweep) **Purpose**: Establish UAV heading when unknown or after sharp turn. **Trigger**: `requires_rotation_sweep()` returns True **Sequence**: ``` ┌───────────────────────────────────────────────────────────────────────────┐ │ F06 Image Rotation Manager │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ try_rotation_steps(image, satellite_tile, tile_bounds) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ │ │ │ ┌───────────────────────┴────────────────────────────┐ │ │ │ For angle in [0°, 30°, 60°, ... 330°]: │ │ │ │ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ H07 rotate_image(image, angle) │ │ │ │ │ └───────────────────┬─────────────────┘ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ F09 align_to_satellite(rotated, │ │ │ │ │ │ satellite_tile, tile_bounds) │ │ │ │ │ └───────────────────┬─────────────────┘ │ │ │ │ │ │ │ │ │ ┌──────────────┴──────────────┐ │ │ │ │ │ Match Found? │ │ │ │ │ ▼ ▼ │ │ │ │ ┌───────────────┐ ┌───────────────┐ │ │ │ │ │ Calculate │ │ Try next │ │ │ │ │ │ precise angle │ │ rotation │ │ │ │ │ └───────┬───────┘ └───────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ F03 save_heading() via F06 │ │ │ │ │ │ update_heading() │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ ┌────────────┴────────────┐ │ │ │ Return RotationResult │ │ │ │ or None │ │ │ └─────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────────┘ ``` **Output**: RotationResult with precise heading angle --- ## Flow 6: Tracking Loss / Recovery (Progressive Search) **Purpose**: Recover localization after tracking loss. **Trigger**: VO inlier count < 20 or LiteSAM match fails **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ F11 Failure Recovery Coordinator │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. EMIT RecoveryStarted event │ │ │ │ └─ F02.2 updates status to "recovering" │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 2. create_chunk_on_tracking_loss() via F12 │ │ │ │ └─ Proactive chunk creation (processing continues) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 3. Single-image recovery attempt: │ │ │ │ ├─ F06 requires_rotation_sweep() → trigger sweep │ │ │ │ ├─ F08 retrieve_candidate_tiles() (DINOv2) │ │ │ │ └─ Progressive tile search (1→4→9→16→25): │ │ │ │ │ │ │ │ ┌───────────────────────────────────────────────────┐ │ │ │ │ │ For grid_size in [1, 4, 9, 16, 25]: │ │ │ │ │ │ ├─ F04 expand_search_grid() │ │ │ │ │ │ ├─ For each tile: │ │ │ │ │ │ │ ├─ F04 compute_tile_bounds() │ │ │ │ │ │ │ └─ F09 align_to_satellite(img, tile, bounds)│ │ │ │ │ │ │ │ │ │ │ │ │ └─ If match found: BREAK │ │ │ │ │ └───────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ │ │ │ ┌────────────────────┴────────────────────┐ │ │ │ Single-image match found? │ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌────────────────────────────┐ │ │ │ EMIT RecoverySucceeded│ │ Continue chunk building │ │ │ │ Resume normal flow │ │ → Flow 7 (Chunk Building) │ │ │ └─────────────────────┘ │ → Flow 8 (Chunk Matching) │ │ │ │ (Background) │ │ │ └────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ If all strategies exhausted: │ │ │ │ → Flow 10 (User Input Recovery) │ │ │ └─────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 7: Chunk Building **Purpose**: Build route chunks when tracking is lost, continuing VO within chunk. **Sequence**: ``` ┌───────────────────────────────────────────────────────────────────────────┐ │ F12 Route Chunk Manager │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ create_chunk(flight_id, start_frame_id) │ │ │ │ ├─ F10 create_chunk_subgraph(flight_id, chunk_id, │ │ │ │ │ start_frame_id) ← Factor graph subgraph │ │ │ │ ├─ Initialize chunk state (unanchored, active) │ │ │ │ └─ F03 save_chunk_state() │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ │ │ │ ┌───────────────────────┴────────────────────────────┐ │ │ │ For each frame in chunk: │ │ │ │ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ F07 compute_relative_pose() │ │ │ │ │ └───────────────────┬─────────────────┘ │ │ │ │ ▼ │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │ │ F12 add_frame_to_chunk() │ │ │ │ │ │ └─ F10 add_relative_factor_to_chunk│ │ │ │ │ │ (flight_id, chunk_id, frame_i, │ │ │ │ │ │ frame_j, relative_pose, cov) │ │ │ │ │ └───────────────────┬──────────────────┘ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ F10 optimize_chunk(flight_id, │ │ │ │ │ │ chunk_id, iterations) (local) │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ is_chunk_ready_for_matching()? │ │ │ │ ├─ Min 5 frames │ │ │ │ ├─ Max 20 frames │ │ │ │ └─ Internal consistency (good VO inlier counts) │ │ │ └─────────────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 8: Background Chunk Matching **Purpose**: Asynchronously match unanchored chunks to satellite data. **Trigger**: Background task (every 5 seconds) **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ F11 process_unanchored_chunks() (Background Task) │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ while flight_active: │ │ │ │ ├─ unanchored = F12 get_chunks_for_matching() │ │ │ │ │ │ │ │ │ └─ for chunk in unanchored: │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ if F12 is_chunk_ready_for_matching(chunk_id): │ │ │ │ │ │ ├─ F12 mark_chunk_matching(chunk_id) │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ STEP 1: Chunk Semantic Matching │ │ │ │ │ │ │ ├─ F12 get_chunk_images() │ │ │ │ │ │ │ └─ F08 retrieve_candidate_tiles_for_chunk() │ │ │ │ │ │ │ └─ F08 compute_chunk_descriptor() │ │ │ │ │ │ │ └─ H04 Faiss search() │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ STEP 2: Chunk LiteSAM Matching (with rotation) │ │ │ │ │ │ │ ├─ For each candidate tile: │ │ │ │ │ │ │ │ ├─ F04 get_tile + compute_tile_bounds() │ │ │ │ │ │ │ │ ├─ F06 try_chunk_rotation_steps() │ │ │ │ │ │ │ │ │ └─ F09 align_chunk_to_satellite() │ │ │ │ │ │ │ │ └─ If match: BREAK │ │ │ │ │ │ │ │ │ │ │ │ │ └─ If match found: │ │ │ │ │ │ └─ → Flow 9 (Chunk Merging) │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ sleep(5 seconds) │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 9: Chunk Merging **Purpose**: Merge anchored chunk into main trajectory. **Trigger**: Successful chunk matching **Sequence**: ``` ┌───────────────────────────────────────────────────────────────────────-──┐ │ F11 merge_chunk_to_trajectory() │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. Get chunk frames: F12 get_chunk_frames(chunk_id) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 2. Anchor chunk: F12 mark_chunk_anchored(chunk_id, gps) │ │ │ │ └─ F10 add_chunk_anchor(flight_id, chunk_id, frame_id, │ │ │ │ gps, covariance) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 3. Determine target chunk (predecessor or "main") │ │ │ │ └─ Returns target_chunk_id (predecessor or "main") │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 4. Merge: F12 merge_chunks(target_chunk_id, chunk_id, Sim3) │ │ │ │ ├─ F10 merge_chunk_subgraphs(flight_id, chunk_id, │ │ │ │ │ target_chunk_id, transform) ← Apply Sim(3) │ │ │ │ ├─ F12 deactivate_chunk(chunk_id) │ │ │ │ └─ F03 save_chunk_state() │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 5. Optimize global: F10 optimize_global(flight_id, │ │ │ │ iterations) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 6. EMIT ChunkMerged event (flight_id,chunk_id,merged_frames)│ │ │ │ └─ F14 subscribes → update_results_after_chunk_merge() │ │ │ │ ├─ F10 get_trajectory(flight_id) → ENU poses │ │ │ │ ├─ F13 enu_to_gps() for each frame │ │ │ │ ├─ F03 save_frame_result() + update_waypoint() │ │ │ │ └─ F15 send_refinement() → SSE "frame_refined" × N │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` **Sim(3) Transform**: Translation + Rotation + Scale alignment between chunks --- ## Flow 10: User Input Recovery **Purpose**: Request human assistance when all automatic recovery fails. **Trigger**: Progressive search exhausted (25 tiles), chunk matching failed **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ F11 create_user_input_request() │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. Get UAV image for frame_id │ │ │ │ 2. Get top-5 candidates from F08 │ │ │ │ 3. Create UserInputRequest │ │ │ │ 4. F15 send_user_input_request() → SSE "user_input_needed" │ │ │ │ 5. EMIT UserInputNeeded event │ │ │ │ └─ F02.2 updates status to "BLOCKED" │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ │ ▼ Client receives SSE event ┌───────────────────────────────────────────────────────────────────────────┐ │ Client UI │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Display UAV image + candidate satellite tiles │ │ │ │ User clicks corresponding point on satellite tile │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ POST /flights/{flightId}/user-fix │ │ │ │ body: { frame_id, uav_pixel, satellite_gps } │ │ │ └─────────────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ F11 apply_user_anchor() │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. Validate anchor data │ │ │ │ 2. F10 add_absolute_factor(is_user_anchor=True) ← σ=5m │ │ │ │ 3. F10 optimize() │ │ │ │ 4. EMIT UserFixApplied event │ │ │ │ └─ F02.2 updates status to "PROCESSING" │ │ │ │ 5. Resume processing loop │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 11: Asynchronous Refinement **Purpose**: Back-propagate optimization improvements to previous frames. **Trigger**: New absolute GPS factor added, chunk merged **Sequence**: ``` ┌─────────────────────────────────────────────────────────────-────────────┐ │ F10 Background Optimization │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. New absolute factor triggers batch optimization │ │ │ │ 2. F10 optimize(iterations=50-100) │ │ │ │ └─ Levenberg-Marquardt with robust kernels │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 3. Identify refined frames │ │ │ │ 4. F14 mark_refined(frame_ids) │ │ │ │ ├─ For each frame: │ │ │ │ │ ├─ F10 get_trajectory(flight_id) → ENU pose │ │ │ │ │ ├─ F13 enu_to_gps(flight_id, enu_pose) │ │ │ │ │ ├─ F03 save_frame_result(refined=True) │ │ │ │ │ └─ F03 update_waypoint() │ │ │ │ │ │ │ │ │ └─ F15 send_refinement() × N → SSE "frame_refined" × N │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 12: Object to GPS Conversion **Purpose**: Convert detected object pixel coordinates to GPS (external integration). **Trigger**: `POST /flights/{flightId}/frames/{frameId}/object-to-gps` **Sequence**: ``` ┌──────────────────┐ POST object-to-gps ┌─────┐ │ External System │ ────────────────────►│ F01 │ │ (Azaion.Inference│ {pixel_x, pixel_y} └──┬──┘ └──────────────────┘ │ ▼ ┌─────────────┐ │ F13 │ Coordinate Transformer └──────┬──────┘ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │F10 get_pose │ │F17 camera │ │ H01 Camera │ │ (frame_id) │ │ _params │ │ Model │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └───────────────────┼───────────────────┘ ▼ ┌─────────────┐ │ pixel_to_gps│ │ calculation │ └──────┬──────┘ │ ▼ ┌───────────────────────────┐ │ Return ObjectGPSResponse │ │ { gps, accuracy_meters }│ └───────────────────────────┘ ``` --- ## Flow 13: Flight Completion **Purpose**: Complete flight processing and clean up resources. **Trigger**: All images processed successfully **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ F02.1 Flight Lifecycle Manager │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 1. All frames processed (Signal from F02.2) │ │ │ │ 2. Wait for pending chunk merges (if any) │ │ │ │ 3. F10 optimize_global(flight_id, iterations=100) │ │ │ │ ← Final optimization │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 4. F14 mark_refined(all_frames) │ │ │ │ └─ Final refinement updates │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 5. F03 save_flight_state(status="completed") │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 6. F15 send event → SSE "flight_completed" │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 7. Cleanup: │ │ │ │ ├─ Stop background chunk matching task │ │ │ │ ├─ F04 clear_flight_cache(flight_id) (optional) │ │ │ │ └─ Release flight resources │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ ``` --- ## Flow 14: System Shutdown **Purpose**: Gracefully shutdown all components. **Sequence**: ``` ┌─────────────────┐ │ Shutdown Signal │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F01 Stop │ ← Stop accepting requests │ accepting │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F02.1 Complete/ │ ← Complete or cancel active flights │ Cancel │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F11 Stop │ ← Stop background chunk matching │ background │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F12 Save chunk │ ← Save chunk state for recovery │ state │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F16 Unload │ ← Unload ML models, free GPU memory │ models │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F03 Close │ ← Close database connections │ connections │ └────────┬────────┘ ▼ ┌─────────────────┐ │ F04 Flush cache │ ← Flush satellite tile cache └────────┬────────┘ ▼ ┌─────────────────┐ │ Shutdown │ │ Complete │ └─────────────────┘ ``` --- ## Component Interaction Summary ### Data Flow Direction ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ EXTERNAL │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Client │ │ Satellite │ │ External │ │ │ │ (UI) │ │ Provider │ │ Detector │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ └─────────┼───────────────────┼───────────────────┼───────────────────────────┘ │ REST/SSE │ HTTP │ REST ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ API LAYER │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ F01 Flight API │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ ORCHESTRATION LAYER │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ F02.1 Flight Lifecycle Manager │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ (Spawns/Manages) │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ F02.2 Flight Processing Engine │ │ │ │ (Processing loop, State machine, Recovery orchestration) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────┐ ▼ ▼ ┌─────────────────────────────────────────────┐ ┌────────────────────────────┐ │ DATA MANAGEMENT LAYER │ │ RECOVERY LAYER │ │ ┌─────────────┐ ┌─────────────┐ │ │ ┌───────────────────────┐ │ │ │ F04 │ │ F05 │ │ │ │ F11 │ │ │ │ Satellite │ │ Image │ │ │ │ Failure Recovery │ │ │ │ Data │ │ Input │ │ │ │ (Logic & Strategies) │ │ │ └─────────────┘ └─────────────┘ │ │ └───────────────────────┘ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ ▼ │ │ │ F12 │ │ F03 │ │ │ ┌───────────────────────┐ │ │ │Route Chunk │ │ Flight │ │ │ │ F12 │ │ │ │ Manager │ │ Database │ │ │ │ (Chunk state source) │ │ │ └─────────────┘ └─────────────┘ │ │ └───────────────────────┘ │ └─────────────────────────────────────────────┘ └────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ VISUAL PROCESSING LAYER │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌──────────────┐ │ │ │ F06 │ │ F07 │ │ F08 │ │ F09 │ │ │ │ Rotation │ │ Sequential VO │ │ Global │ │ Metric │ │ │ │ Manager │ │(SuperPoint+ │ │ Place │ │ Refinement │ │ │ │ (30° sweeps) │ │ LightGlue) │ │ Recognition │ │ (LiteSAM) │ │ │ │ │ │ │ │ (DINOv2) │ │ │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ STATE ESTIMATION LAYER │ │ ┌──────────────────────────────────────────────────────────────────k──┐ │ │ │ F10 Factor Graph Optimizer │ │ │ │ (GTSAM, iSAM2, Robust kernels, Chunk subgraphs, Sim(3) merging) │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ OUTPUT LAYER │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ F13 │ │ F14 │ │ F15 │ │ │ │ Coordinate │ │ Result │ │ SSE │ │ │ │ Transformer │ │ Manager │ │ Streamer │ │ │ │ (ENU↔GPS↔Px) │ │ │ │ │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────-┐ │ INFRASTRUCTURE LAYER │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────────────────────────-┐│ │ │ F16 │ │ F17 │ │ HELPERS ││ │ │ Model │ │Configuration │ │ H01-H08 (Camera, GSD, Kernels, ││ │ │ Manager │ │ Manager │ │ Faiss, Monitor, Mercator, etc) ││ │ └───────────────┘ └───────────────┘ └────────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Status-Based Recovery Communication F11 Failure Recovery Coordinator uses **Direct Call Returns** to communicate with F02.2 Flight Processing Engine. Events have been removed to eliminate circular dependencies and clarify control flow. | Action | Caller | Called | Return/Outcome | |--------|--------|--------|----------------| | `start_search` | F02.2 | F11 | `SearchSession` object | | `try_current_grid` | F02.2 | F11 | `AlignmentResult` (or None) | | `create_user_input_request` | F02.2 | F11 | `UserInputRequest` object | | `apply_user_anchor` | F02.2 | F11 | Success boolean | F02.2 is responsible for updating the flight status (e.g., "recovering", "blocked", "processing") based on these return values. --- ## SSE Events to Client | Event | Trigger | Data | |-------|---------|------| | `frame_processed` | Frame completed | frame_id, gps, altitude, heading, confidence | | `frame_refined` | Trajectory refined | frame_id, updated gps, refined=true | | `search_expanded` | Progressive search | frame_id, grid_size, status | | `user_input_needed` | Recovery exhausted | request_id, frame_id, candidate_tiles | | `processing_blocked` | Status change | reason, frame_id | | `flight_completed` | Flight done | statistics | --- ## Performance Targets | Flow | Target | |------|--------| | System Initialization | < 30 seconds | | Flight Creation | < 500ms response | | Image Batch Upload | < 2 seconds (50 images) | | Per-Frame Processing | < 5 seconds | | Rotation Sweep (12 rotations) | < 1.2 seconds | | Progressive Search (25 tiles) | < 1.5 seconds | | Chunk Matching | < 3 seconds (background) | | SSE Event Latency | < 500ms | --- ## Accuracy Targets | Metric | Target | |--------|--------| | GPS Accuracy | 60% < 20m, 80% < 50m | | Mean Reprojection Error | < 1.0 pixels | | Place Recognition Recall@5 | > 85% | | LiteSAM Success Rate | > 95% (when rotation correct) |