mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 17:21:13 +00:00
Update autodev state, architecture documentation, and glossary terms
Transitioned the autodev state to phase 21, reflecting the completion of Step 5 and the drafting of Step 6 epics. Revised the architecture documentation to clarify the roles of the Tile Manager and its components, ensuring accurate representation of the system's operational flow. Updated glossary entries for Flight State and Operator to incorporate recent changes and enhance clarity on component interactions and responsibilities.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# C3.5 — AdHoP-conditional Refinement
|
||||
|
||||
## 1. High-Level Overview
|
||||
|
||||
**Purpose**: conditionally refine `MatchResult` via OrthoLoC AdHoP (method-agnostic perspective preconditioning) when the initial reprojection residual exceeds a configurable threshold; bypass otherwise. The conditional invocation preserves the AC-4.1 latency budget on the steady-state path while keeping the refinement option for hard frames.
|
||||
|
||||
**Architectural Pattern**: Strategy with two concrete implementations: `AdHoPRefiner` (real refinement) and `PassthroughRefiner` (no-op for the non-conditional baseline / smoke tests). Selection at startup by config (ADR-001); both implementations linked into the deployment binary by default (refinement is conditionally invoked at runtime, not gated at build time).
|
||||
|
||||
**Upstream dependencies**:
|
||||
- C3 → `MatchResult`.
|
||||
- C7 InferenceRuntime — AdHoP backbone forward pass when invoked.
|
||||
|
||||
**Downstream consumers**:
|
||||
- C4 PoseEstimator (consumes the possibly-refined `MatchResult`).
|
||||
|
||||
## 2. Internal Interfaces
|
||||
|
||||
### Interface: `ConditionalRefiner`
|
||||
|
||||
| Method | Input | Output | Async | Error Types |
|
||||
|--------|-------|--------|-------|-------------|
|
||||
| `refine_if_needed` | `NavCameraFrame, MatchResult, residual_threshold_px: float` | `MatchResult` (possibly enriched with refined inliers) | No | `RefinerBackboneError` |
|
||||
| `was_invoked` | `()` | `bool` — last-call flag for FDR provenance | No | — |
|
||||
|
||||
**Input DTOs**:
|
||||
```
|
||||
NavCameraFrame: see C1
|
||||
MatchResult: see C3
|
||||
```
|
||||
|
||||
**Output DTOs**:
|
||||
```
|
||||
MatchResult (refined):
|
||||
Same shape as C3's MatchResult, with the following enrichments when refinement was invoked:
|
||||
per_candidate[i].inlier_correspondences: refined coordinates from AdHoP perspective preconditioning
|
||||
per_candidate[i].per_candidate_residual_px: post-refinement residual
|
||||
refinement_label: "adhop" | "passthrough"
|
||||
refinement_added_latency_ms: float — for FDR latency partition
|
||||
```
|
||||
|
||||
## 3. External API Specification
|
||||
|
||||
Not applicable.
|
||||
|
||||
## 4. Data Access Patterns
|
||||
|
||||
| Query | Frequency | Hot Path | Index Needed |
|
||||
|-------|-----------|----------|--------------|
|
||||
| Nav-frame pixel access (1 frame per invocation) | conditional, <3 Hz | When invoked | already in memory from C1/C2 path |
|
||||
|
||||
No additional caching.
|
||||
|
||||
## 5. Implementation Details
|
||||
|
||||
**Algorithmic Complexity**: AdHoP perspective preconditioning is `O(F)` in feature count plus one extra backbone forward pass. Steady-state cost is zero (passthrough); worst-case adds ~30–90 ms per invocation on the Jetson.
|
||||
|
||||
**State Management**: stateless per-frame.
|
||||
|
||||
**Key Dependencies**:
|
||||
|
||||
| Library | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| OrthoLoC AdHoP (research code drop) | upstream HEAD pinned per Plan-phase | Conditional refinement |
|
||||
| OpenCV | ≥ 4.12.0 | Reprojection residual computation, perspective transforms |
|
||||
| TensorRT | matches C7 | AdHoP backbone engine when invoked |
|
||||
|
||||
**Error Handling Strategy**:
|
||||
- `RefinerBackboneError`: AdHoP backbone failure. Fall through to passthrough — emit C3's original `MatchResult` unchanged; downstream pose estimation may fail subsequent quality gates and trigger F6 satellite re-localization.
|
||||
- The conditional gate is a configuration parameter (`adhop.residual_threshold_px`); no runtime decision logic outside that comparison.
|
||||
|
||||
## 6. Extensions and Helpers
|
||||
|
||||
| Helper | Purpose | Used By |
|
||||
|--------|---------|---------|
|
||||
| `RansacFilter` | shared with C3 | C3, C3.5, C4 |
|
||||
|
||||
## 7. Caveats & Edge Cases
|
||||
|
||||
**Known limitations**:
|
||||
- The threshold is a tunable; setting it too low triggers AdHoP every frame and breaks the AC-4.1 budget; too high lets bad matches through to C4. Calibration via NFT-PERF-01 invocation-rate measurement during planning's NFT validation cycle.
|
||||
- D-CROSS-LATENCY-1 hybrid does not directly change C3.5's behaviour; under thermal throttle, the elevated frame-to-frame latency may push the threshold to be raised at the operator-tooling level pre-flight (C12 concern).
|
||||
|
||||
**Potential race conditions**:
|
||||
- Stateless; concurrent calls are safe in principle but the hot path is single-threaded by design.
|
||||
|
||||
**Performance bottlenecks**:
|
||||
- AdHoP invocation is the variable cost in the F3 budget. NFT-PERF-01 measures the invocation rate; an invocation rate above ~30% suggests the threshold needs revisiting.
|
||||
|
||||
## 8. Dependency Graph
|
||||
|
||||
**Must be implemented after**: C3 (input), C7 (inference runtime).
|
||||
|
||||
**Can be implemented in parallel with**: C1, C6 — independent paths.
|
||||
|
||||
**Blocks**: C4, F3 / F6.
|
||||
|
||||
## 9. Logging Strategy
|
||||
|
||||
| Log Level | When | Example |
|
||||
|-----------|------|---------|
|
||||
| ERROR | `RefinerBackboneError` | `AdHoP backbone failure; frame=12345; falling through to passthrough` |
|
||||
| WARN | invocation rate over rolling 60 s exceeds budget | `AdHoP invocation rate 38% > target 25%; frame=12345` |
|
||||
| INFO | Strategy ready | `Refiner ready: strategy=adhop, threshold=2.5px` |
|
||||
| DEBUG | per-frame invoked/passthrough decision | `Refiner frame=12345 invoked=true added_latency_ms=42` |
|
||||
|
||||
**Log format**: structured JSON.
|
||||
**Log storage**: stdout / journald / FDR via C13 (ERROR + WARN only). DEBUG goes to FDR's per-frame estimate stream as a flag (`refinement_label`).
|
||||
@@ -0,0 +1,104 @@
|
||||
# Test Specification — C3.5 AdHoP-Conditional Refinement
|
||||
|
||||
Component-scoped. Suite-level coverage in `_docs/02_document/tests/*.md`.
|
||||
|
||||
## Acceptance Criteria Traceability
|
||||
|
||||
| AC ID | Acceptance Criterion (one-line) | Test IDs | Coverage |
|
||||
|-------|---------------------------------|----------|----------|
|
||||
| AC-2.2 (cross-domain MRE on hard frames) | MRE < 2.5 px after refinement | FT-P-06, **C3.5-IT-01** | Covered |
|
||||
| AC-4.1 | E2E latency budget under conditional invocation | NFT-PERF-01, **C3.5-PT-01** | Covered |
|
||||
|
||||
---
|
||||
|
||||
## Component-Internal Tests
|
||||
|
||||
### C3.5-IT-01: residual reduction under refinement
|
||||
|
||||
**Summary**: when `refine_if_needed` is invoked (residual > threshold), the post-refinement residual is strictly lower than the pre-refinement residual on ≥90% of invocations.
|
||||
|
||||
**Traces to**: AC-2.2 (hard-frame portion)
|
||||
|
||||
**Description**: prepare a fixture of "hard frames" (synthetic perspective skew that pushes the C3 residual above the threshold); run C3 → C3.5; assert `MatchResult.per_candidate[best].per_candidate_residual_px` post-refinement < pre-refinement value in ≥90% of invocations. The remaining ≤10% are accepted (refinement can legitimately fail to improve a frame; passthrough is the documented fallback).
|
||||
|
||||
**Input data**: `synthetic_matcher/hard_frames_perspective_skew_50f/`.
|
||||
|
||||
**Expected result**: improvement rate ≥ 0.90.
|
||||
|
||||
**Max execution time**: 5 min on Tier-1.
|
||||
|
||||
---
|
||||
|
||||
### C3.5-IT-02: passthrough fall-through on `RefinerBackboneError`
|
||||
|
||||
**Summary**: if the AdHoP backbone fails, C3.5 returns C3's original `MatchResult` unchanged with `refinement_label = "passthrough"`.
|
||||
|
||||
**Traces to**: defensive (no AC trace; backstops the conditional-refinement design contract)
|
||||
|
||||
**Description**: monkey-patch the AdHoP runtime to raise `RefinerBackboneError`; run 20 hard frames; assert (a) every frame produces a `MatchResult`, (b) `refinement_label == "passthrough"`, (c) error logged at ERROR level, (d) inlier coordinates equal C3's input coordinates bit-for-bit (no silent corruption).
|
||||
|
||||
**Input data**: as C3.5-IT-01.
|
||||
|
||||
**Expected result**: 20/20 passthrough; bit-identical correspondences.
|
||||
|
||||
**Max execution time**: 60 s.
|
||||
|
||||
---
|
||||
|
||||
### C3.5-IT-03: invocation rate stays under target on the steady-state path
|
||||
|
||||
**Summary**: on the Derkachi normal segment, the AdHoP invocation rate is below the 25% target threshold; if it exceeds 30%, the test fails (signals a threshold mis-tune).
|
||||
|
||||
**Traces to**: NFT-PERF-01 invocation-rate budget partition
|
||||
|
||||
**Description**: replay Derkachi normal segment; count `was_invoked()` true returns over 60 s rolling windows; assert max invocation rate < 0.30 (warning at 0.25 per the component spec § 9 logging table).
|
||||
|
||||
**Input data**: `flight_derkachi/normal_segment_60_stills/`.
|
||||
|
||||
**Expected result**: max invocation rate < 0.30.
|
||||
|
||||
**Max execution time**: 90 s.
|
||||
|
||||
---
|
||||
|
||||
## Performance Tests
|
||||
|
||||
### C3.5-PT-01: refinement-added latency budget
|
||||
|
||||
**Traces to**: AC-4.1
|
||||
|
||||
**Load scenario**: 3 Hz, mixed normal + hard frames (25% hard) replicating realistic invocation rate.
|
||||
|
||||
**Expected results**:
|
||||
|
||||
| Metric | Target | Failure Threshold |
|
||||
|--------|--------|-------------------|
|
||||
| `refine_if_needed` p95 (when invoked) | ≤ 90 ms (one extra backbone forward + perspective remap) | 150 ms |
|
||||
| `refine_if_needed` p95 (passthrough) | ≤ 0.5 ms | 2 ms |
|
||||
| Frame-aggregated added latency p95 | ≤ 25 ms (≤25% × 90 ms invocation; ≥75% × 0.5 ms passthrough) | 40 ms |
|
||||
|
||||
---
|
||||
|
||||
## Security Tests
|
||||
|
||||
C3.5 has no externally-reachable surface.
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Tests
|
||||
|
||||
Covered transitively via FT-P-06.
|
||||
|
||||
---
|
||||
|
||||
## Test Data Management
|
||||
|
||||
| Data Set | Source | Size |
|
||||
|----------|--------|------|
|
||||
| `synthetic_matcher/hard_frames_perspective_skew_50f/` | generated, deterministic | ~50 MB |
|
||||
| `flight_derkachi/normal_segment_60_stills/` | shared | shared |
|
||||
| AdHoP TRT engine | C7-built artifact | shared |
|
||||
|
||||
**Setup**: AdHoP engine must be compiled (deterministic; cached after first build).
|
||||
**Teardown**: read-only.
|
||||
**Data isolation**: per-test temp dirs.
|
||||
Reference in New Issue
Block a user