diff --git a/docs/01_whitepapers/A_Cross-View_Geo-Localization_Algorithm_Using_UAV_.pdf b/docs/01_whitepapers/A_Cross-View_Geo-Localization_Algorithm_Using_UAV_.pdf deleted file mode 100644 index 6d950c4..0000000 Binary files a/docs/01_whitepapers/A_Cross-View_Geo-Localization_Algorithm_Using_UAV_.pdf and /dev/null differ diff --git a/docs/01_whitepapers/AnyVisLoc.pdf b/docs/01_whitepapers/AnyVisLoc.pdf deleted file mode 100644 index e8a3121..0000000 Binary files a/docs/01_whitepapers/AnyVisLoc.pdf and /dev/null differ diff --git a/docs/02_components/10_factor_graph_optimizer/factor_graph_optimizer_spec.md b/docs/02_components/10_factor_graph_optimizer/factor_graph_optimizer_spec.md index 8319541..323d053 100644 --- a/docs/02_components/10_factor_graph_optimizer/factor_graph_optimizer_spec.md +++ b/docs/02_components/10_factor_graph_optimizer/factor_graph_optimizer_spec.md @@ -61,8 +61,8 @@ class IFactorGraphOptimizer(ABC): pass @abstractmethod - def merge_chunk_subgraphs(self, flight_id: str, source_chunk_id: str, target_chunk_id: str, transform: Sim3Transform) -> bool: - """Merges source_chunk INTO target_chunk. Source chunk subgraph is merged into target.""" + def merge_chunk_subgraphs(self, flight_id: str, new_chunk_id: str, main_chunk_id: str, transform: Sim3Transform) -> bool: + """Merges new_chunk INTO main_chunk. Extends main_chunk with new_chunk's subgraph.""" pass @abstractmethod @@ -523,18 +523,18 @@ bool: True if anchor added --- -### `merge_chunks(chunk_id_1: str, chunk_id_2: str, transform: Sim3Transform) -> bool` +### `merge_chunk_subgraphs(flight_id: str, new_chunk_id: str, main_chunk_id: str, transform: Sim3Transform) -> bool` -**Description**: Merges two chunks using Sim(3) similarity transformation. +**Description**: Merges new_chunk INTO main_chunk using Sim(3) similarity transformation. Extends main_chunk with new_chunk's frames. **Called By**: -- F11 Failure Recovery Coordinator (after chunk matching) -- Background optimization task +- F12 Route Chunk Manager (via merge_chunks method) **Input**: ```python -chunk_id_1: str # Source chunk (typically newer) -chunk_id_2: str # Target chunk (typically older, merged into) +flight_id: str # Flight identifier +new_chunk_id: str # New chunk being merged (source, typically newer/recently anchored) +main_chunk_id: str # Main chunk being extended (destination, typically older/established) transform: Sim3Transform: translation: np.ndarray # (3,) rotation: np.ndarray # (3, 3) or quaternion @@ -547,11 +547,11 @@ bool: True if merge successful ``` **Processing Flow**: -1. Verify both chunks exist and chunk_id_1 is anchored -2. Apply Sim(3) transform to all poses in chunk_id_1 -3. Merge chunk_id_1's subgraph into chunk_id_2's subgraph -4. Update frame-to-chunk mapping -5. Mark chunk_id_1 as merged +1. Verify both chunks exist and new_chunk is anchored +2. Apply Sim(3) transform to all poses in new_chunk +3. Merge new_chunk's subgraph into main_chunk's subgraph +4. Update frame-to-chunk mapping (new_chunk frames now belong to main_chunk) +5. Mark new_chunk subgraph as merged (F12 handles state updates) 6. Optimize merged graph globally **Sim(3) Transformation**: @@ -560,7 +560,7 @@ bool: True if merge successful - Preserves internal consistency of both chunks **Test Cases**: -1. **Merge anchored chunks**: Chunks merged successfully +1. **Merge anchored chunks**: new_chunk merged into main_chunk successfully 2. **Merge unanchored chunk**: Returns False 3. **Global consistency**: Merged trajectory is globally consistent diff --git a/docs/02_components/11_failure_recovery_coordinator/failure_recovery_coordinator_spec.md b/docs/02_components/11_failure_recovery_coordinator/failure_recovery_coordinator_spec.md index a08deae..5b2b302 100644 --- a/docs/02_components/11_failure_recovery_coordinator/failure_recovery_coordinator_spec.md +++ b/docs/02_components/11_failure_recovery_coordinator/failure_recovery_coordinator_spec.md @@ -123,6 +123,24 @@ This separation ensures: - **Chunk lifecycle and matching coordination** - **Multi-chunk simultaneous processing** +### Architecture Note: Single Responsibility Consideration + +F11 has extensive responsibilities including progressive search, chunk creation coordination, chunk matching coordination (semantic + LiteSAM), chunk merging coordination, and user input handling. While this represents significant scope, these remain together in a single component because: + +1. **Tight Coupling**: All recovery strategies share state (SearchSession, chunk status) and need coordinated fallback logic (progressive search → chunk matching → user input). + +2. **Sequential Dependency**: Chunk semantic matching feeds into chunk LiteSAM matching, which feeds into chunk merging. Splitting these would create circular dependencies or complex event choreography. + +3. **Pure Logic Pattern**: F11 remains a pure logic component (no I/O, no threads). All execution is delegated to F02.2, keeping F11 focused on decision-making rather than coordination. + +4. **Single Point of Recovery Policy**: Having all recovery strategies in one component makes the fallback logic explicit and maintainable. The alternative—multiple coordinators—would require a meta-coordinator. + +**Future Consideration**: If F11 grows beyond ~1000 lines or if specific recovery strategies need independent evolution, consider splitting into: +- `F11a_search_coordinator` - Progressive search, user input handling +- `F11b_chunk_recovery_coordinator` - Chunk semantic matching, LiteSAM matching, merging + +For now, the component remains unified with clear internal organization (search methods, chunk methods). + ## API Methods ### `check_confidence(vo_result: RelativePose, litesam_result: Optional[AlignmentResult]) -> ConfidenceAssessment` @@ -518,11 +536,11 @@ bool: True if merge successful 2. Get chunk anchor frame (middle frame or best frame) 3. Call F12.mark_chunk_anchored() with GPS (F12 coordinates with F10) 4. **Determine merge target**: - - Target is typically the temporal predecessor (previous chunk by frame_id order) - - If no predecessor: merge to main trajectory (target_chunk_id="main") - - F11 determines target based on chunk frame_id ordering -5. Call F12.merge_chunks(target_chunk_id, chunk_id, transform) - - Note: `merge_chunks(target, source)` merges source INTO target + - Main chunk is typically the temporal predecessor (previous chunk by frame_id order) + - If no predecessor: merge to main trajectory (main_chunk_id="main") + - F11 determines main_chunk based on chunk frame_id ordering +5. Call F12.merge_chunks(main_chunk_id, chunk_id, transform) + - Note: `merge_chunks(main_chunk, new_chunk)` merges new_chunk INTO main_chunk - chunk_id (source) is merged into target_chunk_id 6. F12 handles chunk state updates (deactivation, status updates) 7. F10 optimizes merged graph globally (via F12.merge_chunks()) diff --git a/docs/02_components/12_route_chunk_manager/route_chunk_manager_spec.md b/docs/02_components/12_route_chunk_manager/route_chunk_manager_spec.md index d4a2e82..17a4af0 100644 --- a/docs/02_components/12_route_chunk_manager/route_chunk_manager_spec.md +++ b/docs/02_components/12_route_chunk_manager/route_chunk_manager_spec.md @@ -59,12 +59,16 @@ class IRouteChunkManager(ABC): pass @abstractmethod - def merge_chunks(self, target_chunk_id: str, source_chunk_id: str, transform: Sim3Transform) -> bool: + def merge_chunks(self, main_chunk_id: str, new_chunk_id: str, transform: Sim3Transform) -> bool: """ + Merges new_chunk INTO main_chunk. Extends main_chunk with new_chunk's frames. + Transactional update: - 1. Calls F10.merge_chunk_subgraphs(). - 2. IF success: Updates internal state (source merged/deactivated). + 1. Calls F10.merge_chunk_subgraphs(flight_id, new_chunk_id, main_chunk_id, transform). + 2. IF success: Updates internal state (new_chunk merged/deactivated). 3. Returns success status. + + Note: flight_id is obtained from the ChunkHandle stored internally for main_chunk_id. """ pass @@ -88,6 +92,14 @@ class IRouteChunkManager(ABC): - **Transactional Integrity**: Ensures internal state updates are atomic with respect to Factor Graph (F10) operations. - **Implementation**: Uses "Check-Act" pattern. Calls F10 first; if F10 fails, F12 does not update state and returns error. +### Internal State Management +F12 maintains an internal dictionary of `ChunkHandle` objects keyed by `chunk_id`. Each `ChunkHandle` contains `flight_id`, allowing F12 to resolve flight context for F10 calls without requiring `flight_id` as a parameter on every method. This simplifies the API for callers while maintaining flight isolation internally. + +```python +# Internal state +_chunks: Dict[str, ChunkHandle] # chunk_id -> ChunkHandle (contains flight_id) +``` + ### Interaction - Called by **F02.2 Flight Processing Engine** and **F11 Failure Recovery Coordinator** (via F02.2 or direct delegation). - Calls **F10 Factor Graph Optimizer**. @@ -311,17 +323,17 @@ gps: GPSPoint --- -### `merge_chunks(target_chunk_id: str, source_chunk_id: str, transform: Sim3Transform) -> bool` +### `merge_chunks(main_chunk_id: str, new_chunk_id: str, transform: Sim3Transform) -> bool` -**Description**: Merges source_chunk INTO target_chunk. The resulting merged chunk is target_chunk. Source chunk is deactivated after merge. +**Description**: Merges new_chunk INTO main_chunk. The resulting merged chunk is main_chunk (extended with new_chunk's frames). new_chunk is deactivated after merge. **Called By**: - F11 Failure Recovery Coordinator (after successful chunk matching) **Input**: ```python -target_chunk_id: str # Target chunk (receives the merge, typically older/main) -source_chunk_id: str # Source chunk (being merged in, typically newer) +main_chunk_id: str # Main chunk being extended (destination, typically older/established trajectory) +new_chunk_id: str # New chunk being merged in (source, typically newer/recently anchored) transform: Sim3Transform: translation: np.ndarray # (3,) rotation: np.ndarray # (3, 3) or quaternion @@ -330,21 +342,24 @@ transform: Sim3Transform: **Output**: `bool` - True if merge successful +**flight_id Resolution**: F12 internally stores ChunkHandle objects keyed by chunk_id. The flight_id is extracted from the ChunkHandle for main_chunk_id when calling F10 methods. + **Processing Flow**: -1. Call F10.merge_chunk_subgraphs(flight_id, source_chunk_id, target_chunk_id, transform) -2. If successful: - - Update source_chunk_id state: +1. Get flight_id from internally stored ChunkHandle for main_chunk_id +2. Call F10.merge_chunk_subgraphs(flight_id, new_chunk_id, main_chunk_id, transform) +3. If successful: + - Update new_chunk_id state: - Set is_active=False - Set matching_status="merged" - - Call deactivate_chunk(source_chunk_id) - - target_chunk remains active (now contains merged frames) + - Call deactivate_chunk(new_chunk_id) + - main_chunk remains active (now contains merged frames) - Persist chunk state via F03 Flight Database.save_chunk_state() -3. Return True +4. Return True **Test Cases**: -1. **Merge anchored chunk**: source_chunk merged into target_chunk -2. **Source deactivated**: source_chunk marked as merged and deactivated -3. **Target unchanged**: target_chunk remains active with new frames +1. **Merge anchored chunk**: new_chunk merged into main_chunk +2. **New chunk deactivated**: new_chunk marked as merged and deactivated +3. **Main chunk extended**: main_chunk remains active with additional frames --- @@ -380,11 +395,12 @@ transform: Sim3Transform: 5. get_chunks_for_matching() → returns only chunk_2 ### Test 4: Chunk Merging -1. Create chunk_1 (frames 1-10), chunk_2 (frames 20-30) -2. Anchor chunk_1 via mark_chunk_anchored() -3. merge_chunks(chunk_1, chunk_2, transform) → chunks merged -4. Verify chunk_1 marked as merged and deactivated -5. Verify F10 merge_chunks() called +1. Create main_chunk (frames 1-10), new_chunk (frames 20-30) +2. Anchor new_chunk via mark_chunk_anchored() +3. merge_chunks(main_chunk, new_chunk, transform) → new_chunk merged into main_chunk +4. Verify new_chunk marked as merged and deactivated +5. Verify main_chunk extended with new frames +6. Verify F10.merge_chunk_subgraphs() called with correct parameters ### Test 5: Chunk Matching Status 1. Create chunk diff --git a/docs/02_components/14_result_manager/result_manager_spec.md b/docs/02_components/14_result_manager/result_manager_spec.md index c5e6390..e118b13 100644 --- a/docs/02_components/14_result_manager/result_manager_spec.md +++ b/docs/02_components/14_result_manager/result_manager_spec.md @@ -27,7 +27,15 @@ class IResultManager(ABC): pass @abstractmethod - def mark_refined(self, flight_id: str, frame_ids: List[int]) -> bool: + def mark_refined(self, flight_id: str, refined_results: List[RefinedFrameResult]) -> bool: + """ + Updates results for frames that have been retrospectively improved. + + Args: + flight_id: Flight identifier + refined_results: List of RefinedFrameResult containing frame_id and GPS-converted coordinates + (caller F02.2 converts ENU to GPS before calling this method) + """ pass @abstractmethod @@ -35,7 +43,15 @@ class IResultManager(ABC): pass @abstractmethod - def update_results_after_chunk_merge(self, flight_id: str, merged_frames: List[int]) -> bool: + def update_results_after_chunk_merge(self, flight_id: str, refined_results: List[RefinedFrameResult]) -> bool: + """ + Updates results for frames affected by chunk merge. + + Args: + flight_id: Flight identifier + refined_results: List of RefinedFrameResult with GPS-converted coordinates + (caller F02.2 converts ENU to GPS before calling this method) + """ pass ``` @@ -141,35 +157,37 @@ FlightResults: --- -### `mark_refined(flight_id: str, frame_ids: List[int]) -> bool` +### `mark_refined(flight_id: str, refined_results: List[RefinedFrameResult]) -> bool` **Description**: Updates results for frames that have been retrospectively improved (e.g., after loop closure or chunk merge). **Called By**: -- F10 Factor Graph (after asynchronous refinement) +- F02.2 Flight Processing Engine (after factor graph optimization) **Input**: ```python flight_id: str -frame_ids: List[int] # Frames with updated poses +refined_results: List[RefinedFrameResult] # GPS-converted results from F02.2 ``` **Output**: `bool` -**Note**: F14 does NOT call F10 or F13. The caller (F02.2) performs the following steps before calling mark_refined(): -1. F02.2 gets refined poses from F10.get_trajectory(flight_id) +**Important**: F14 does NOT call F10 or F13. The caller (F02.2) performs the following steps before calling mark_refined(): +1. F02.2 gets refined poses from F10.get_trajectory(flight_id) (ENU coordinates) 2. F02.2 converts ENU to GPS via F13.enu_to_gps(flight_id, enu_tuple) -3. F02.2 calls F14.mark_refined() with the GPS-converted results +3. F02.2 constructs RefinedFrameResult objects with GPS coordinates +4. F02.2 calls F14.mark_refined() with the GPS-converted results **Processing Flow**: -1. For each frame_id in frame_ids: - - Receive GPS coordinates from caller (already converted) +1. For each refined_result in refined_results: + - Extract frame_id, gps_center, confidence from RefinedFrameResult - Update result with refined=True via F03 Flight Database (part of transaction) - Update waypoint via F03 Flight Database (part of transaction) - Call F15 SSE Event Streamer.send_refinement() **Test Cases**: 1. Batch refinement → all frames updated and published +2. GPS coordinates match converted values --- @@ -194,25 +212,34 @@ since: datetime --- -### `update_results_after_chunk_merge(flight_id: str, merged_frames: List[int]) -> bool` +### `update_results_after_chunk_merge(flight_id: str, refined_results: List[RefinedFrameResult]) -> bool` -**Description**: Handling specific to chunk merging events. +**Description**: Updates results for frames affected by chunk merging into main trajectory. -**Triggered By**: -- `ChunkMerged` event from F11 (F14 subscribes to this event) -- Alternative: F02.2 Flight Processing Engine can coordinate this call after receiving ChunkMerged event +**Called By**: +- F02.2 Flight Processing Engine (after chunk merge completes) **Input**: ```python flight_id: str -merged_frames: List[int] # Frames whose poses changed due to chunk merge +refined_results: List[RefinedFrameResult] # GPS-converted results for merged frames ``` **Output**: `bool` - True if updated successfully +**Important**: F14 does NOT call F10, F13, or F11. F02.2 coordinates the chunk merge workflow: +1. F11 returns merge result to F02.2 (direct call return, not event) +2. F02.2 gets updated poses from F10.get_trajectory(flight_id) (ENU coordinates) +3. F02.2 converts ENU to GPS via F13.enu_to_gps(flight_id, enu_tuple) +4. F02.2 constructs RefinedFrameResult objects +5. F02.2 calls F14.update_results_after_chunk_merge() with GPS-converted results + **Processing Flow**: -1. Similar to `mark_refined` but triggered by `ChunkMerged` event context. -2. Ensures all frames in the merged chunk are updated to the global coordinate system. +1. For each refined_result in refined_results: + - Extract frame_id, gps_center, confidence from RefinedFrameResult + - Update result with refined=True via F03 Flight Database (part of transaction) + - Update waypoint via F03 Flight Database (part of transaction) + - Call F15 SSE Event Streamer.send_refinement() **Test Cases**: 1. **Chunk merge updates**: All merged frames updated and published @@ -286,6 +313,19 @@ class FrameResult(BaseModel): updated_at: datetime ``` +### RefinedFrameResult +```python +class RefinedFrameResult(BaseModel): + """ + GPS-converted frame result provided by F02.2 after coordinate transformation. + F02.2 converts ENU poses from F10 to GPS using F13 before passing to F14. + """ + frame_id: int + gps_center: GPSPoint # GPS coordinates (converted from ENU by F02.2) + confidence: float + heading: Optional[float] = None # Updated heading if available +``` + ### FlightResults ```python class FlightStatistics(BaseModel): diff --git a/docs/02_components/astral_next_components_diagram.drawio b/docs/02_components/astral_next_components_diagram.drawio index e0dd564..55a940b 100644 --- a/docs/02_components/astral_next_components_diagram.drawio +++ b/docs/02_components/astral_next_components_diagram.drawio @@ -1,62 +1,71 @@ - + - - + + - + - - + + - - + + - - + + - - - - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + @@ -70,6 +79,9 @@ + + + @@ -88,6 +100,9 @@ + + + @@ -100,36 +115,49 @@ - + - + + + + + + + - + + - + - + - - + + - - - - - + + - - - - - + + + + + + + + + + + + + + diff --git a/docs/02_components/decomposition_plan.md b/docs/02_components/decomposition_plan.md index 27f11e6..77ac3f6 100644 --- a/docs/02_components/decomposition_plan.md +++ b/docs/02_components/decomposition_plan.md @@ -275,7 +275,7 @@ | 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_chunk_subgraphs()` | **Chunk merging** | +| F11 (background) | F12 | `mark_chunk_anchored()` + `merge_chunks(main, new)` | **Chunk merging via F12** | | F11 (fail) | F02.2 | Returns `UserInputRequest` | Request human help (last resort) | | F02.2 | F15 | `send_user_input_request()` | Send SSE event to client | @@ -314,11 +314,15 @@ | Source | Target | Method | Purpose | |--------|--------|--------|---------| | F10 | Internal (background) | `optimize()` | Back-propagate anchors | -| F14 | F10 | `get_trajectory()` | Get refined poses | +| F02.2 | F10 | `get_trajectory()` | Get refined poses (ENU) | +| F02.2 | F13 | `enu_to_gps()` | Convert ENU poses to GPS | +| F02.2 | F14 | `mark_refined(List[RefinedFrameResult])` | Pass GPS-converted results | | F14 | F03 | `batch_update_waypoints()` | Batch update waypoints | | F14 | F15 | `send_refinement()` × N | Send updates | | F15 | Client | SSE `frame_refined` × N | Incremental updates | +**Note**: F14 does NOT call F10 or F13. F02.2 performs coordinate conversion and provides GPS results to F14. + ### Chunk Matching (Background) | Source | Target | Method | Purpose | @@ -332,7 +336,7 @@ | 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) | +| F11 | F12 | `merge_chunks(main_chunk, new_chunk)` | Merge new_chunk into main_chunk (Sim3 transform) | | F10 | Internal | `optimize_global()` | Global optimization after merging | | F11 | F12 | `mark_chunk_anchored()` | Update chunk state | diff --git a/docs/02_components/system_flows.md b/docs/02_components/system_flows.md index 7f3d1bd..da1bc97 100644 --- a/docs/02_components/system_flows.md +++ b/docs/02_components/system_flows.md @@ -297,8 +297,8 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────┐ │ │ -│ │ │ F03 save_heading() via F06 │ │ │ -│ │ │ update_heading() │ │ │ +│ │ │ F06 update_heading() → returns │ │ │ +│ │ │ F02.2 calls F03 save_heading() │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ │ │ └────────────────────────────────────────────────────┘ │ @@ -323,15 +323,15 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ -│ F11 Failure Recovery Coordinator │ +│ F02.2 calls F11 methods (direct returns, NO EVENTS) │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 1. EMIT RecoveryStarted event │ │ -│ │ └─ F02.2 updates status to "recovering" │ │ +│ │ 1. F02.2 calls F11.start_search() → returns SearchSession │ │ +│ │ F02.2 updates status to "recovering" │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 2. create_chunk_on_tracking_loss() via F12 │ │ +│ │ 2. F02.2 calls F11.create_chunk_on_tracking_loss() via F12 │ │ │ │ └─ Proactive chunk creation (processing continues) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ @@ -343,10 +343,9 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match │ │ │ │ │ │ ┌───────────────────────────────────────────────────┐ │ │ │ │ │ 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)│ │ │ +│ │ │ ├─ F11.expand_search_radius() → tiles │ │ │ +│ │ │ ├─ F02.2 fetches tiles via F04 │ │ │ +│ │ │ ├─ F11.try_current_grid() → AlignmentResult │ │ │ │ │ │ │ │ │ │ │ │ │ └─ If match found: BREAK │ │ │ │ │ └───────────────────────────────────────────────────┘ │ │ @@ -357,8 +356,8 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match │ │ Single-image match found? │ │ │ ▼ ▼ │ │ ┌─────────────────────┐ ┌────────────────────────────┐ │ -│ │ EMIT RecoverySucceeded│ │ Continue chunk building │ │ -│ │ Resume normal flow │ │ → Flow 7 (Chunk Building) │ │ +│ │ F11.mark_found() │ │ Continue chunk building │ │ +│ │ Resume normal flow │ │ → Flow 7 (Chunk Building) │ │ │ └─────────────────────┘ │ → Flow 8 (Chunk Matching) │ │ │ │ (Background) │ │ │ └────────────────────────────┘ │ @@ -480,28 +479,28 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match **Sequence**: ``` ┌───────────────────────────────────────────────────────────────────────-──┐ -│ F11 merge_chunk_to_trajectory() │ +│ F02.2 orchestrates via F11.merge_chunk_to_trajectory() │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 1. Get chunk frames: F12 get_chunk_frames(chunk_id) │ │ +│ │ 1. Get chunk frames: F12 get_chunk_frames(new_chunk_id) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 2. Anchor chunk: F12 mark_chunk_anchored(chunk_id, gps) │ │ -│ │ └─ F10 add_chunk_anchor(flight_id, chunk_id, frame_id, │ │ +│ │ 2. Anchor chunk: F12 mark_chunk_anchored(new_chunk_id, gps) │ │ +│ │ └─ F10 add_chunk_anchor(flight_id, new_chunk_id, frame_id│ │ │ │ gps, covariance) │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 3. Determine target chunk (predecessor or "main") │ │ -│ │ └─ Returns target_chunk_id (predecessor or "main") │ │ +│ │ 3. Determine main chunk (predecessor or "main") │ │ +│ │ └─ Returns main_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) │ │ +│ │ 4. Merge: F12 merge_chunks(main_chunk_id,new_chunk_id,Sim3) │ │ +│ │ ├─ F10 merge_chunk_subgraphs(flight_id, new_chunk_id, │ │ +│ │ │ main_chunk_id, transform) ← Apply Sim(3) │ │ +│ │ ├─ F12 deactivate_chunk(new_chunk_id) │ │ │ │ └─ F03 save_chunk_state() │ │ │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ @@ -511,10 +510,11 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match │ └──────────────────────────────┬──────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 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 │ │ +│ │ 6. F11 returns True → F02.2 coordinates result updates: │ │ +│ │ ├─ F02.2 calls F10 get_trajectory(flight_id) → ENU poses │ │ +│ │ ├─ F02.2 calls F13 enu_to_gps() for each frame │ │ +│ │ ├─ F02.2 constructs List[RefinedFrameResult] │ │ +│ │ └─ F02.2 calls F14.update_results_after_chunk_merge() │ │ │ │ ├─ F03 save_frame_result() + update_waypoint() │ │ │ │ └─ F15 send_refinement() → SSE "frame_refined" × N │ │ │ └─────────────────────────────────────────────────────────────┘ │ @@ -522,6 +522,7 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match ``` **Sim(3) Transform**: Translation + Rotation + Scale alignment between chunks +**Note**: F14 does NOT call F10/F13. F02.2 performs coordinate conversion and passes GPS results. --- @@ -534,14 +535,18 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match **Sequence**: ``` ┌──────────────────────────────────────────────────────────────────────────┐ -│ F11 create_user_input_request() │ +│ F02.2 orchestrates via 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 │ │ +│ │ 1. F11.create_user_input_request() → returns UserInputRequest│ │ +│ │ └─ Gets UAV image, top-5 candidates from F08 │ │ +│ │ └─ Returns request object (does NOT call F15) │ │ +│ └──────────────────────────────┬──────────────────────────────┘ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ 2. F02.2 receives UserInputRequest │ │ +│ │ ├─ F02.2 calls F15.send_user_input_request() │ │ +│ │ │ → SSE "user_input_needed" │ │ │ │ └─ F02.2 updates status to "BLOCKED" │ │ │ └─────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────┘ diff --git a/docs/_metodology/tutorial.md b/docs/_metodology/tutorial.md index 9acac7e..94d1ce2 100644 --- a/docs/_metodology/tutorial.md +++ b/docs/_metodology/tutorial.md @@ -87,7 +87,7 @@ ## 2.10 **🤖📋AI plan**: Generate components - ### Execute `/2.10_gen_components` + ### Execute `/2.planning/2.10_gen_components` ### Revise - Revise the plan, answer questions, put detailed descriptions @@ -97,9 +97,9 @@ save plan to `docs/02_components/00_decomposition_plan.md` -## 2.15 **🤖📋AI plan**: Components assesment +## 2.15 **🤖AI agent**: Components assesment - ### Execute `/2.15_components_assesment` + ### Execute `/2.planning/2.15_components_assesment` ### Revise - Revise the plan, answer questions, put detailed descriptions @@ -108,9 +108,16 @@ ### plan save plan to `docs/02_components/00_decomposition_plan.md` -## 2.20 **🤖📋AI plan**: Generate Jira Epics +## 2.20 **🤖AI agent**: Generate Jira Epics - ### Execute `/2.20/_gen_epics` + ### Add Jira MCP to IDE and authenticate + ``` + "Jira-MCP-Server": { + "url": "https://mcp.atlassian.com/v1/sse" + } + ``` + + ### Execute `/2.planning/2.20_gen_epics use jira mcp` ### Revise - Revise the epics, answer questions, put detailed descriptions @@ -128,7 +135,7 @@ ## 2.40 **🤖📋AI plan**: Component Decomposition To Features ### Execute For each component in `docs/02_components` run - `/2.40_gen_features --component @docs/02_components/[##]_[component_name]/[component_name]_spec.md` + `/2.planning/2.40_gen_features --component @[component_name]_spec.md` ### Revise - Revise the features, answer questions, put detailed descriptions