mirror of
https://github.com/azaion/gps-denied-desktop.git
synced 2026-04-22 07:06:37 +00:00
spec cleanup
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -61,8 +61,8 @@ class IFactorGraphOptimizer(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def merge_chunk_subgraphs(self, flight_id: str, source_chunk_id: str, target_chunk_id: str, transform: Sim3Transform) -> bool:
|
def merge_chunk_subgraphs(self, flight_id: str, new_chunk_id: str, main_chunk_id: str, transform: Sim3Transform) -> bool:
|
||||||
"""Merges source_chunk INTO target_chunk. Source chunk subgraph is merged into target."""
|
"""Merges new_chunk INTO main_chunk. Extends main_chunk with new_chunk's subgraph."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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**:
|
**Called By**:
|
||||||
- F11 Failure Recovery Coordinator (after chunk matching)
|
- F12 Route Chunk Manager (via merge_chunks method)
|
||||||
- Background optimization task
|
|
||||||
|
|
||||||
**Input**:
|
**Input**:
|
||||||
```python
|
```python
|
||||||
chunk_id_1: str # Source chunk (typically newer)
|
flight_id: str # Flight identifier
|
||||||
chunk_id_2: str # Target chunk (typically older, merged into)
|
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:
|
transform: Sim3Transform:
|
||||||
translation: np.ndarray # (3,)
|
translation: np.ndarray # (3,)
|
||||||
rotation: np.ndarray # (3, 3) or quaternion
|
rotation: np.ndarray # (3, 3) or quaternion
|
||||||
@@ -547,11 +547,11 @@ bool: True if merge successful
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Processing Flow**:
|
**Processing Flow**:
|
||||||
1. Verify both chunks exist and chunk_id_1 is anchored
|
1. Verify both chunks exist and new_chunk is anchored
|
||||||
2. Apply Sim(3) transform to all poses in chunk_id_1
|
2. Apply Sim(3) transform to all poses in new_chunk
|
||||||
3. Merge chunk_id_1's subgraph into chunk_id_2's subgraph
|
3. Merge new_chunk's subgraph into main_chunk's subgraph
|
||||||
4. Update frame-to-chunk mapping
|
4. Update frame-to-chunk mapping (new_chunk frames now belong to main_chunk)
|
||||||
5. Mark chunk_id_1 as merged
|
5. Mark new_chunk subgraph as merged (F12 handles state updates)
|
||||||
6. Optimize merged graph globally
|
6. Optimize merged graph globally
|
||||||
|
|
||||||
**Sim(3) Transformation**:
|
**Sim(3) Transformation**:
|
||||||
@@ -560,7 +560,7 @@ bool: True if merge successful
|
|||||||
- Preserves internal consistency of both chunks
|
- Preserves internal consistency of both chunks
|
||||||
|
|
||||||
**Test Cases**:
|
**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
|
2. **Merge unanchored chunk**: Returns False
|
||||||
3. **Global consistency**: Merged trajectory is globally consistent
|
3. **Global consistency**: Merged trajectory is globally consistent
|
||||||
|
|
||||||
|
|||||||
+23
-5
@@ -123,6 +123,24 @@ This separation ensures:
|
|||||||
- **Chunk lifecycle and matching coordination**
|
- **Chunk lifecycle and matching coordination**
|
||||||
- **Multi-chunk simultaneous processing**
|
- **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
|
## API Methods
|
||||||
|
|
||||||
### `check_confidence(vo_result: RelativePose, litesam_result: Optional[AlignmentResult]) -> ConfidenceAssessment`
|
### `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)
|
2. Get chunk anchor frame (middle frame or best frame)
|
||||||
3. Call F12.mark_chunk_anchored() with GPS (F12 coordinates with F10)
|
3. Call F12.mark_chunk_anchored() with GPS (F12 coordinates with F10)
|
||||||
4. **Determine merge target**:
|
4. **Determine merge target**:
|
||||||
- Target is typically the temporal predecessor (previous chunk by frame_id order)
|
- Main chunk is typically the temporal predecessor (previous chunk by frame_id order)
|
||||||
- If no predecessor: merge to main trajectory (target_chunk_id="main")
|
- If no predecessor: merge to main trajectory (main_chunk_id="main")
|
||||||
- F11 determines target based on chunk frame_id ordering
|
- F11 determines main_chunk based on chunk frame_id ordering
|
||||||
5. Call F12.merge_chunks(target_chunk_id, chunk_id, transform)
|
5. Call F12.merge_chunks(main_chunk_id, chunk_id, transform)
|
||||||
- Note: `merge_chunks(target, source)` merges source INTO target
|
- Note: `merge_chunks(main_chunk, new_chunk)` merges new_chunk INTO main_chunk
|
||||||
- chunk_id (source) is merged into target_chunk_id
|
- chunk_id (source) is merged into target_chunk_id
|
||||||
6. F12 handles chunk state updates (deactivation, status updates)
|
6. F12 handles chunk state updates (deactivation, status updates)
|
||||||
7. F10 optimizes merged graph globally (via F12.merge_chunks())
|
7. F10 optimizes merged graph globally (via F12.merge_chunks())
|
||||||
|
|||||||
@@ -59,12 +59,16 @@ class IRouteChunkManager(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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:
|
Transactional update:
|
||||||
1. Calls F10.merge_chunk_subgraphs().
|
1. Calls F10.merge_chunk_subgraphs(flight_id, new_chunk_id, main_chunk_id, transform).
|
||||||
2. IF success: Updates internal state (source merged/deactivated).
|
2. IF success: Updates internal state (new_chunk merged/deactivated).
|
||||||
3. Returns success status.
|
3. Returns success status.
|
||||||
|
|
||||||
|
Note: flight_id is obtained from the ChunkHandle stored internally for main_chunk_id.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -88,6 +92,14 @@ class IRouteChunkManager(ABC):
|
|||||||
- **Transactional Integrity**: Ensures internal state updates are atomic with respect to Factor Graph (F10) operations.
|
- **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.
|
- **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
|
### Interaction
|
||||||
- Called by **F02.2 Flight Processing Engine** and **F11 Failure Recovery Coordinator** (via F02.2 or direct delegation).
|
- Called by **F02.2 Flight Processing Engine** and **F11 Failure Recovery Coordinator** (via F02.2 or direct delegation).
|
||||||
- Calls **F10 Factor Graph Optimizer**.
|
- 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**:
|
**Called By**:
|
||||||
- F11 Failure Recovery Coordinator (after successful chunk matching)
|
- F11 Failure Recovery Coordinator (after successful chunk matching)
|
||||||
|
|
||||||
**Input**:
|
**Input**:
|
||||||
```python
|
```python
|
||||||
target_chunk_id: str # Target chunk (receives the merge, typically older/main)
|
main_chunk_id: str # Main chunk being extended (destination, typically older/established trajectory)
|
||||||
source_chunk_id: str # Source chunk (being merged in, typically newer)
|
new_chunk_id: str # New chunk being merged in (source, typically newer/recently anchored)
|
||||||
transform: Sim3Transform:
|
transform: Sim3Transform:
|
||||||
translation: np.ndarray # (3,)
|
translation: np.ndarray # (3,)
|
||||||
rotation: np.ndarray # (3, 3) or quaternion
|
rotation: np.ndarray # (3, 3) or quaternion
|
||||||
@@ -330,21 +342,24 @@ transform: Sim3Transform:
|
|||||||
|
|
||||||
**Output**: `bool` - True if merge successful
|
**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**:
|
**Processing Flow**:
|
||||||
1. Call F10.merge_chunk_subgraphs(flight_id, source_chunk_id, target_chunk_id, transform)
|
1. Get flight_id from internally stored ChunkHandle for main_chunk_id
|
||||||
2. If successful:
|
2. Call F10.merge_chunk_subgraphs(flight_id, new_chunk_id, main_chunk_id, transform)
|
||||||
- Update source_chunk_id state:
|
3. If successful:
|
||||||
|
- Update new_chunk_id state:
|
||||||
- Set is_active=False
|
- Set is_active=False
|
||||||
- Set matching_status="merged"
|
- Set matching_status="merged"
|
||||||
- Call deactivate_chunk(source_chunk_id)
|
- Call deactivate_chunk(new_chunk_id)
|
||||||
- target_chunk remains active (now contains merged frames)
|
- main_chunk remains active (now contains merged frames)
|
||||||
- Persist chunk state via F03 Flight Database.save_chunk_state()
|
- Persist chunk state via F03 Flight Database.save_chunk_state()
|
||||||
3. Return True
|
4. Return True
|
||||||
|
|
||||||
**Test Cases**:
|
**Test Cases**:
|
||||||
1. **Merge anchored chunk**: source_chunk merged into target_chunk
|
1. **Merge anchored chunk**: new_chunk merged into main_chunk
|
||||||
2. **Source deactivated**: source_chunk marked as merged and deactivated
|
2. **New chunk deactivated**: new_chunk marked as merged and deactivated
|
||||||
3. **Target unchanged**: target_chunk remains active with new frames
|
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
|
5. get_chunks_for_matching() → returns only chunk_2
|
||||||
|
|
||||||
### Test 4: Chunk Merging
|
### Test 4: Chunk Merging
|
||||||
1. Create chunk_1 (frames 1-10), chunk_2 (frames 20-30)
|
1. Create main_chunk (frames 1-10), new_chunk (frames 20-30)
|
||||||
2. Anchor chunk_1 via mark_chunk_anchored()
|
2. Anchor new_chunk via mark_chunk_anchored()
|
||||||
3. merge_chunks(chunk_1, chunk_2, transform) → chunks merged
|
3. merge_chunks(main_chunk, new_chunk, transform) → new_chunk merged into main_chunk
|
||||||
4. Verify chunk_1 marked as merged and deactivated
|
4. Verify new_chunk marked as merged and deactivated
|
||||||
5. Verify F10 merge_chunks() called
|
5. Verify main_chunk extended with new frames
|
||||||
|
6. Verify F10.merge_chunk_subgraphs() called with correct parameters
|
||||||
|
|
||||||
### Test 5: Chunk Matching Status
|
### Test 5: Chunk Matching Status
|
||||||
1. Create chunk
|
1. Create chunk
|
||||||
|
|||||||
@@ -27,7 +27,15 @@ class IResultManager(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -35,7 +43,15 @@ class IResultManager(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@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
|
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).
|
**Description**: Updates results for frames that have been retrospectively improved (e.g., after loop closure or chunk merge).
|
||||||
|
|
||||||
**Called By**:
|
**Called By**:
|
||||||
- F10 Factor Graph (after asynchronous refinement)
|
- F02.2 Flight Processing Engine (after factor graph optimization)
|
||||||
|
|
||||||
**Input**:
|
**Input**:
|
||||||
```python
|
```python
|
||||||
flight_id: str
|
flight_id: str
|
||||||
frame_ids: List[int] # Frames with updated poses
|
refined_results: List[RefinedFrameResult] # GPS-converted results from F02.2
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `bool`
|
**Output**: `bool`
|
||||||
|
|
||||||
**Note**: F14 does NOT call F10 or F13. The caller (F02.2) performs the following steps before calling mark_refined():
|
**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)
|
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)
|
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**:
|
**Processing Flow**:
|
||||||
1. For each frame_id in frame_ids:
|
1. For each refined_result in refined_results:
|
||||||
- Receive GPS coordinates from caller (already converted)
|
- Extract frame_id, gps_center, confidence from RefinedFrameResult
|
||||||
- Update result with refined=True via F03 Flight Database (part of transaction)
|
- Update result with refined=True via F03 Flight Database (part of transaction)
|
||||||
- Update waypoint via F03 Flight Database (part of transaction)
|
- Update waypoint via F03 Flight Database (part of transaction)
|
||||||
- Call F15 SSE Event Streamer.send_refinement()
|
- Call F15 SSE Event Streamer.send_refinement()
|
||||||
|
|
||||||
**Test Cases**:
|
**Test Cases**:
|
||||||
1. Batch refinement → all frames updated and published
|
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**:
|
**Called By**:
|
||||||
- `ChunkMerged` event from F11 (F14 subscribes to this event)
|
- F02.2 Flight Processing Engine (after chunk merge completes)
|
||||||
- Alternative: F02.2 Flight Processing Engine can coordinate this call after receiving ChunkMerged event
|
|
||||||
|
|
||||||
**Input**:
|
**Input**:
|
||||||
```python
|
```python
|
||||||
flight_id: str
|
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
|
**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**:
|
**Processing Flow**:
|
||||||
1. Similar to `mark_refined` but triggered by `ChunkMerged` event context.
|
1. For each refined_result in refined_results:
|
||||||
2. Ensures all frames in the merged chunk are updated to the global coordinate system.
|
- 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**:
|
**Test Cases**:
|
||||||
1. **Chunk merge updates**: All merged frames updated and published
|
1. **Chunk merge updates**: All merged frames updated and published
|
||||||
@@ -286,6 +313,19 @@ class FrameResult(BaseModel):
|
|||||||
updated_at: datetime
|
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
|
### FlightResults
|
||||||
```python
|
```python
|
||||||
class FlightStatistics(BaseModel):
|
class FlightStatistics(BaseModel):
|
||||||
|
|||||||
@@ -1,62 +1,71 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram name="ASTRAL-Next Components" id="astral-next-components">
|
<diagram name="ASTRAL-Next Components" id="astral-next-components">
|
||||||
<mxGraphModel dx="771" dy="632" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="500" math="0" shadow="0">
|
<mxGraphModel dx="1100" dy="750" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="600" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="title" value="ASTRAL-Next Component Connections" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontStyle=1;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="title" value="ASTRAL-Next Component Diagram with Jira Epic Numbers" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=16;fontStyle=1;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="280" y="10" width="300" height="25" as="geometry"/>
|
<mxGeometry x="300" y="10" width="500" height="30" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="client" value="Client" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1565C0;strokeColor=#64B5F6;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="client" value="Client" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1565C0;strokeColor=#64B5F6;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="20" y="50" width="60" height="35" as="geometry"/>
|
<mxGeometry x="20" y="60" width="60" height="35" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f01" value="F01 API" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#8B1A1A;strokeColor=#EF5350;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f01" value="F01 API AZ-112" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#8B1A1A;strokeColor=#EF5350;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="50" width="70" height="35" as="geometry"/>
|
<mxGeometry x="100" y="55" width="80" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f02" value="F02 Flight Processor" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#6A1B9A;strokeColor=#BA68C8;fontColor=#ffffff;fontStyle=1;" parent="1" vertex="1">
|
<mxCell id="f02" value="F02 Flight Processor AZ-113" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#6A1B9A;strokeColor=#BA68C8;fontColor=#ffffff;fontStyle=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="195" y="70" width="110" height="45" as="geometry"/>
|
<mxGeometry x="200" y="55" width="130" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f03" value="F03 DB" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#424242;strokeColor=#BDBDBD;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f03" value="F03 DB AZ-114" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#424242;strokeColor=#BDBDBD;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="340" y="50" width="70" height="35" as="geometry"/>
|
<mxGeometry x="350" y="55" width="80" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f04" value="F04 Satellite Mgr" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f05" value="F05 Image Pipeline AZ-116" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="60" y="367.5" width="80" height="45" as="geometry"/>
|
<mxGeometry x="450" y="55" width="110" height="45" as="geometry"/>
|
||||||
</mxCell>
|
|
||||||
<mxCell id="f05" value="F05 Image Pipeline" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
|
||||||
<mxGeometry x="550" y="45" width="80" height="45" as="geometry"/>
|
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="satellite" value="Satellite Provider" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFB300;fontColor=#ffffff;dashed=1;" vertex="1" parent="1">
|
<mxCell id="satellite" value="Satellite Provider" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFB300;fontColor=#ffffff;dashed=1;" vertex="1" parent="1">
|
||||||
<mxGeometry x="660" y="45" width="70" height="45" as="geometry"/>
|
<mxGeometry x="580" y="55" width="80" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f15" value="F15 SSE" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFA726;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f15" value="F15 SSE AZ-126" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFA726;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="20" y="120" width="60" height="35" as="geometry"/>
|
<mxGeometry x="20" y="130" width="70" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f11" value="F11 Failure Recovery" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f08" value="F08 Place Recog AZ-119" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="310" y="120" width="110" height="45" as="geometry"/>
|
<mxGeometry x="100" y="130" width="100" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f06" value="F06 Rotation" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f11" value="F11 Failure Recovery AZ-122" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="195" width="70" height="45" as="geometry"/>
|
<mxGeometry x="220" y="130" width="120" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f07" value="F07 Sequential VO" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f12" value="F12 Chunk Mgr AZ-123" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#7B1FA2;strokeColor=#BA68C8;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="200" y="195" width="90" height="45" as="geometry"/>
|
<mxGeometry x="360" y="130" width="100" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f08" value="F08 Place Recog" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f16" value="F16 Model Mgr AZ-127" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#424242;strokeColor=#BDBDBD;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="100" y="120" width="80" height="45" as="geometry"/>
|
<mxGeometry x="480" y="130" width="100" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f09" value="F09 Metric Refine" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f06" value="F06 Rotation AZ-117" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="340" y="195" width="80" height="45" as="geometry"/>
|
<mxGeometry x="100" y="210" width="90" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f12" value="F12 Chunk Manager" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#7B1FA2;strokeColor=#BA68C8;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f07" value="F07 Sequential VO AZ-118" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="450" y="120" width="100" height="45" as="geometry"/>
|
<mxGeometry x="210" y="210" width="110" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f10" value="F10 Factor Graph" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;fontStyle=1;" parent="1" vertex="1">
|
<mxCell id="f09" value="F09 Metric Refine AZ-120" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#1E88E5;strokeColor=#42A5F5;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="330" y="280" width="100" height="45" as="geometry"/>
|
<mxGeometry x="340" y="210" width="110" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f13" value="F13 Coord Transform" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f17" value="F17 Config Mgr AZ-128" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#424242;strokeColor=#BDBDBD;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
<mxGeometry x="390" y="355" width="100" height="45" as="geometry"/>
|
<mxGeometry x="470" y="210" width="100" height="45" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="f14" value="F14 Result Manager" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFA726;fontColor=#ffffff;" parent="1" vertex="1">
|
<mxCell id="f10" value="F10 Factor Graph AZ-121" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;fontStyle=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="190" y="372.5" width="120" height="35" as="geometry"/>
|
<mxGeometry x="260" y="290" width="120" height="50" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="f04" value="F04 Satellite Mgr AZ-115" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#CC6600;strokeColor=#FFB300;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="100" y="290" width="110" height="50" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="f13" value="F13 Coord Transform AZ-124" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#388E3C;strokeColor=#66BB6A;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="400" y="290" width="120" height="50" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="f14" value="F14 Result Manager AZ-125" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E65100;strokeColor=#FFA726;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="250" y="370" width="130" height="45" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="helpers" value="H01-H08 Helpers AZ-129" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#546E7A;strokeColor=#78909C;fontColor=#ffffff;" parent="1" vertex="1">
|
||||||
|
<mxGeometry x="540" y="290" width="110" height="50" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="c1" value="HTTP" style="strokeColor=#FFFFFF;fontColor=#ffffff;fontSize=8;" edge="1" parent="1" source="client" target="f01">
|
<mxCell id="c1" value="HTTP" style="strokeColor=#FFFFFF;fontColor=#ffffff;fontSize=8;" edge="1" parent="1" source="client" target="f01">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
@@ -70,6 +79,9 @@
|
|||||||
<mxCell id="c4" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f02" target="f03">
|
<mxCell id="c4" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f02" target="f03">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="c4b" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f02" target="f05">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
<mxCell id="c5" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f02" target="f11">
|
<mxCell id="c5" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f02" target="f11">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
@@ -88,6 +100,9 @@
|
|||||||
<mxCell id="c12" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f11" target="f12">
|
<mxCell id="c12" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f11" target="f12">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="c13" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f11" target="f06">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
<mxCell id="c14" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f07" target="f10">
|
<mxCell id="c14" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f07" target="f10">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
@@ -100,36 +115,49 @@
|
|||||||
<mxCell id="c17" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f10" target="f13">
|
<mxCell id="c17" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f10" target="f13">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="c18" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f14" target="f13">
|
<mxCell id="c18" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f10" target="f14">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="c19" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f14" target="f15">
|
<mxCell id="c19" style="strokeColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="f14" target="f15">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="c20" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f08" target="f04">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="c21" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f04" target="satellite">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||
<Array as="points">
|
<Array as="points">
|
||||||
<mxPoint x="80" y="270"/>
|
<mxPoint x="155" y="370"/>
|
||||||
|
<mxPoint x="620" y="370"/>
|
||||||
</Array>
|
</Array>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="c13" style="strokeColor=#66BB6A;dashed=1;" edge="1" parent="1" source="f11" target="f14">
|
<mxCell id="c22" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f07" target="f16">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="c21" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f05" target="satellite">
|
<mxCell id="c23" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f08" target="f16">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="legend" value="── sync - - event" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=9;fontColor=#888888;" vertex="1" parent="1">
|
<mxCell id="c24" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f09" target="f16">
|
||||||
<mxGeometry x="600" y="380" width="100" height="20" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="" style="strokeColor=#FFFFFF;endArrow=none;" edge="1" parent="1" source="f11" target="f02">
|
<mxCell id="c25" style="strokeColor=#FFFFFF;dashed=1;" edge="1" parent="1" source="f17" target="f16">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
<mxPoint x="507.02127659574467" y="100.00000000000011" as="sourcePoint"/>
|
|
||||||
<mxPoint x="256.3829787234042" y="289.9999999999999" as="targetPoint"/>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="2" value="" style="strokeColor=#FFFFFF;fontColor=#ffffff;endArrow=none;" edge="1" parent="1" source="f04" target="f14">
|
<mxCell id="c26" style="strokeColor=#78909C;dashed=1;" edge="1" parent="1" source="helpers" target="f10">
|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
<mxPoint x="715" y="121.22222222222206" as="sourcePoint"/>
|
</mxCell>
|
||||||
<mxPoint x="125" y="212.9999999999999" as="targetPoint"/>
|
<mxCell id="c27" style="strokeColor=#78909C;dashed=1;" edge="1" parent="1" source="helpers" target="f13">
|
||||||
</mxGeometry>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="c28" style="strokeColor=#FFFFFF;" edge="1" parent="1" source="f06" target="f09">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="legend" value="── sync call - - - event/config" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;fontColor=#888888;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="20" y="430" width="200" height="20" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="legend2" value="Colors: Red=API | Purple=Orchestration | Blue=Visual Processing | Green=State | Orange=Data/IO | Gray=Infrastructure" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=9;fontColor=#666666;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="20" y="450" width="650" height="20" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
|
|||||||
@@ -275,7 +275,7 @@
|
|||||||
| F11 (background) | F08 | `retrieve_candidate_tiles_for_chunk()` | **Chunk semantic matching** |
|
| F11 (background) | F08 | `retrieve_candidate_tiles_for_chunk()` | **Chunk semantic matching** |
|
||||||
| F11 (background) | F06 | `try_chunk_rotation_steps()` | **Chunk rotation sweeps** |
|
| F11 (background) | F06 | `try_chunk_rotation_steps()` | **Chunk rotation sweeps** |
|
||||||
| F11 (background) | F09 | `align_chunk_to_satellite()` | **Chunk LiteSAM matching** |
|
| 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) |
|
| F11 (fail) | F02.2 | Returns `UserInputRequest` | Request human help (last resort) |
|
||||||
| F02.2 | F15 | `send_user_input_request()` | Send SSE event to client |
|
| F02.2 | F15 | `send_user_input_request()` | Send SSE event to client |
|
||||||
|
|
||||||
@@ -314,11 +314,15 @@
|
|||||||
| Source | Target | Method | Purpose |
|
| Source | Target | Method | Purpose |
|
||||||
|--------|--------|--------|---------|
|
|--------|--------|--------|---------|
|
||||||
| F10 | Internal (background) | `optimize()` | Back-propagate anchors |
|
| 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 | F03 | `batch_update_waypoints()` | Batch update waypoints |
|
||||||
| F14 | F15 | `send_refinement()` × N | Send updates |
|
| F14 | F15 | `send_refinement()` × N | Send updates |
|
||||||
| F15 | Client | SSE `frame_refined` × N | Incremental 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)
|
### Chunk Matching (Background)
|
||||||
|
|
||||||
| Source | Target | Method | Purpose |
|
| Source | Target | Method | Purpose |
|
||||||
@@ -332,7 +336,7 @@
|
|||||||
| F11 | F06 | `try_chunk_rotation_steps()` | Chunk rotation sweeps (12 rotations) |
|
| F11 | F06 | `try_chunk_rotation_steps()` | Chunk rotation sweeps (12 rotations) |
|
||||||
| F06 | F09 | `align_chunk_to_satellite()` × 12 | Try LiteSAM for each rotation |
|
| F06 | F09 | `align_chunk_to_satellite()` × 12 | Try LiteSAM for each rotation |
|
||||||
| F11 | F10 | `add_chunk_anchor()` | Anchor chunk with GPS |
|
| 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 |
|
| F10 | Internal | `optimize_global()` | Global optimization after merging |
|
||||||
| F11 | F12 | `mark_chunk_anchored()` | Update chunk state |
|
| F11 | F12 | `mark_chunk_anchored()` | Update chunk state |
|
||||||
|
|
||||||
|
|||||||
@@ -297,8 +297,8 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match
|
|||||||
│ │ │ │ │
|
│ │ │ │ │
|
||||||
│ │ ▼ │ │
|
│ │ ▼ │ │
|
||||||
│ │ ┌─────────────────────────────────────┐ │ │
|
│ │ ┌─────────────────────────────────────┐ │ │
|
||||||
│ │ │ F03 save_heading() via F06 │ │ │
|
│ │ │ F06 update_heading() → returns │ │ │
|
||||||
│ │ │ update_heading() │ │ │
|
│ │ │ 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**:
|
**Sequence**:
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────────────────────┐
|
||||||
│ F11 Failure Recovery Coordinator │
|
│ F02.2 calls F11 methods (direct returns, NO EVENTS) │
|
||||||
│ │
|
│ │
|
||||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
│ │ 1. EMIT RecoveryStarted event │ │
|
│ │ 1. F02.2 calls F11.start_search() → returns SearchSession │ │
|
||||||
│ │ └─ F02.2 updates status to "recovering" │ │
|
│ │ 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) │ │
|
│ │ └─ 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]: │ │ │
|
│ │ │ For grid_size in [1, 4, 9, 16, 25]: │ │ │
|
||||||
│ │ │ ├─ F04 expand_search_grid() │ │ │
|
│ │ │ ├─ F11.expand_search_radius() → tiles │ │ │
|
||||||
│ │ │ ├─ For each tile: │ │ │
|
│ │ │ ├─ F02.2 fetches tiles via F04 │ │ │
|
||||||
│ │ │ │ ├─ F04 compute_tile_bounds() │ │ │
|
│ │ │ ├─ F11.try_current_grid() → AlignmentResult │ │ │
|
||||||
│ │ │ │ └─ F09 align_to_satellite(img, tile, bounds)│ │ │
|
|
||||||
│ │ │ │ │ │ │
|
│ │ │ │ │ │ │
|
||||||
│ │ │ └─ If match found: BREAK │ │ │
|
│ │ │ └─ 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? │ │
|
│ │ Single-image match found? │ │
|
||||||
│ ▼ ▼ │
|
│ ▼ ▼ │
|
||||||
│ ┌─────────────────────┐ ┌────────────────────────────┐ │
|
│ ┌─────────────────────┐ ┌────────────────────────────┐ │
|
||||||
│ │ EMIT RecoverySucceeded│ │ Continue chunk building │ │
|
│ │ F11.mark_found() │ │ Continue chunk building │ │
|
||||||
│ │ Resume normal flow │ │ → Flow 7 (Chunk Building) │ │
|
│ │ Resume normal flow │ │ → Flow 7 (Chunk Building) │ │
|
||||||
│ └─────────────────────┘ │ → Flow 8 (Chunk Matching) │ │
|
│ └─────────────────────┘ │ → Flow 8 (Chunk Matching) │ │
|
||||||
│ │ (Background) │ │
|
│ │ (Background) │ │
|
||||||
│ └────────────────────────────┘ │
|
│ └────────────────────────────┘ │
|
||||||
@@ -480,28 +479,28 @@ ASTRAL-Next is a GPS-denied UAV visual localization system using tri-layer match
|
|||||||
**Sequence**:
|
**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) │ │
|
│ │ 2. Anchor chunk: F12 mark_chunk_anchored(new_chunk_id, gps) │ │
|
||||||
│ │ └─ F10 add_chunk_anchor(flight_id, chunk_id, frame_id, │ │
|
│ │ └─ F10 add_chunk_anchor(flight_id, new_chunk_id, frame_id│ │
|
||||||
│ │ gps, covariance) │ │
|
│ │ gps, covariance) │ │
|
||||||
│ └──────────────────────────────┬──────────────────────────────┘ │
|
│ └──────────────────────────────┬──────────────────────────────┘ │
|
||||||
│ ▼ │
|
│ ▼ │
|
||||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
│ │ 3. Determine target chunk (predecessor or "main") │ │
|
│ │ 3. Determine main chunk (predecessor or "main") │ │
|
||||||
│ │ └─ Returns target_chunk_id (predecessor or "main") │ │
|
│ │ └─ Returns main_chunk_id (predecessor or "main") │ │
|
||||||
│ └──────────────────────────────┬──────────────────────────────┘ │
|
│ └──────────────────────────────┬──────────────────────────────┘ │
|
||||||
│ ▼ │
|
│ ▼ │
|
||||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
│ │ 4. Merge: F12 merge_chunks(target_chunk_id, chunk_id, Sim3) │ │
|
│ │ 4. Merge: F12 merge_chunks(main_chunk_id,new_chunk_id,Sim3) │ │
|
||||||
│ │ ├─ F10 merge_chunk_subgraphs(flight_id, chunk_id, │ │
|
│ │ ├─ F10 merge_chunk_subgraphs(flight_id, new_chunk_id, │ │
|
||||||
│ │ │ target_chunk_id, transform) ← Apply Sim(3) │ │
|
│ │ │ main_chunk_id, transform) ← Apply Sim(3) │ │
|
||||||
│ │ ├─ F12 deactivate_chunk(chunk_id) │ │
|
│ │ ├─ F12 deactivate_chunk(new_chunk_id) │ │
|
||||||
│ │ └─ F03 save_chunk_state() │ │
|
│ │ └─ 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)│ │
|
│ │ 6. F11 returns True → F02.2 coordinates result updates: │ │
|
||||||
│ │ └─ F14 subscribes → update_results_after_chunk_merge() │ │
|
│ │ ├─ F02.2 calls F10 get_trajectory(flight_id) → ENU poses │ │
|
||||||
│ │ ├─ F10 get_trajectory(flight_id) → ENU poses │ │
|
│ │ ├─ F02.2 calls F13 enu_to_gps() for each frame │ │
|
||||||
│ │ ├─ 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() │ │
|
│ │ ├─ F03 save_frame_result() + update_waypoint() │ │
|
||||||
│ │ └─ F15 send_refinement() → SSE "frame_refined" × N │ │
|
│ │ └─ 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
|
**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**:
|
**Sequence**:
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────────────────────┐
|
||||||
│ F11 create_user_input_request() │
|
│ F02.2 orchestrates via F11.create_user_input_request() │
|
||||||
│ │
|
│ │
|
||||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
│ │ 1. Get UAV image for frame_id │ │
|
│ │ 1. F11.create_user_input_request() → returns UserInputRequest│ │
|
||||||
│ │ 2. Get top-5 candidates from F08 │ │
|
│ │ └─ Gets UAV image, top-5 candidates from F08 │ │
|
||||||
│ │ 3. Create UserInputRequest │ │
|
│ │ └─ Returns request object (does NOT call F15) │ │
|
||||||
│ │ 4. F15 send_user_input_request() → SSE "user_input_needed" │ │
|
│ └──────────────────────────────┬──────────────────────────────┘ │
|
||||||
│ │ 5. EMIT UserInputNeeded event │ │
|
│ ▼ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ 2. F02.2 receives UserInputRequest │ │
|
||||||
|
│ │ ├─ F02.2 calls F15.send_user_input_request() │ │
|
||||||
|
│ │ │ → SSE "user_input_needed" │ │
|
||||||
│ │ └─ F02.2 updates status to "BLOCKED" │ │
|
│ │ └─ F02.2 updates status to "BLOCKED" │ │
|
||||||
│ └─────────────────────────────────────────────────────────────┘ │
|
│ └─────────────────────────────────────────────────────────────┘ │
|
||||||
└──────────────────────────────────────────────────────────────────────────┘
|
└──────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
## 2.10 **🤖📋AI plan**: Generate components
|
## 2.10 **🤖📋AI plan**: Generate components
|
||||||
|
|
||||||
### Execute `/2.10_gen_components`
|
### Execute `/2.planning/2.10_gen_components`
|
||||||
|
|
||||||
### Revise
|
### Revise
|
||||||
- Revise the plan, answer questions, put detailed descriptions
|
- Revise the plan, answer questions, put detailed descriptions
|
||||||
@@ -97,9 +97,9 @@
|
|||||||
save plan to `docs/02_components/00_decomposition_plan.md`
|
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
|
||||||
- Revise the plan, answer questions, put detailed descriptions
|
- Revise the plan, answer questions, put detailed descriptions
|
||||||
@@ -108,9 +108,16 @@
|
|||||||
### plan
|
### plan
|
||||||
save plan to `docs/02_components/00_decomposition_plan.md`
|
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
|
||||||
- Revise the epics, answer questions, put detailed descriptions
|
- Revise the epics, answer questions, put detailed descriptions
|
||||||
@@ -128,7 +135,7 @@
|
|||||||
## 2.40 **🤖📋AI plan**: Component Decomposition To Features
|
## 2.40 **🤖📋AI plan**: Component Decomposition To Features
|
||||||
### Execute
|
### Execute
|
||||||
For each component in `docs/02_components` run
|
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
|
||||||
- Revise the features, answer questions, put detailed descriptions
|
- Revise the features, answer questions, put detailed descriptions
|
||||||
|
|||||||
Reference in New Issue
Block a user