add chunking

This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-11-27 03:43:19 +02:00
parent 4f8c18a066
commit 2037870f67
43 changed files with 7041 additions and 4135 deletions
+214 -184
View File
@@ -1,4 +1,3 @@
<!-- 31098ee5-58fb-474a-815e-fd9cbd17c063 9f609f9e-c80d-4c88-b618-3135b96a8333 -->
# ASTRAL-Next System Component Decomposition Plan
## Design Principle: Interface-Based Architecture
@@ -24,133 +23,106 @@
## System Architecture Overview
**Two separate REST APIs in same repository:**
**Single unified Flight API:**
### Route API (Separate Project)
- Route/waypoint/geofence CRUD
- Shared by GPS-Denied and Mission Planner
- Does NOT call satellite provider
### GPS-Denied API (Main System)
- Tri-layer localization (SuperPoint+LightGlue, AnyLoc, LiteSAM)
- Flight CRUD operations (create, read, update, delete)
- Waypoint management within flights
- Geofence management
- Tri-layer localization (SuperPoint+LightGlue, DINOv2, LiteSAM)
- Calls satellite provider for tiles
- Rotation preprocessing (LiteSAM 45° limit)
- Per-frame Route API updates
- Per-frame waypoint updates
- Progressive tile search (1→4→9→16→25)
- SSE streaming for real-time results
---
## ROUTE API COMPONENTS (4 components)
## FLIGHT API COMPONENTS (17 components)
### R01_route_rest_api
### Core API Layer
**Interface**: `IRouteRestAPI`
**Endpoints**: `POST /routes`, `GET /routes/{routeId}`, `PUT /routes/{routeId}/waypoints`, `DELETE /routes/{routeId}`
**F01_flight_api**
**Interface**: `IFlightAPI`
**Endpoints**: `POST /flights`, `GET /flights/{flightId}`, `DELETE /flights/{flightId}`, `PUT /flights/{flightId}/waypoints/{waypointId}`, `POST .../images/batch`, `POST .../user-fix`, `GET .../status`, `GET .../stream`
### R02_route_data_manager
**F02_flight_processor**
**Interface**: `IFlightProcessor`
**API**: `create_flight()`, `get_flight()`, `get_flight_state()`, `delete_flight()`, `update_waypoint()`, `batch_update_waypoints()`, `validate_waypoint()`, `validate_geofence()`, `process_frame()`, `run_processing_loop()`, `handle_tracking_loss()`, `initialize_system()`
**Interface**: `IRouteDataManager`
**API**: `save_route()`, `load_route()`, `update_waypoint()`, `delete_waypoint()`, `get_route_metadata()`
### R03_waypoint_validator
**Interface**: `IWaypointValidator`
**API**: `validate_waypoint()`, `validate_geofence()`, `check_bounds()`, `validate_route_continuity()`
### R04_route_database_layer
**Interface**: `IRouteDatabase`
**API**: `insert_route()`, `update_route()`, `query_routes()`, `get_waypoints()`
---
## GPS-DENIED API COMPONENTS (17 components)
### Core REST API Layer
**G01_gps_denied_rest_api**
**Interface**: `IGPSDeniedRestAPI`
**Endpoints**: `POST /gps-denied/flights`, `POST .../images/batch`, `POST .../user-fix`, `GET .../status`, `GET .../stream`
**G02_flight_manager**
**Interface**: `IFlightManager`
**API**: `create_flight()`, `get_flight_state()`, `link_to_route()`, `update_flight_status()`
**G03_route_api_client**
**Interface**: `IRouteAPIClient`
**API**: `update_route_waypoint()`, `get_route_info()`, `batch_update_waypoints()`
**F03_flight_database**
**Interface**: `IFlightDatabase`
**API**: `insert_flight()`, `update_flight()`, `query_flights()`, `get_flight_by_id()`, `delete_flight()`, `get_waypoints()`, `insert_waypoint()`, `update_waypoint()`, `batch_update_waypoints()`, `save_flight_state()`, `load_flight_state()`, `save_frame_result()`, `get_frame_results()`, `save_heading()`, `get_heading_history()`, `get_latest_heading()`, `save_image_metadata()`, `get_image_path()`, `get_image_metadata()`
### Data Management
**G04_satellite_data_manager**
**F04_satellite_data_manager**
**Interface**: `ISatelliteDataManager`
**API**: `fetch_tile()`, `fetch_tile_grid()`, `prefetch_route_corridor()`, `progressive_fetch()`, `cache_tile()`, `get_cached_tile()`, `compute_tile_coords()`, `expand_search_grid()`
**API**: `fetch_tile()`, `fetch_tile_grid()`, `prefetch_route_corridor()`, `progressive_fetch()`, `cache_tile()`, `get_cached_tile()`, `compute_tile_coords()`, `expand_search_grid()`, `compute_tile_bounds()`
**Features**: Progressive retrieval, tile caching, grid calculations
**G05_image_input_pipeline**
**F05_image_input_pipeline**
**Interface**: `IImageInputPipeline`
**API**: `queue_batch()`, `process_next_batch()`, `validate_batch()`, `store_images()`, `get_next_image()`, `get_image_by_sequence()`
**Features**: FIFO queuing, validation, storage
**G06_image_rotation_manager**
**F06_image_rotation_manager**
**Interface**: `IImageRotationManager`
**API**: `rotate_image_360()`, `try_rotation_steps()`, `calculate_precise_angle()`, `get_current_heading()`, `update_heading()`, `detect_sharp_turn()`, `requires_rotation_sweep()`
**Features**: 30° rotation sweeps, heading tracking
### Visual Processing
**G07_sequential_visual_odometry**
**F07_sequential_visual_odometry**
**Interface**: `ISequentialVO`
**API**: `compute_relative_pose()`, `extract_features()`, `match_features()`, `estimate_motion()`
**G08_global_place_recognition**
**F08_global_place_recognition**
**Interface**: `IGlobalPlaceRecognition`
**API**: `retrieve_candidate_tiles()`, `compute_location_descriptor()`, `query_database()`, `rank_candidates()`
**G09_metric_refinement**
**F09_metric_refinement**
**Interface**: `IMetricRefinement`
**API**: `align_to_satellite()`, `compute_homography()`, `extract_gps_from_alignment()`, `compute_match_confidence()`
**API**: `align_to_satellite(uav_image, satellite_tile, tile_bounds)`, `compute_homography()`, `extract_gps_from_alignment()`, `compute_match_confidence()`
### State Estimation
**G10_factor_graph_optimizer**
**F10_factor_graph_optimizer**
**Interface**: `IFactorGraphOptimizer`
**API**: `add_relative_factor()`, `add_absolute_factor()`, `add_altitude_prior()`, `optimize()`, `get_trajectory()`
**API**: `add_relative_factor()`, `add_absolute_factor()`, `add_altitude_prior()`, `optimize()`, `get_trajectory()`, `get_marginal_covariance()`
**G11_failure_recovery_coordinator**
**F11_failure_recovery_coordinator**
**Interface**: `IFailureRecoveryCoordinator`
**API**: `check_confidence()`, `detect_tracking_loss()`, `start_search()`, `expand_search_radius()`, `try_current_grid()`, `create_user_input_request()`, `apply_user_anchor()`
**G12_coordinate_transformer**
**F12_route_chunk_manager**
**Interface**: `IRouteChunkManager`
**API**: `create_chunk()`, `add_frame_to_chunk()`, `get_chunk_frames()`, `get_chunk_images()`, `get_chunk_composite_descriptor()`, `get_chunk_bounds()`, `is_chunk_ready_for_matching()`, `mark_chunk_anchored()`, `get_chunks_for_matching()`, `get_active_chunk()`, `deactivate_chunk()`
**Features**: Chunk lifecycle management, chunk state tracking, chunk matching coordination
**F13_coordinate_transformer**
**Interface**: `ICoordinateTransformer`
**API**: `pixel_to_gps()`, `gps_to_pixel()`, `image_object_to_gps()`, `compute_gsd()`, `transform_points()`
**API**: `set_enu_origin()`, `get_enu_origin()`, `gps_to_enu()`, `enu_to_gps()`, `pixel_to_gps()`, `gps_to_pixel()`, `image_object_to_gps()`, `compute_gsd()`, `transform_points()`
### Results & Communication
**G13_result_manager**
**F14_result_manager**
**Interface**: `IResultManager`
**API**: `update_frame_result()`, `publish_to_route_api()`, `get_flight_results()`, `mark_refined()`
**API**: `update_frame_result()`, `publish_waypoint_update()`, `get_flight_results()`, `mark_refined()`
**G14_sse_event_streamer**
**F15_sse_event_streamer**
**Interface**: `ISSEEventStreamer`
**API**: `create_stream()`, `send_frame_result()`, `send_search_progress()`, `send_user_input_request()`, `send_refinement()`
### Infrastructure
**G15_model_manager**
**F16_model_manager**
**Interface**: `IModelManager`
**API**: `load_model()`, `get_inference_engine()`, `optimize_to_tensorrt()`, `fallback_to_onnx()`
**G16_configuration_manager**
**F17_configuration_manager**
**Interface**: `IConfigurationManager`
**API**: `load_config()`, `get_camera_params()`, `validate_config()`, `get_flight_config()`
**G17_gps_denied_database_layer**
**Interface**: `IGPSDeniedDatabase`
**API**: `save_flight_state()`, `load_flight_state()`, `query_processing_history()`
---
## HELPER COMPONENTS (8 components)
@@ -166,156 +138,217 @@
---
## System Startup Initialization Order
**Startup sequence** (blocking, sequential):
| Order | Component | Method | Purpose | Dependencies |
|-------|-----------|--------|---------|--------------|
| 1 | F16 Configuration Manager | `load_config()` | Load system configuration | None |
| 2 | F03 Flight Database | Initialize connections | Establish DB connection pool | F16 |
| 3 | F15 Model Manager | `load_model("SuperPoint")` | Load SuperPoint feature extractor | F16 |
| 4 | F15 Model Manager | `load_model("LightGlue")` | Load LightGlue matcher | F16 |
| 5 | F15 Model Manager | `load_model("DINOv2")` | Load DINOv2 for place recognition | F16 |
| 6 | F15 Model Manager | `load_model("LiteSAM")` | Load LiteSAM for cross-view matching | F16 |
| 7 | F04 Satellite Data Manager | Initialize cache | Initialize tile cache directory | F16 |
| 8 | F08 Global Place Recognition | `build_index()` or `load_index()` | Build/load Faiss index from satellite tiles | F04, F15, H04 |
| 9 | F12 Route Chunk Manager | Initialize | Initialize chunk state tracking | F10 |
| 10 | F02 Flight Processor | Ready | Ready to accept flights | All above |
| 11 | F01 Flight API | Start server | Start FastAPI/Uvicorn | F02 |
**Estimated total startup time**: ~30 seconds (dominated by model loading)
**Shutdown sequence** (reverse order):
1. F01 Flight API - Stop accepting requests
2. F02 Flight Processor - Complete or cancel active flights
3. F11 Failure Recovery Coordinator - Stop background chunk matching
4. F12 Route Chunk Manager - Save chunk state
5. F16 Model Manager - Unload models
6. F03 Flight Database - Close connections
7. F04 Satellite Data Manager - Flush cache
---
## Comprehensive Component Interaction Matrix
### System Initialization
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G02 | G15 | `load_model()` × 4 | Load SuperPoint, LightGlue, DINOv2, LiteSAM |
| G02 | G16 | `load_config()` | Load system configuration |
| G04 | G08 | Satellite tiles | G08 generates descriptors for Faiss |
| G08 | H04 | `build_index()` | Build satellite descriptor index |
| G08 | G15 | `get_inference_engine("DINOv2")` | Get model for descriptor generation |
| F02 | F16 | `load_config()` | Load system configuration |
| F02 | F15 | `load_model()` × 4 | Load SuperPoint, LightGlue, DINOv2, LiteSAM |
| F04 | F08 | Satellite tiles | F08 generates descriptors for Faiss |
| F08 | H04 | `build_index()` | Build satellite descriptor index |
| F08 | F15 | `get_inference_engine("DINOv2")` | Get model for descriptor generation |
### Flight Creation
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| Client | G01 | `POST /gps-denied/flights` | Create flight |
| G01 | G02 | `create_flight()` | Initialize flight state |
| G02 | G16 | `get_flight_config()` | Get camera params, altitude |
| G02 | G03 | `get_route_info()` | Fetch route metadata |
| G03 | Route API | `GET /routes/{routeId}` | HTTP call |
| G02 | G04 | `prefetch_route_corridor()` | Prefetch tiles |
| G04 | Satellite Provider | `GET /api/satellite/tiles/batch` | HTTP batch download |
| G04 | H06 | `compute_tile_bounds()` | Tile coordinate calculations |
| G02 | G17 | `save_flight_state()` | Persist flight metadata |
| Client | G01 | `GET .../stream` | Open SSE connection |
| G01 | G14 | `create_stream()` | Establish SSE channel |
| Client | F01 | `POST /flights` | Create flight |
| F01 | F02 | `create_flight()` | Initialize flight state |
| F02 | F16 | `get_flight_config()` | Get camera params, altitude |
| F02 | F12 | `set_enu_origin(start_gps)` | Set ENU coordinate origin |
| F02 | F04 | `prefetch_route_corridor()` | Prefetch tiles |
| F04 | Satellite Provider | `GET /api/satellite/tiles/batch` | HTTP batch download |
| F04 | H06 | `compute_tile_bounds()` | Tile coordinate calculations |
| F02 | F03 | `insert_flight()` | Persist flight data |
| Client | F01 | `GET .../stream` | Open SSE connection |
| F01 | F14 | `create_stream()` | Establish SSE channel |
### Image Upload
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| Client | G01 | `POST .../images/batch` | Upload 10-50 images |
| G01 | G05 | `queue_batch()` | Queue for processing |
| G05 | H08 | `validate_batch()` | Validate sequence, format |
| G05 | G17 | `store_images()` | Persist images |
| Client | F01 | `POST .../images/batch` | Upload 10-50 images |
| F01 | F05 | `queue_batch()` | Queue for processing |
| F05 | H08 | `validate_batch()` | Validate sequence, format |
| F05 | F03 | `save_image_metadata()` | Persist image metadata |
### Per-Frame Processing (First Frame / Sharp Turn)
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G05 | G06 | `get_next_image()` | Get image for processing |
| G06 | G06 | `requires_rotation_sweep()` | Check if sweep needed |
| G06 | H07 | `rotate_image()` × 12 | Rotate in 30° steps |
| G06 | G09 | `align_to_satellite()` × 12 | Try LiteSAM each rotation |
| G09 | G04 | `get_cached_tile()` | Get expected tile |
| G09 | G15 | `get_inference_engine("LiteSAM")` | Get model |
| G06 | H07 | `calculate_rotation_from_points()` | Precise angle from homography |
| G06 | Internal | `update_heading()` | Store UAV heading |
| F02 | F05 | `get_next_image()` | Get image for processing |
| F02 | F06 | `requires_rotation_sweep()` | Check if sweep needed |
| F06 | H07 | `rotate_image()` × 12 | Rotate in 30° steps |
| F06 | F09 | `align_to_satellite(img, tile, bounds)` × 12 | Try LiteSAM each rotation |
| F06 | F04 | `get_cached_tile()` + `compute_tile_bounds()` | Get expected tile with bounds |
| F09 | F15 | `get_inference_engine("LiteSAM")` | Get model |
| F06 | H07 | `calculate_rotation_from_points()` | Precise angle from homography |
| F06 | F03 | `save_heading()` | Store UAV heading |
### Per-Frame Processing (Sequential VO)
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G05 | G07 | `get_next_image()` | Provide image |
| G07 | G15 | `get_inference_engine("SuperPoint")` | Get feature extractor |
| G07 | G15 | `get_inference_engine("LightGlue")` | Get matcher |
| G07 | H05 | `start_timer()`, `end_timer()` | Monitor timing |
| G07 | G10 | `add_relative_factor()` | Add pose measurement |
| F02 | F12 | `get_active_chunk()` | Get active chunk for frame |
| F02 | F07 | Process frame | Provide image and chunk context |
| F07 | F16 | `get_inference_engine("SuperPoint")` | Get feature extractor |
| F07 | F16 | `get_inference_engine("LightGlue")` | Get matcher |
| F07 | H05 | `start_timer()`, `end_timer()` | Monitor timing |
| F07 | F10 | `add_relative_factor_to_chunk()` | Add pose measurement to chunk subgraph |
| F02 | F12 | `add_frame_to_chunk()` | Add frame to chunk |
### Tracking Good (Drift Correction)
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G07 | G11 | `check_confidence()` | Check tracking quality |
| G11 | G09 | `align_to_satellite()` | Align to 1 tile |
| G09 | G04 | `get_tile_grid(1)` | Get single tile |
| G09 | G10 | `add_absolute_factor()` | Add GPS measurement |
| F02 | F11 | `check_confidence()` | Check tracking quality |
| F02 | F04 | `fetch_tile()` + `compute_tile_bounds()` | Get single tile with bounds |
| F02 | F09 | `align_to_satellite(img, tile, bounds)` | Align to 1 tile |
| F02 | F10 | `add_absolute_factor()` | Add GPS measurement |
### Tracking Lost (Progressive Search)
### Tracking Lost (Progressive Search + Chunk Building)
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G07 | G11 | `check_confidence()` → FAIL | Low confidence |
| G11 | G06 | `requires_rotation_sweep()` | Trigger rotation sweep |
| G11 | G08 | `retrieve_candidate_tiles()` | Coarse localization |
| G08 | G15 | `get_inference_engine("DINOv2")` | Get model |
| G08 | H04 | `search()` | Query Faiss index |
| G08 | G04 | `get_tile_by_gps()` × 5 | Get candidate tiles |
| G11 | G04 | `expand_search_grid(4)` | Get 2×2 grid |
| G11 | G09 | `align_to_satellite()` | Try LiteSAM on 4 tiles |
| G11 (fail) | G04 | `expand_search_grid(9)` | Expand to 3×3 |
| G11 (fail) | G04 | `expand_search_grid(16)` | Expand to 4×4 |
| G11 (fail) | G04 | `expand_search_grid(25)` | Expand to 5×5 |
| G11 (fail) | G14 | `send_user_input_request()` | Request human help |
| G11 | G02 | `update_flight_status("BLOCKED")` | Block processing |
| F02 | F11 | `check_confidence()` → FAIL | Low confidence |
| F11 | F12 | `create_chunk_on_tracking_loss()` | **Proactive chunk creation** |
| F12 | F10 | `create_new_chunk()` | Create chunk in factor graph |
| F02 | F12 | `get_active_chunk()` | Get new active chunk |
| F11 | F06 | `requires_rotation_sweep()` | Trigger rotation sweep (single-image) |
| F11 | F08 | `retrieve_candidate_tiles()` | Coarse localization (single-image) |
| F08 | F15 | `get_inference_engine("DINOv2")` | Get model |
| F08 | H04 | `search()` | Query Faiss index |
| F08 | F04 | `get_tile_by_gps()` × 5 | Get candidate tiles |
| F11 | F04 | `expand_search_grid(4)` | Get 2×2 grid |
| F11 | F09 | `align_to_satellite(img, tile, bounds)` | Try LiteSAM on tiles |
| F11 (fail) | F04 | `expand_search_grid(9)` | Expand to 3×3 |
| F11 (fail) | F04 | `expand_search_grid(16)` | Expand to 4×4 |
| F11 (fail) | F04 | `expand_search_grid(25)` | Expand to 5×5 |
| F11 (fail) | F03 | Continue building chunk | **Chunk building continues** |
| F11 (background) | F03 | `get_chunks_for_matching()` | Get unanchored chunks |
| F11 (background) | F08 | `retrieve_candidate_tiles_for_chunk()` | **Chunk semantic matching** |
| F11 (background) | F06 | `try_chunk_rotation_steps()` | **Chunk rotation sweeps** |
| F11 (background) | F09 | `align_chunk_to_satellite()` | **Chunk LiteSAM matching** |
| F11 (background) | F10 | `add_chunk_anchor()` + `merge_chunks()` | **Chunk merging** |
| F11 (fail) | F14 | `send_user_input_request()` | Request human help (last resort) |
| F11 | F02 | `update_flight_status("BLOCKED")` | Block processing |
### Optimization & Results
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G10 | H03 | `huber_loss()`, `cauchy_loss()` | Apply robust kernels |
| G10 | Internal | `optimize()` | Run iSAM2 optimization |
| G10 | G12 | `get_trajectory()` | Get optimized poses |
| G12 | H01 | `project()`, `unproject()` | Camera operations |
| G12 | H02 | `compute_gsd()` | GSD calculations |
| G12 | H06 | `tile_to_latlon()` | Coordinate transforms |
| G12 | G13 | Frame GPS + object coords | Provide results |
| G13 | G03 | `update_route_waypoint()` | Per-frame Route API update |
| G03 | Route API | `PUT /routes/.../waypoints/...` | HTTP call |
| G13 | G14 | `send_frame_result()` | Publish to client |
| G14 | Client | SSE `frame_processed` | Real-time delivery |
| G13 | G17 | `save_flight_state()` | Persist state |
| F10 | H03 | `huber_loss()`, `cauchy_loss()` | Apply robust kernels |
| F10 | Internal | `optimize()` | Run iSAM2 optimization |
| F02 | F10 | `get_trajectory()` | Get optimized poses |
| F02 | F13 | `enu_to_gps()` | Convert ENU to GPS |
| F13 | H01 | `project()`, `unproject()` | Camera operations |
| F13 | H02 | `compute_gsd()` | GSD calculations |
| F13 | H06 | `tile_to_latlon()` | Coordinate transforms |
| F02 | F14 | Frame GPS + object coords | Provide results |
| F14 | F02 | `update_waypoint()` | Per-frame waypoint update |
| F14 | F15 | `send_frame_result()` | Publish to client |
| F15 | Client | SSE `frame_processed` | Real-time delivery |
| F14 | F03 | `save_frame_result()` | Persist frame result |
### User Input Recovery
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G14 | Client | SSE `user_input_needed` | Notify client |
| Client | G01 | `POST .../user-fix` | Provide anchor |
| G01 | G11 | `apply_user_anchor()` | Apply fix |
| G11 | G10 | `add_absolute_factor()` (high confidence) | Hard constraint |
| G10 | Internal | `optimize()` | Re-optimize |
| G11 | G02 | `update_flight_status("PROCESSING")` | Resume |
| F15 | Client | SSE `user_input_needed` | Notify client |
| Client | F01 | `POST .../user-fix` | Provide anchor |
| F01 | F11 | `apply_user_anchor()` | Apply fix |
| F11 | F10 | `add_absolute_factor()` (high confidence) | Hard constraint |
| F10 | Internal | `optimize()` | Re-optimize |
| F11 | F02 | `update_flight_status("PROCESSING")` | Resume |
### Asynchronous Refinement
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G10 | Internal (background) | `optimize()` | Back-propagate anchors |
| G10 | G13 | `get_trajectory()` | Get refined poses |
| G13 | G03 | `batch_update_waypoints()` | Batch update Route API |
| G13 | G14 | `send_refinement()` × N | Send updates |
| G14 | Client | SSE `frame_refined` × N | Incremental updates |
| F10 | Internal (background) | `optimize()` | Back-propagate anchors |
| F10 | F14 | `get_trajectory()` | Get refined poses |
| F14 | F02 | `batch_update_waypoints()` | Batch update waypoints |
| F14 | F15 | `send_refinement()` × N | Send updates |
| F15 | Client | SSE `frame_refined` × N | Incremental updates |
### Chunk Matching (Background)
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| F11 (background) | F12 | `get_chunks_for_matching()` | Get unanchored chunks ready for matching |
| F11 | F12 | `get_chunk_images()` | Get chunk images |
| F11 | F08 | `retrieve_candidate_tiles_for_chunk()` | Chunk semantic matching (aggregate DINOv2) |
| F08 | F16 | `get_inference_engine("DINOv2")` | Get model for descriptor computation |
| F08 | H04 | `search()` | Query Faiss with chunk descriptor |
| F11 | F06 | `try_chunk_rotation_steps()` | Chunk rotation sweeps (12 rotations) |
| F06 | F09 | `align_chunk_to_satellite()` × 12 | Try LiteSAM for each rotation |
| F11 | F10 | `add_chunk_anchor()` | Anchor chunk with GPS |
| F11 | F10 | `merge_chunks()` | Merge chunk to main trajectory (Sim3) |
| F10 | Internal | `optimize_global()` | Global optimization after merging |
| F11 | F12 | `mark_chunk_anchored()` | Update chunk state |
### Cross-Cutting Concerns
| Source | Target | Method | Purpose |
|--------|--------|--------|---------|
| G16 | ALL | `get_*_config()` | Provide configuration |
| H05 | G07, G08, G09, G10, G11 | `start_timer()`, `end_timer()` | Performance monitoring |
| F16 | ALL | `get_*_config()` | Provide configuration |
| H05 | F07, F08, F09, F10, F11 | `start_timer()`, `end_timer()` | Performance monitoring |
---
## Interaction Coverage Verification
**Initialization**: G02→G15, G16, G17; G04→G08→H04
**Flight creation**: Client→G01→G02→G03,G04,G16,G17,G14
**Image upload**: Client→G01→G05→H08,G17
**Rotation sweep**: G06→H07,G09 (12 iterations)
**Sequential VO**: G07→G15,G10,H05
**Drift correction**: G11→G09→G04(1),G10
**Tracking loss**: G11→G06,G08,G04(progressive),G09,G14,G02
**Global PR**: G08→G15,H04,G04
**Optimization**: G10→H03,G12
**Coordinate transform**: G12→H01,H02,H06
**Results**: G12→G13→G03,G14,G17
**User input**: Client→G01→G11→G10,G02
**Refinement**: G10→G13→G03,G14
**Configuration**: G16→ALL
**Initialization**: F02→F15, F16, F17; F04→F08→H04
**Flight creation**: Client→F01→F02→F04,F12,F16,F17,F14
**Image upload**: Client→F01→F05→H08,F17
**Rotation sweep**: F06→H07,F09 (12 iterations)
**Sequential VO**: F07→F16,F10(chunk),F12,H05
**Drift correction**: F02→F04,F09,F10
**Tracking loss**: F11→F12(proactive chunk),F06,F08,F04(progressive),F09,F15,F02
**Chunk building**: F02→F12→F10,F07
**Chunk semantic matching**: F11→F12→F08(chunk descriptor)
**Chunk LiteSAM matching**: F11→F06(chunk rotation)→F09(chunk alignment)
**Chunk merging**: F11→F10(Sim3 transform)
**Global PR**: F08→F16,H04,F04
**Optimization**: F10→H03(chunk optimization, global optimization)
**Coordinate transform**: F13→H01,H02,H06
**Results**: F02→F13→F14→F15,F03
**User input**: Client→F01→F11→F10,F02
**Refinement**: F10→F14→F02,F15
**Configuration**: F17→ALL
**Performance**: H05→processing components
**All major component interactions are covered.**
@@ -324,13 +357,12 @@
## Deliverables
**Component Count**: 29 total
**Component Count**: 25 total
- Route API: 4 (R01-R04)
- GPS-Denied API: 17 (G01-G17)
- Flight API: 17 (F01-F17)
- Helpers: 8 (H01-H08)
**For each component**, create `docs/02_components/[project]_[##]_[component_name]/[component_name]_spec.md`:
**For each component**, create `docs/02_components/[##]_[component_name]/[component_name]_spec.md`:
1. **Interface Definition** (interface name, methods, contracts)
2. **Component Description** (responsibilities, scope)
@@ -340,25 +372,23 @@
6. **Dependencies** (which components it calls)
7. **Data Models**
**Generate draw.io diagram** showing:
- Two API projects (Route API, GPS-Denied API)
- All 29 components
- Route API ↔ GPS-Denied API communication
- GPS-Denied → Satellite Provider calls
- Rotation preprocessing flow
- Progressive search expansion (1→4→9→16→25)
- Per-frame Route API update flow
- Helper component usage
### To-dos
- [x] Create 4 Route API specs with interfaces (REST, data manager, validator, DB)
- [x] Create GPS-Denied core API specs with interfaces (REST, flight manager, Route client)
- [x] Create data management specs with interfaces (satellite, image pipeline, rotation)
- [x] Create visual processing specs with interfaces (VO, place recognition, LiteSAM)
- [x] Create coordination specs with interfaces (factor graph, failure recovery, transformer)
- [x] Create results/infrastructure specs with interfaces (result manager, SSE, models, config, DB)
- [x] Create 8 helper specs with interfaces
- [x] Generate draw.io with all components, interactions, flows
### Component Specifications Status
- [x] F01 Flight API (merged from R01 Route REST API)
- [x] F02 Flight Processor (merged from R02, R03, G02)
- [x] F04 Satellite Data Manager
- [x] F05 Image Input Pipeline
- [x] F06 Image Rotation Manager
- [x] F07 Sequential Visual Odometry
- [x] F08 Global Place Recognition
- [x] F09 Metric Refinement
- [x] F10 Factor Graph Optimizer
- [x] F11 Failure Recovery Coordinator
- [x] F12 Route Chunk Manager (Atlas multi-map chunk lifecycle)
- [x] F13 Coordinate Transformer (with ENU origin)
- [x] F14 Result Manager
- [x] F15 SSE Event Streamer
- [x] F16 Model Manager
- [x] F17 Configuration Manager
- [x] F03 Flight Database (merged from R04, G17)
- [x] Helper components (H01-H08)