start over again

This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-07 04:08:03 +03:00
parent ee6606a9c2
commit 8382cdae10
351 changed files with 0 additions and 30337 deletions
@@ -1,115 +0,0 @@
# Camera Ingest And Calibration
## 1. High-Level Overview
**Purpose**: Ingest navigation-camera frames, attach timestamps and calibration metadata, undistort/normalize imagery, detect total occlusion/blackout before VIO, and classify image quality before VIO or satellite matching consumes it.
**Architectural Pattern**: Streaming adapter + validation gate.
**Upstream dependencies**: Navigation camera, camera calibration files.
**Downstream consumers**: VIO adapter, Satellite Service, anchor verification, Tile Manager, FDR.
## 2. Internal Interfaces
### Interface: `FrameProvider`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `next_frame` | `FrameRequest` | `FramePacket` | Yes | `FrameUnavailable`, `CalibrationMissing`, `InvalidFrame` |
| `detect_occlusion` | `FramePacket` | `OcclusionReport` | No | `InvalidFrame` |
| `classify_quality` | `FramePacket` | `ImageQualityReport` | No | `InvalidFrame` |
**Input DTOs**:
```yaml
FrameRequest:
source: enum(live_camera, replay_file)
timestamp_ns: integer optional
```
**Output DTOs**:
```yaml
FramePacket:
frame_id: string
timestamp_ns: integer
image_ref: path_or_buffer
camera_calibration_id: string
altitude_hint_m: number optional
occlusion: OcclusionReport
quality: ImageQualityReport
OcclusionReport:
status: enum(clear, partial_occlusion, total_occlusion, blackout)
reason: enum(cloud, lens_cover, whiteout, decode_failure, underexposed, overexposed, unknown) optional
usable_for_vio: boolean
usable_for_anchor: boolean
ImageQualityReport:
usable_for_vio: boolean
usable_for_anchor: boolean
blackout_detected: boolean
blur_score: number
texture_score: number
```
## 3. Data Access Patterns
| Query | Frequency | Hot Path | Index Needed |
|-------|-----------|----------|--------------|
| Load calibration by ID | Startup | Yes | No |
| Read replay frame | Test/replay | Yes | File order |
## 4. Implementation Details
**State Management**: Maintains current camera calibration version and frame sequence state.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| OpenCV | Decode, undistort, homography support, image metrics |
| Camera SDK / V4L2 / GigE SDK | Live camera access once interface is selected |
**Error Handling Strategy**:
- Camera or decode errors emit degraded quality and FDR events.
- Total occlusion or blackout sets `usable_for_vio=false`, bypasses BASALT for that frame, and emits a degradation signal to the safety/anchor wrapper.
- Missing calibration blocks production startup.
- ADTi public spec mismatch is tracked as a verification blocker until manufacturer spec is pinned.
## 5. Extensions and Helpers
| Helper | Purpose | Used By |
|--------|---------|---------|
| `geo_geometry_helper` | Coordinate transforms, GSD, WGS84/local conversions | Camera ingest, safety wrapper, Tile Manager |
## 6. Caveats & Edge Cases
**Known limitations**:
- Public ADTi pages list 2 fps continuous capture and -10..40 C operating range; project assumptions need manufacturer verification.
- Live camera interface is TBD.
- Total occlusion detection must be conservative: false positives cause temporary IMU-only degradation, while false negatives can feed unusable frames into VIO.
**Performance bottlenecks**:
- Full-resolution preprocessing must stay inside the <400 ms p95 pipeline budget.
## 7. Dependency Graph
**Must be implemented after**: none.
**Can be implemented in parallel with**: Tile Manager, MAVLink/GCS integration.
**Blocks**: VIO adapter, anchor verification, generated tile lifecycle.
## 8. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | Camera unavailable or calibration missing | `camera_calibration_missing id=...` |
| WARN | Frame degraded or occluded | `frame_quality_degraded occlusion=total_occlusion blur=... texture=...` |
| INFO | Calibration loaded | `camera_calibration_loaded version=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment and health log.
@@ -1,139 +0,0 @@
# Test Specification — Camera Ingest And Calibration
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-2.1a | VO registration uses only normal usable frames | IT-01, AT-01 | Covered |
| AC-3.5 | Visual blackout switches to degraded mode quickly | IT-02, AT-02 | Covered |
| AC-4.1 | Capture-to-output latency budget | PT-01 | Covered |
| AC-4.2 | Jetson memory budget | PT-01 | Covered |
| AC-8.4 | Mid-flight tile generation input eligibility | IT-03 | Covered |
| AC-8.5 | No raw frame retention | ST-01 | Covered |
| AC-NEW-8 | Full blackout/occlusion degraded-mode trigger | IT-02, AT-02 | Covered |
## Blackbox Tests
### IT-01: Usable Frame Classification
**Summary**: Verify normal nadir frames are marked usable for VIO and anchor matching.
**Traces to**: AC-2.1a
**Input data**: Project still images plus calibration metadata.
**Expected result**: `FramePacket.quality.usable_for_vio=true`, `usable_for_anchor=true`, and `occlusion.status=clear` for normal daytime textured frames.
**Max execution time**: 100 ms per frame.
**Dependencies**: Calibration file, replay fixture.
---
### IT-02: Total Occlusion Gate Before VIO
**Summary**: Verify total occlusion is detected before BASALT receives the frame.
**Traces to**: AC-3.5, AC-NEW-8
**Input data**: Black/white/covered-lens frames, corrupt frame fixture, low-texture whiteout frames.
**Expected result**: `occlusion.status` is `total_occlusion` or `blackout`, `usable_for_vio=false`, `usable_for_anchor=false`, and a degradation signal is emitted to the safety wrapper.
**Max execution time**: 100 ms per frame.
**Dependencies**: Safety wrapper test double.
---
### IT-03: Tile Generation Eligibility Metadata
**Summary**: Verify frame metadata required for generated tiles is available without persisting raw frames.
**Traces to**: AC-8.4, AC-8.5
**Input data**: Valid frame, altitude hint, calibration, pose fixture.
**Expected result**: Frame metadata supports orthorectification handoff; raw frame is not retained after processing outside allowed FDR thumbnail exception.
**Max execution time**: 100 ms per frame.
**Dependencies**: Tile Manager test double.
## Performance Tests
### PT-01: Ingest And Quality Latency
**Summary**: Verify decode, calibration lookup, occlusion detection, and quality classification stay inside the system latency budget.
**Traces to**: AC-4.1, AC-4.2
**Load scenario**:
- Input rate: target camera/replay rate.
- Duration: 30 minutes replay.
- Dataset: project still images plus synthetic occlusion frames.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Per-frame ingest p95 | <=100 ms | >150 ms |
| Memory contribution | <=1 GB | >1.5 GB |
| Dropped frames | <=10% under sustained load | >10% |
**Resource limits**: Jetson shared memory remains below system 8 GB cap.
## Security Tests
### ST-01: Raw Frame Retention Check
**Summary**: Verify normal operation does not persist raw navigation frames.
**Traces to**: AC-8.5
**Attack vector**: Sensitive raw imagery remains on disk after processing.
**Test procedure**:
1. Run replay with normal and failed tile-generation frames.
2. Inspect output directories and FDR artifacts.
**Expected behavior**: Only metadata, generated tiles, and allowed low-rate failed-frame thumbnails are retained.
**Pass criteria**: No raw full-resolution frames remain after teardown.
## Acceptance Tests
### AT-01: Normal Frame Enters VIO
**Summary**: Confirm normal usable frames are passed to BASALT.
**Traces to**: AC-2.1a
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Feed a calibrated normal frame | Occlusion status is `clear` |
| 2 | Process quality gate | Frame is emitted to VIO adapter |
---
### AT-02: Occluded Frame Bypasses VIO
**Summary**: Confirm full occlusion triggers IMU-only degraded path.
**Traces to**: AC-3.5, AC-NEW-8
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Feed total-occlusion frame | `usable_for_vio=false` |
| 2 | Observe downstream routing | BASALT is bypassed and safety wrapper receives degradation signal |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `project_60_still_images` | Normal nadir frames | `_docs/00_problem/input_data/` | Project data |
| `synthetic_occlusion_frames` | Black/white/corrupt/whiteout frames | Generated fixture | Small |
**Setup procedure**: Load calibration fixture and mount read-only frame data.
**Teardown procedure**: Remove run-scoped temp directories and verify no raw-frame persistence.
**Data isolation strategy**: Each run writes to a unique `test-results/<run-id>/` directory.
@@ -1,105 +0,0 @@
# VIO Adapter
## 1. High-Level Overview
**Purpose**: Wrap the selected relative VIO backend as a replaceable component that consumes calibrated frames and FC IMU data, then emits relative pose/velocity/bias state and tracking quality.
**Architectural Pattern**: Adapter / anti-corruption layer.
**Upstream dependencies**: Camera ingest/calibration, MAVLink telemetry stream.
**Downstream consumers**: Safety/anchor wrapper, FDR, separate e2e test suite.
## 2. Internal Interfaces
### Interface: `VioAdapter`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `initialize` | selected `VioBackend` / `VioRuntimeConfig` | updates `VioHealthReport` | No | backend initialization / native prerequisite errors |
| `process` | `VioInputPacket` | `VioProcessingResult` | No | timestamp mismatch, backend runtime errors |
| `health` | none | `VioHealthReport` | No | none |
**Input DTOs**:
```yaml
VioInputPacket:
frame: FramePacket
telemetry_samples: list[TelemetrySample]
VioRuntimeConfig:
environment: development | ci | staging | jetson | production
mode: replay | native optional
native_backend_name: string
native_runner_module: string
native_runner_factory: string
native_runner_config: object
```
**Output DTOs**:
```yaml
VioStatePacket:
timestamp_ns: integer
relative_pose: transform
velocity: vector3
bias_estimate: object optional
tracking_quality: number
covariance_hint: matrix optional
VioProcessingResult:
state_packet: VioStatePacket optional
health: VioHealthReport
processing_latency_ms: number optional
error: ErrorEnvelope optional
```
## 3. Data Access Patterns
No persistent production data ownership. Reads calibration/config at startup and emits state to downstream consumers.
## 4. Implementation Details
**State Management**: Owns selected VIO backend runtime state and resets only through explicit wrapper command.
**Runtime Selection**: `create_vio_adapter` selects replay mode only for explicit development/replay configuration. Production and Jetson profiles derive native mode, instantiate `ConfiguredNativeVioBackend`, and load a BASALT-compatible runner through `BasaltNativeRunner`.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| BASALT | Current selected relative visual-inertial odometry backend |
| Eigen/Sophus or backend-native math stack | Pose and transform representation |
**Error Handling Strategy**:
- Missing or invalid production native runtime prerequisites fail initialization with explicit health/error state and no replay-derived successful VIO output.
- Tracking loss is surfaced to the safety/anchor wrapper, not hidden.
- Timestamp/camera-IMU sync violations fail the packet and are logged.
- The adapter never emits WGS84 coordinates; absolute semantics belong to the wrapper.
## 5. Caveats & Edge Cases
**Known limitations**:
- BASALT has no special fixed-wing nadir mode; validation must prove fit under low-parallax/planar terrain.
- Backend covariance/confidence output is not the product authority; wrapper calibration is required.
**Performance bottlenecks**:
- Native VIO runtime and image resolution can exceed Jetson budget if not tuned.
## 6. Dependency Graph
**Must be implemented after**: Camera ingest/calibration, MAVLink telemetry DTO definitions.
**Can be implemented in parallel with**: Satellite Service, Tile Manager.
**Blocks**: Safety/anchor wrapper final integration.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | VIO backend initialization fails | `vio_init_failed reason=...` |
| WARN | Tracking quality drops | `vio_tracking_degraded quality=...` |
| INFO | VIO reset/reinitialized | `vio_reset cause=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment.
@@ -1,141 +0,0 @@
# Test Specification — VIO Adapter
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-1.3 | Drift between anchors and anchor-age reporting input | IT-02, AT-01 | Covered |
| AC-2.1a | >95% VO registration on normal segments | IT-01, AT-01 | Covered |
| AC-2.2 | <1.0 px VO MRE | IT-01 | Covered |
| AC-3.1 | Handles 350 m outliers/tilt | IT-03 | Covered |
| AC-3.2 | Sharp turns trigger relocalization path | IT-04 | Covered |
| AC-3.4 | Loss threshold feeds relocalization/dead reckoning | IT-04 | Covered |
| AC-4.1 | Hot-path latency | PT-01 | Covered |
| AC-4.2 | Jetson memory budget | PT-01 | Covered |
## Blackbox Tests
### IT-01: Public Dataset VIO Replay
**Summary**: Verify the VIO adapter produces relative motion for synchronized camera/IMU replay.
**Traces to**: AC-2.1a, AC-2.2
**Input data**: Derkachi cropped nadir video + `SCALED_IMU2` + `GLOBAL_POSITION_INT`, MUN-FRL preferred slice, or representative synchronized nav-camera + IMU + ground truth.
**Expected result**: VO registration succeeds for >95% of normal usable frames; frame-to-frame MRE <1.0 px where ground-truth/feature evaluation supports it. Derkachi runs are accepted as calibration-limited until intrinsics, distortion, and camera-to-body transform are pinned.
**Max execution time**: Dataset-dependent; report per-frame latency.
**Dependencies**: Camera ingest, MAVLink telemetry/replay, calibration fixtures.
---
### IT-02: Relative Drift Reporting
**Summary**: Verify adapter emits state needed for wrapper drift and anchor-age accounting.
**Traces to**: AC-1.3
**Input data**: Segment with two known satellite anchors and IMU samples.
**Expected result**: Adapter emits continuous `VioStatePacket` values with timestamps and quality, enabling wrapper to compare VO extrapolation to next anchor.
**Max execution time**: Dataset-dependent.
**Dependencies**: Safety wrapper test harness.
---
### IT-03: Tilt/Outlier Robustness
**Summary**: Verify adapter reports degraded tracking without false success under tilt/outlier cases.
**Traces to**: AC-3.1
**Input data**: Replay segment with synthetic +/-20 degree tilt and up to 350 m apparent outlier.
**Expected result**: Adapter either tracks with quality metadata or emits `TrackingLost`; it never hides a failure as high-quality VIO.
**Max execution time**: 15 minutes per fixture.
---
### IT-04: Sharp Turn / Loss Signal
**Summary**: Verify sharp turns and disconnected visual overlap produce wrapper-visible failure signals.
**Traces to**: AC-3.2, AC-3.4
**Input data**: <5% overlap sequence with heading change <70 degrees.
**Expected result**: Adapter emits low tracking quality or `TrackingLost` within the loss window, allowing relocalization trigger.
**Max execution time**: 10 minutes.
## Performance Tests
### PT-01: VIO Adapter Runtime Budget
**Summary**: Verify VIO processing does not consume the full <400 ms system p95 budget.
**Traces to**: AC-4.1, AC-4.2
**Load scenario**:
- Input: Derkachi synchronized replay and public/representative replay.
- Duration: 30 minutes plus release long-run slice.
- Target: Jetson Orin Nano Super.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Adapter p95 latency | <=250 ms | >300 ms |
| Memory contribution | <=3 GB | >4 GB |
| Tracking failure on normal segments | <5% | >=5% |
**Resource limits**: Total system memory remains below 8 GB.
## Security Tests
### ST-01: Timestamp Injection Rejection
**Summary**: Verify malformed or non-monotonic timestamps do not produce trusted VIO state.
**Traces to**: AC-NEW-4
**Attack vector**: Replay or telemetry timestamp manipulation.
**Test procedure**:
1. Feed non-monotonic frame and IMU timestamps.
2. Observe adapter output.
**Expected behavior**: Adapter returns `TimestampMismatch` or low-quality failure; wrapper does not trust the state.
**Pass criteria**: No high-quality VIO state is emitted from malformed timing.
## Acceptance Tests
### AT-01: Normal VIO State Contract
**Summary**: Confirm adapter output contract supports downstream localization.
**Traces to**: AC-1.3, AC-2.1a
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Initialize with calibrated frame/IMU config | `VioInitResult` succeeds |
| 2 | Replay normal frames | `VioStatePacket` includes timestamp, relative pose, velocity, tracking quality |
| 3 | End segment | State stream is continuous enough for wrapper drift accounting |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `derkachi_video_telemetry` | Cropped nadir MP4 + synchronized IMU and `GLOBAL_POSITION_INT` trajectory | Project fixture | ~282 MB video + CSV |
| `public_nadir_vio_candidates` | MUN-FRL/ALTO/Kagaru/EPFL slices | Public pinned fixtures | Dataset-dependent |
| `representative_sync_replay` | Target camera + FC IMU + calibrated ground truth | Project collection | TBD |
**Setup procedure**: Pin calibration/extrinsics and mount read-only synchronized replay data.
**Teardown procedure**: Remove generated result reports and adapter temp state.
**Data isolation strategy**: One run directory per dataset slice and configuration hash.
@@ -1,106 +0,0 @@
# Safety And Anchor Wrapper
## 1. High-Level Overview
**Purpose**: Own the authoritative localization state, confidence calibration, source labels, anchor fusion, degraded modes, tile-write gates, and MAVLink output semantics.
**Architectural Pattern**: Stateful coordinator / safety facade.
**Upstream dependencies**: VIO adapter, anchor verification, MAVLink telemetry, camera quality reports.
**Downstream consumers**: MAVLink/GCS integration, FDR, Tile Manager, separate e2e test suite.
## 2. Internal Interfaces
### Interface: `LocalizationStateMachine`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `update_vio` | `VioStatePacket` | `PositionEstimate` | Yes | `StateInconsistent` |
| `consider_anchor` | `AnchorDecision` | `AnchorAcceptanceResult` | No | `AnchorRejected` |
| `degrade` | `DegradationSignal` | `PositionEstimate` | No | none |
| `propagate_imu_only` | `ImuOnlyPropagationRequest` | `PositionEstimate` | Yes | `InsufficientTelemetry` |
| `tile_write_eligibility` | `FramePacket` | `TileWriteDecision` | No | none |
**Input DTOs**:
```yaml
AnchorDecision:
candidate_id: string
timestamp_ns: integer
estimated_pose_wgs84: object
inlier_count: integer
mre_px: number
tile_freshness_status: enum
provenance_status: enum
DegradationSignal:
type: enum(total_occlusion, visual_blackout, gps_spoofing, covariance_growth, tracking_lost)
timestamp_ns: integer
ImuOnlyPropagationRequest:
last_trusted_estimate: PositionEstimate
imu_samples: list[TelemetrySample]
elapsed_blackout_ms: integer
reason: enum(total_occlusion, visual_blackout, tracking_lost)
```
**Output DTOs**:
```yaml
PositionEstimate:
timestamp_ns: integer
lat_deg: number
lon_deg: number
alt_msl_m: number
covariance_95_semi_major_m: number
source_label: enum(satellite_anchored, vo_extrapolated, dead_reckoned)
fix_type: integer
horiz_accuracy_m: number
last_satellite_anchor_age_ms: integer
```
## 3. Data Access Patterns
No direct tile/image storage ownership. Writes all decisions to FDR via observability component.
## 4. Implementation Details
**State Management**: Owns the authoritative state machine and covariance growth model.
**Error Handling Strategy**:
- Reject uncertain anchors by default.
- Never emit optimistic accuracy when confidence is degraded.
- On total occlusion or visual blackout, do not call VIO for that frame; propagate from the last trusted state with IMU-only dynamics, set `source_label=dead_reckoned`, and grow covariance monotonically.
- If covariance or blackout thresholds exceed AC limits, emit no-fix/failsafe semantics.
- Treat cache freshness and provenance as evidence carried by `AnchorDecision`; do not call the Tile Manager directly during anchor acceptance.
## 5. Caveats & Edge Cases
**Known limitations**:
- Final covariance calibration requires representative synchronized data.
- The wrapper must stay independent of BASALT internals so VIO can be replaced.
- IMU-only propagation is an emergency bridge, not a reliable long-duration localization mode; the spec requires failsafe/no-fix once time or covariance thresholds are exceeded.
**Potential race conditions**:
- A delayed anchor result must be checked against current timestamp/state before acceptance.
## 6. Dependency Graph
**Must be implemented after**: VIO DTOs, anchor DTOs, MAVLink output contract.
**Can be implemented in parallel with**: FDR schema after DTOs stabilize.
**Blocks**: MAVLink production output, tile-write lifecycle, end-to-end validation.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | State invariant violation | `localization_state_inconsistent reason=...` |
| WARN | Anchor rejected or mode degraded | `anchor_rejected reason=mahalanobis_gate` |
| INFO | Mode transition | `source_label_changed from=vo_extrapolated to=dead_reckoned reason=total_occlusion` |
**Log format**: FDR structured event.
**Log storage**: FDR segment and QGC status for operator-critical events.
@@ -1,208 +0,0 @@
# Test Specification — Safety And Anchor Wrapper
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-1.1 | >=80% within 50 m | AT-01 | Covered |
| AC-1.2 | >=50% within 20 m | AT-01 | Covered |
| AC-1.3 | Drift and anchor age | IT-01 | Covered |
| AC-1.4 | Quantitative confidence + label | IT-02, AT-02 | Covered |
| AC-3.4 | Relocalization after no-position window | IT-03 | Covered |
| AC-3.5 | Blackout to dead reckoned | IT-04, AT-03 | Covered |
| AC-4.3 | GPS_INPUT semantics source fields | IT-05 | Covered |
| AC-4.4 | Frame-by-frame streaming | PT-01 | Covered |
| AC-4.5 | Correction updates | IT-06 | Covered |
| AC-5.1 | Initialize from FC state | IT-07 | Covered |
| AC-5.2 | >3 s no-estimate fallback | IT-03 | Covered |
| AC-5.3 | Reinitialize after reboot | IT-07 | Covered |
| AC-NEW-2 | Spoofing promotion <3 s | IT-05 | Covered |
| AC-NEW-4 | False-position safety budget | ST-01, AT-02 | Covered |
| AC-NEW-8 | IMU-only blackout thresholds | IT-04, AT-03 | Covered |
## Blackbox Tests
### IT-01: Drift And Anchor Age Accounting
**Summary**: Verify VO extrapolation drift and anchor age are tracked per estimate.
**Traces to**: AC-1.3
**Input data**: VIO state stream with two accepted anchor decisions.
**Expected result**: Every `PositionEstimate` includes `last_satellite_anchor_age_ms`; drift at next anchor is measured and binned by age.
**Max execution time**: 5 minutes.
---
### IT-02: Confidence Output Contract
**Summary**: Verify every estimate has covariance and source label.
**Traces to**: AC-1.4
**Input data**: satellite-anchored, VO-extrapolated, and dead-reckoned state fixtures.
**Expected result**: Each output contains `covariance_95_semi_major_m`, `source_label`, `fix_type`, and `horiz_accuracy_m`; `horiz_accuracy_m` never under-reports covariance.
**Max execution time**: 2 minutes.
---
### IT-03: No-Position Relocalization Trigger
**Summary**: Verify no position for >=3 frames and >=2 s triggers relocalization/degraded behavior.
**Traces to**: AC-3.4, AC-5.2
**Input data**: VIO loss sequence with no accepted anchors.
**Expected result**: Relocalization request is emitted and wrapper continues dead reckoning until fail threshold.
**Max execution time**: 5 minutes.
---
### IT-04: Total Blackout IMU-Only Propagation
**Summary**: Verify total occlusion produces honest IMU-only estimates and failsafe thresholds.
**Traces to**: AC-3.5, AC-NEW-8
**Input data**: Last trusted estimate, IMU/attitude/airspeed/altitude stream, total-occlusion signal for 5 s, 15 s, and 35 s.
**Expected result**: Wrapper emits `dead_reckoned` within <=1 frame or <=400 ms, covariance grows monotonically, and no-fix/failsafe is emitted when blackout >30 s or covariance >500 m.
**Max execution time**: 10 minutes.
---
### IT-05: Spoofing Promotion And GPS_INPUT Mapping
**Summary**: Verify wrapper promotes own estimate and maps output fields correctly under GPS spoofing.
**Traces to**: AC-4.3, AC-NEW-2
**Input data**: Plane SITL spoofing telemetry and trusted wrapper estimate.
**Expected result**: Own estimate is promoted within <3 s; v1 emits `GPS_INPUT` only; source labels and accuracy fields are correct.
**Max execution time**: 10 minutes.
---
### IT-06: Correction Update
**Summary**: Verify refined estimates can correct previous positions.
**Traces to**: AC-4.5
**Input data**: VO estimate followed by accepted satellite anchor for same segment.
**Expected result**: Wrapper emits updated estimate/correction with improved source label and covariance.
**Max execution time**: 5 minutes.
---
### IT-07: Initialization And Reboot Recovery
**Summary**: Verify wrapper initializes from FC state and can reinitialize after reboot.
**Traces to**: AC-5.1, AC-5.3
**Input data**: FC EKF position, IMU-extrapolated state, simulated companion restart.
**Expected result**: Wrapper resumes from current FC state and reports degraded confidence until re-anchored.
**Max execution time**: 5 minutes.
## Performance Tests
### PT-01: Wrapper Streaming Overhead
**Summary**: Verify state-machine processing does not delay frame-by-frame output.
**Traces to**: AC-4.4
**Load scenario**:
- Input: 3 Hz estimate stream with anchor and blackout events.
- Duration: 8-hour synthetic run.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Wrapper p95 processing | <=25 ms | >50 ms |
| Missed frame outputs | 0 except skip-allowed upstream drops | Any silent batch/delay |
**Resource limits**: Negligible memory growth across run.
## Security Tests
### ST-01: False Anchor Rejection
**Summary**: Verify impossible anchors do not become trusted estimates.
**Traces to**: AC-NEW-4
**Attack vector**: Anchor decision with plausible inliers but impossible jump or stale provenance.
**Test procedure**:
1. Feed an anchor >1 km from predicted state with low covariance.
2. Feed stale/provenance-failed anchor evidence.
**Expected behavior**: Anchor is rejected, FDR logs reason, source label remains degraded or VO extrapolated.
**Pass criteria**: 0 accepted impossible/stale anchors.
## Acceptance Tests
### AT-01: Position Accuracy Aggregation
**Summary**: Verify wrapper outputs can be scored against frame-center thresholds.
**Traces to**: AC-1.1, AC-1.2
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Replay mapped frame-center estimates | Report computes >=80% within 50 m and >=50% within 20 m |
| 2 | Include source labels | Accuracy is binned by source label |
---
### AT-02: Confidence Honesty
**Summary**: Verify reported confidence is conservative relative to measured error.
**Traces to**: AC-1.4, AC-NEW-4
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Replay ground-truth trajectory | Measured error is not systematically above reported covariance |
| 2 | Inject over-confident anchors | Mahalanobis gate rejects them |
---
### AT-03: Blackout Failsafe
**Summary**: Verify operator-visible blackout/failsafe behavior.
**Traces to**: AC-3.5, AC-NEW-8
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Inject total visual blackout | `dead_reckoned` within <=400 ms |
| 2 | Continue >30 s or covariance >500 m | `fix_type=0`, `horiz_accuracy=999.0`, QGC failsafe status |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `wrapper_state_fixtures` | VIO states, anchors, blackouts, spoofing signals | Generated fixtures | Small |
| `representative_replay` | Target synchronized replay and ground truth | Project collection | TBD |
**Setup procedure**: Load deterministic VIO/anchor/telemetry fixtures and run with isolated PostgreSQL schema.
**Teardown procedure**: Drop run schema and remove FDR segments.
**Data isolation strategy**: Use per-run mission IDs and database schemas.
@@ -1,102 +0,0 @@
# Satellite Service
## 1. High-Level Overview
**Purpose**: Own the onboard boundary to the suite Satellite Service: import pre-flight mission cache packages, upload generated-tile packages after flight, and convert query frames into ranked local VPR candidates using preloaded DINOv2-VLAD descriptors and FAISS.
**Architectural Pattern**: Offline sync gateway + local retrieval index adapter.
**Upstream dependencies**: Camera ingest/calibration, Tile Manager, safety/anchor wrapper, Azaion Suite Satellite Service before/after flight.
**Downstream consumers**: Anchor verification, FDR.
## 2. Internal Interfaces
### Interface: `SatelliteService`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `import_mission_cache` | `CacheImportRequest` | `CacheImportResult` | Yes | `SyncUnavailable`, `PackageInvalid` |
| `upload_generated_tiles` | `GeneratedTileUploadRequest` | `GeneratedTileUploadResult` | Yes | `SyncUnavailable`, `PackageRejected` |
| `retrieve` | `RetrievalRequest` | `RetrievalResult` | Yes | `IndexUnavailable`, `DescriptorFailed` |
| `load_index` | `IndexLoadRequest` | `IndexStatus` | No | `ManifestInvalid`, `IndexUnavailable` |
**Input DTOs**:
```yaml
RetrievalRequest:
frame: FramePacket
prior_estimate: PositionEstimate optional
search_radius_m: number optional
max_candidates: integer
```
**Output DTOs**:
```yaml
RetrievalResult:
query_descriptor_id: string
candidates: list[VprCandidate]
VprCandidate:
chunk_id: string
tile_id: string
score: number
footprint: geometry
freshness_status: enum
```
## 3. Data Access Patterns
| Query | Frequency | Hot Path | Index Needed |
|-------|-----------|----------|--------------|
| Top-K FAISS search | Triggered only | No steady-state | FAISS index |
| Import/export package sync | Pre-flight / post-flight only | No mid-flight | Package manifest and sidecar hashes |
| Load chunk metadata | Per candidate | No | PostgreSQL/PostGIS spatial and chunk indexes |
## 4. Implementation Details
**State Management**: Holds loaded descriptor model and FAISS index handles; tracks pre-flight import and post-flight upload package status.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| DINOv2 / ONNX / TensorRT candidate path | Query descriptor extraction |
| FAISS CPU | Top-K retrieval |
| Satellite Service client | Pre-flight cache import and post-flight generated-tile upload |
**Error Handling Strategy**:
- If descriptor extraction or index load fails, return no candidates and trigger degraded mode.
- Optimized engines are allowed only after descriptor-fidelity tests pass.
- Network/package sync failures are allowed only before takeoff or after landing; during flight, the component must never call a satellite provider or suite service.
## 5. Caveats & Edge Cases
**Known limitations**:
- VPR result is only a candidate, never an accepted fix.
- Cross-domain retrieval can be wrong under seasonal, lighting, or terrain ambiguity.
- External Satellite Service availability cannot be part of the mid-flight localization safety case.
**Performance bottlenecks**:
- Descriptor extraction on Jetson must be trigger-limited and profiled separately from BASALT.
## 6. Dependency Graph
**Must be implemented after**: cache manifest/index schema, camera frame DTOs.
**Can be implemented in parallel with**: anchor verification.
**Blocks**: satellite relocalization flow.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | Index unavailable | `faiss_index_unavailable id=...` |
| WARN | No candidates | `vpr_no_candidates frame_id=...` |
| INFO | Retrieval invoked | `vpr_query candidates=... latency_ms=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment.
@@ -1,172 +0,0 @@
# Test Specification — Satellite Service
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-3.2 | Sharp-turn relocalization | IT-02, AT-01 | Covered |
| AC-3.3 | >=3 disconnected segments | IT-03 | Covered |
| AC-3.4 | Relocalization request after loss | IT-02 | Covered |
| AC-4.1 | Trigger path latency | PT-01 | Covered |
| AC-4.2 | Memory budget | PT-01 | Covered |
| AC-8.1 | Cache imagery interface | IT-01 | Covered |
| AC-8.3 | Preloaded/preprocessed cache | IT-01 | Covered |
| AC-8.6 | VPR chunks, multi-scale, dynamic K | IT-01, IT-04 | Covered |
| AC-NEW-1 | Cold-start first fix support | PT-02 | Covered |
| AC-NEW-6 | Freshness-aware retrieval | IT-04, ST-01 | Covered |
## Blackbox Tests
### IT-01: Index Load And Chunk Coverage
**Summary**: Verify preloaded VPR chunks and FAISS index cover the operational area.
**Traces to**: AC-8.1, AC-8.3, AC-8.6
**Input data**: PostgreSQL/PostGIS cache manifest, VPR chunk metadata, FAISS index.
**Expected result**: Every test frame footprint falls inside at least one VPR chunk; fine and coarse descriptors are present where required.
**Max execution time**: 2 minutes per mission cache.
---
### IT-02: Sharp-Turn Local Retrieval Trigger
**Summary**: Verify sharp-turn state requests candidates rather than relying on frame-to-frame VO.
**Traces to**: AC-3.2, AC-3.4
**Input data**: Wrapper relocalization request with sharp-turn/loss reason.
**Expected result**: Satellite Service returns bounded top-K candidates from preloaded local indexes based on sector/covariance policy.
**Max execution time**: 2 seconds per query.
---
### IT-03: Disconnected Segment Retrieval
**Summary**: Verify at least three disconnected segments can each retrieve candidate chunks.
**Traces to**: AC-3.3
**Input data**: Three disconnected query frames with approximate prior/covariance.
**Expected result**: Each query returns a candidate set including the ground-truth region when covered by the cache fixture.
**Max execution time**: Dataset-dependent.
---
### IT-04: Dynamic K And Freshness Filter
**Summary**: Verify K varies by sector and covariance, and stale candidates are tagged.
**Traces to**: AC-8.6, AC-NEW-6
**Input data**: Stable and active-conflict sector cache fixtures with fresh/stale tiles.
**Expected result**: K=5 for stable low-covariance, K=20 for active-conflict, K=50 fallback; stale candidates are flagged for rejection/down-confidence.
**Max execution time**: 2 seconds per query.
## Performance Tests
### PT-01: Retrieval Query Runtime
**Summary**: Verify descriptor extraction and FAISS query fit trigger-path budget.
**Traces to**: AC-4.1, AC-4.2
**Load scenario**:
- Query set: 100 representative relocalization frames.
- Environment: Jetson and replay workstation.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Retrieval p95 | <=300 ms trigger path share | >400 ms |
| Memory contribution | <=2 GB | >3 GB |
| Candidate count policy | Exact | Any wrong K |
**Resource limits**: Total system memory remains below 8 GB.
---
### PT-02: Cold-Start Index Load
**Summary**: Verify retrieval readiness supports first fix <30 s.
**Traces to**: AC-NEW-1
**Load scenario**:
- Cold boot 50 runs.
- Cache/index mounted locally.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Index ready p95 | <=10 s | >15 s |
| First retrieval p95 | Fits <30 s first-fix budget | Exceeds budget |
## Security Tests
### ST-01: Stale Candidate Handling
**Summary**: Verify stale imagery cannot silently appear as a trusted retrieval candidate.
**Traces to**: AC-NEW-6
**Attack vector**: Manipulated cache manifest marks stale tile as available.
**Test procedure**:
1. Load cache fixture with stale capture dates.
2. Query against stale region.
**Expected behavior**: Candidate carries stale status; anchor path cannot accept it as `satellite_anchored`.
**Pass criteria**: 0 stale candidates without explicit stale/down-confidence metadata.
---
### ST-02: No Mid-Flight Satellite Service Calls
**Summary**: Verify relocalization never performs satellite-provider or suite Satellite Service network calls during flight.
**Traces to**: AC-8.3, R-SAT-01
**Attack vector**: Runtime attempts to fetch missing cache/index data over the network during relocalization.
**Test procedure**:
1. Disable external network access during a replay scenario.
2. Trigger relocalization against preloaded cache fixtures.
3. Inspect network call logs and Satellite Service client telemetry.
**Expected behavior**: Retrieval uses only mounted local cache/index data; missing data produces degraded/no-candidate behavior, not a network fetch.
**Pass criteria**: 0 mid-flight Satellite Service or satellite-provider calls.
## Acceptance Tests
### AT-01: Relocalization Candidate Returned
**Summary**: Verify a relocalization request returns usable candidates for anchor verification.
**Traces to**: AC-3.2, AC-8.6
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Submit sharp-turn query | Retrieval invokes VPR |
| 2 | Read output | Candidate list includes chunk IDs, tile IDs, scores, footprints, freshness |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `cache_vpr_fixture` | PostGIS manifest, COGs, descriptors, FAISS index | Generated/cache fixture | Mission-dependent |
| `aerial_vpr_queries` | Aerial query frames with ground-truth regions | ALTO/AerialVL/representative | Dataset-dependent |
**Setup procedure**: Restore isolated PostgreSQL schema and mount read-only descriptor/index files.
**Teardown procedure**: Drop schema and remove generated retrieval reports.
**Data isolation strategy**: Per-run schema and read-only cache fixture volume.
@@ -1,93 +0,0 @@
# Anchor Verification
## 1. High-Level Overview
**Purpose**: Verify retrieved cache candidates with local feature matching and geometric checks before the safety wrapper considers an absolute anchor.
**Architectural Pattern**: Validation pipeline.
**Upstream dependencies**: Satellite Service, camera ingest/calibration, Tile Manager.
**Downstream consumers**: Safety/anchor wrapper, FDR.
## 2. Internal Interfaces
### Interface: `AnchorVerifier`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `verify` | `AnchorVerificationRequest` | `AnchorDecision` | Yes | `TileUnavailable`, `MatchFailed`, `GeometryFailed` |
| `benchmark_matcher` | `MatcherBenchmarkRequest` | `MatcherBenchmarkReport` | Yes | `ModelUnavailable` |
**Input DTOs**:
```yaml
AnchorVerificationRequest:
frame: FramePacket
candidates: list[VprCandidate]
matcher_profile: enum(aliked, disk, sift_orb_baseline)
```
**Output DTOs**:
```yaml
AnchorDecision:
candidate_id: string
accepted_by_geometry: boolean
estimated_pose_wgs84: object optional
inlier_count: integer
mre_px: number
homography: matrix optional
rejection_reason: string optional
```
## 3. Data Access Patterns
| Query | Frequency | Hot Path | Index Needed |
|-------|-----------|----------|--------------|
| Read candidate COG footprint/window | Triggered only | No | Tile spatial metadata |
| Read matcher model | Startup | No | No |
## 4. Implementation Details
**State Management**: Loads matcher/extractor models and tracks benchmark-selected profile.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| ALIKED/DISK + LightGlue | Learned local matching |
| OpenCV | RANSAC/USAC geometry and error metrics |
**Error Handling Strategy**:
- Low inlier count, high MRE, stale tile, or provenance failure returns a rejected decision with reason.
- SuperPoint can be benchmarked only if legal approval allows its license use.
## 5. Caveats & Edge Cases
**Known limitations**:
- ALIKED-LightGlue is not VIO by itself; it supplies correspondences. A full VIO path still needs state estimation and IMU fusion.
- Optional frame-to-frame VO fallback must be benchmarked separately from cross-domain anchor verification.
**Performance bottlenecks**:
- Learned matching can exceed the Jetson budget if run per-frame; default invocation is trigger-based.
## 6. Dependency Graph
**Must be implemented after**: Satellite Service candidate DTOs, Tile Manager tile access.
**Can be implemented in parallel with**: VIO adapter.
**Blocks**: accepted satellite-anchor path.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | Matcher model unavailable | `lightglue_model_unavailable profile=aliked` |
| WARN | Candidate rejected | `anchor_geometry_rejected mre_px=... inliers=...` |
| INFO | Anchor verified | `anchor_verified tile_id=... mre_px=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment.
@@ -1,124 +0,0 @@
# Test Specification — Anchor Verification
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-1.1 | 50 m frame-center accuracy via accepted anchors | AT-01 | Covered |
| AC-1.2 | 20 m stretch accuracy via accepted anchors | AT-01 | Covered |
| AC-2.1b | Satellite-anchor registration measured separately | IT-01 | Covered |
| AC-2.2 | <2.5 px cross-domain MRE | IT-01, AT-01 | Covered |
| AC-3.1 | Outlier rejection | ST-01 | Covered |
| AC-4.1 | Trigger-path latency | PT-01 | Covered |
| AC-4.2 | Memory budget | PT-01 | Covered |
| AC-NEW-4 | False-position safety budget | ST-01 | Covered |
| AC-NEW-6 | Stale imagery rejection evidence | IT-02, ST-02 | Covered |
## Blackbox Tests
### IT-01: Cross-Domain Match And RANSAC
**Summary**: Verify ALIKED/DISK-LightGlue plus RANSAC produces measurable anchor evidence.
**Traces to**: AC-2.1b, AC-2.2
**Input data**: UAV frame, retrieved COG candidate window, ground-truth georegistration.
**Expected result**: Accepted anchors have MRE <2.5 px, sufficient inliers, and homography/pose evidence.
**Max execution time**: 2 seconds per candidate set.
---
### IT-02: Stale Candidate Verification
**Summary**: Verify stale or provenance-failed candidates are rejected or marked unsafe.
**Traces to**: AC-NEW-6
**Input data**: Candidate list with stale tile metadata and valid-looking image content.
**Expected result**: `AnchorDecision` is rejected or carries stale/provenance failure; safety wrapper cannot accept it as trusted.
**Max execution time**: 2 seconds per candidate.
## Performance Tests
### PT-01: Local Matcher Runtime
**Summary**: Verify learned matching stays bounded on Jetson when invoked.
**Traces to**: AC-4.1, AC-4.2
**Load scenario**:
- Candidate sets: K=5, K=20, K=50.
- Matcher profiles: ALIKED, DISK, SIFT/ORB baseline.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| K=5 p95 | <=300 ms | >500 ms |
| K=20 p95 | Reported and bounded | Unbounded/no report |
| Memory contribution | <=2 GB | >3 GB |
**Resource limits**: Total Jetson shared memory remains below 8 GB.
## Security Tests
### ST-01: False Match / Impossible Jump Rejection
**Summary**: Verify visually plausible but geographically impossible matches are rejected.
**Traces to**: AC-3.1, AC-NEW-4
**Attack vector**: Candidate tile from wrong region with repetitive texture.
**Test procedure**:
1. Pair query with wrong-region candidate.
2. Run matcher and RANSAC.
3. Pass result to safety wrapper fixture.
**Expected behavior**: Anchor is rejected by geometry or downstream consistency gates.
**Pass criteria**: 0 accepted anchors from wrong-region fixtures.
---
### ST-02: Provenance Failure
**Summary**: Verify unsigned/hash-failed candidate tiles cannot produce accepted anchors.
**Traces to**: AC-NEW-6
**Attack vector**: Tampered COG or sidecar.
**Test procedure**: Run verification against tampered tile fixture.
**Expected behavior**: `AnchorDecision` includes provenance failure and is not accepted.
**Pass criteria**: 0 trusted anchors from tampered tiles.
## Acceptance Tests
### AT-01: Accepted Anchor Accuracy
**Summary**: Verify accepted anchors support position accuracy thresholds.
**Traces to**: AC-1.1, AC-1.2, AC-2.2
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Verify satellite candidate against query | MRE <2.5 px |
| 2 | Convert accepted anchor to WGS84 evidence | Error supports 50 m / 20 m aggregate thresholds |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `anchor_match_fixture` | Query frames, COG windows, expected georegistration | ALTO/AerialVL/project cache | Dataset-dependent |
| `tampered_tile_fixture` | Hash/signature/stale cases | Generated fixture | Small |
**Setup procedure**: Load cache fixture and matcher model profile.
**Teardown procedure**: Remove matcher outputs and reports.
**Data isolation strategy**: Read-only imagery with per-run output folders.
@@ -1,92 +0,0 @@
# Tile Manager
## 1. High-Level Overview
**Purpose**: Manage local tiles: service-source COGs, manifests, descriptor metadata, freshness/provenance checks, nadir-image orthorectification into generated tiles, generated tile writes, and post-flight package preparation.
**Architectural Pattern**: Repository + policy gate.
**Upstream dependencies**: Satellite Service cache packages, safety/anchor wrapper, camera ingest/calibration.
**Downstream consumers**: Satellite Service, anchor verification, FDR, post-flight sync.
## 2. Internal Interfaces
### Interface: `TileManager`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `validate_cache` | `CacheValidationRequest` | `CacheValidationReport` | No | `ManifestInvalid`, `SignatureInvalid` |
| `get_tile_window` | `TileWindowRequest` | `TileWindow` | No | `TileUnavailable`, `TileRejected` |
| `orthorectify_frame` | `TileGenerationRequest` | `GeneratedTileCandidate` | Yes | `TileWriteRejected`, `FrameNotUsable` |
| `write_generated_tile` | `GeneratedTileRequest` | `GeneratedTileRecord` | Yes | `TileWriteRejected`, `StorageFull` |
| `package_sync` | `SyncPackageRequest` | `SyncPackage` | Yes | `PackageFailed` |
## 3. Data Access Patterns
| Query | Frequency | Hot Path | Index Needed |
|-------|-----------|----------|--------------|
| Tile by footprint/time/freshness | Per retrieval/anchor | Yes during relocalization | Spatial/time indexes |
| Descriptor metadata by chunk | Per Satellite Service retrieval | Yes during relocalization | Chunk ID index |
| Generated tile by mission/sector | Post-flight | No | Mission ID index |
### Caching Strategy
| Data | Cache Type | TTL | Invalidation |
|------|------------|-----|--------------|
| Manifest metadata | PostgreSQL/PostGIS query cache / process cache | Mission duration | New mission cache load |
| Sidecar verification | In-memory result cache | Mission duration | File hash change |
### Storage Estimates
| Table/Collection | Est. Row Count | Row Size | Total Size | Growth Rate |
|------------------|----------------|----------|------------|-------------|
| Cache manifest tiles | Mission-dependent | Small metadata | Within ~10 GB package with imagery | Per mission |
| Generated tiles | Flight-dependent | Metadata + COG payload | FDR/cache budget constrained | Per flight |
## 4. Implementation Details
**State Management**: Owns PostgreSQL/PostGIS manifest connection, sidecar verification state, and generated tile staging area.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| PostgreSQL + PostGIS | Manifest, spatial metadata, freshness queries, and generated-tile metadata |
| GDAL/rasterio candidate | COG read/write |
| OpenCV/GDAL geometry utilities | Nadir-frame orthorectification into generated COG tiles |
| Cryptographic hash/signature library | Sidecar validation |
**Error Handling Strategy**:
- Invalid signatures/hashes reject tiles.
- Storage-full blocks generated tile writes without affecting localization output.
- Cache validation failure blocks mission cache usage.
## 5. Caveats & Edge Cases
**Known limitations**:
- JSON-only manifests are avoided for scale and queryability, but signed JSON sidecars remain required for audit/interchange.
- PostgreSQL/PostGIS must be available locally before flight; runtime cannot depend on a remote DB link.
**Potential race conditions**:
- Generated tile and PostgreSQL manifest update must be atomic enough to avoid orphan trusted metadata.
## 6. Dependency Graph
**Must be implemented after**: data model schema decisions.
**Can be implemented in parallel with**: camera ingest, MAVLink integration.
**Blocks**: Satellite Service retrieval, anchor verification, generated tile lifecycle.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | Cache package invalid | `cache_manifest_invalid reason=signature` |
| WARN | Tile rejected | `tile_rejected reason=stale tile_id=...` |
| INFO | Generated tile staged | `generated_tile_written tile_id=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment plus cache validation report.
@@ -1,167 +0,0 @@
# Test Specification — Tile Manager
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-4.2 | Memory/storage pressure | PT-01 | Covered |
| AC-8.1 | Resolution at cache interface | IT-01 | Covered |
| AC-8.2 | Freshness thresholds | IT-02, ST-01 | Covered |
| AC-8.3 | Preloaded/preprocessed offline cache | IT-01 | Covered |
| AC-8.4 | Mid-flight tile generation/write-back | IT-03, AT-01 | Covered |
| AC-8.5 | Persistent imagery policy | ST-02 | Covered |
| AC-8.6 | VPR chunk metadata | IT-04 | Covered |
| AC-NEW-3 | FDR/tile storage cap interaction | PT-01 | Covered |
| AC-NEW-6 | Imagery freshness enforcement | IT-02, ST-01 | Covered |
| AC-NEW-7 | Cache-poisoning safety budget | ST-03, AT-01 | Covered |
## Blackbox Tests
### IT-01: Mission Cache Validation
**Summary**: Verify preloaded COGs, PostGIS metadata, sidecars, descriptors, and indexes validate before flight.
**Traces to**: AC-8.1, AC-8.3
**Input data**: Mission cache package with COGs, signed JSON sidecars, PostGIS manifest seed, FAISS index files.
**Expected result**: Valid cache passes resolution, hash, signature, descriptor-reference, and spatial coverage checks.
**Max execution time**: 5 minutes per cache fixture.
---
### IT-02: Freshness Gate
**Summary**: Verify active-conflict and stable-rear freshness rules.
**Traces to**: AC-8.2, AC-NEW-6
**Input data**: Tiles at fresh, grace, and stale ages for both sector classes.
**Expected result**: Fresh tiles pass, grace tiles are down-confidence weighted if allowed, stale tiles are rejected and cannot emit `satellite_anchored`.
**Max execution time**: 2 minutes.
---
### IT-03: Generated Tile Write
**Summary**: Verify nadir frames are orthorectified and written as generated tiles only when pose and frame quality gates pass.
**Traces to**: AC-8.4
**Input data**: Frame metadata, pose covariance <=3 m, <=5 m, and >5 m.
**Expected result**: <=3 m writes full-quality candidate, 3-5 m writes soft candidate, >5 m rejects write.
**Max execution time**: 2 minutes.
---
### IT-04: VPR Chunk Metadata
**Summary**: Verify chunk metadata supports retrieval rules.
**Traces to**: AC-8.6
**Input data**: Operational-area cache manifest.
**Expected result**: Chunks are 600-800 m equivalent footprint with 40-50% overlap and multi-scale active-sector descriptors.
**Max execution time**: 2 minutes.
## Performance Tests
### PT-01: Cache And FDR Storage Budget
**Summary**: Verify cache metadata and generated tile writes stay within storage/memory budgets.
**Traces to**: AC-4.2, AC-NEW-3
**Load scenario**:
- Mission cache: up to operational budget.
- Generated tiles: 8-hour synthetic flight.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Persistent cache | <=10 GB unless split budget approved | >budget without report |
| FDR + generated artifacts | <=64 GB per flight | >64 GB without rollover |
| DB query p95 | <=50 ms for indexed tile lookup | >150 ms |
**Resource limits**: PostgreSQL/PostGIS stays within total system 8 GB memory budget.
## Security Tests
### ST-01: Signed Manifest Enforcement
**Summary**: Verify unsigned/tampered/stale manifests are rejected.
**Traces to**: AC-8.2, AC-NEW-6
**Attack vector**: Tampered sidecar, bad hash, unsigned manifest.
**Test procedure**: Load invalid cache variants and run validation.
**Expected behavior**: Invalid tiles are rejected and logged.
**Pass criteria**: 0 invalid cache entries become available to retrieval/anchor verification.
---
### ST-02: Raw Frame Persistence Check
**Summary**: Verify Tile Manager persists tiles, not raw frames.
**Traces to**: AC-8.5
**Attack vector**: Raw frames accidentally stored as generated artifacts.
**Test procedure**: Run tile generation and inspect cache/FDR outputs.
**Expected behavior**: Only COG tiles, sidecars, manifests, and allowed failed-frame thumbnails exist.
**Pass criteria**: No raw full-resolution frames retained.
---
### ST-03: Cache Poisoning Gate
**Summary**: Verify misaligned generated tiles cannot become trusted basemap.
**Traces to**: AC-NEW-7
**Attack vector**: Over-confident pose writes misaligned generated tile.
**Test procedure**: Inject deflated covariance and wrong pose during tile write.
**Expected behavior**: Tile is rejected or marked candidate/soft; never promoted to trusted by onboard component.
**Pass criteria**: 0 direct trusted basemap promotions onboard.
## Acceptance Tests
### AT-01: Generated Tile Package For Satellite Service
**Summary**: Verify post-flight sync package contains valid generated tiles and metadata.
**Traces to**: AC-8.4, AC-NEW-7
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Orthorectify and write generated candidate tile | COG + sidecar + PostGIS manifest row created |
| 2 | Package post-flight sync | Manifest delta includes trust level and parent covariance |
| 3 | Inspect package | No tile is marked trusted basemap by onboard runtime |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `cache_integrity_fixtures` | Valid/stale/unsigned/hash-mismatched manifests | Generated fixture | Small |
| `mission_cache_fixture` | COGs, descriptors, PostGIS seed | Satellite Service stub | Mission-dependent |
**Setup procedure**: Restore isolated PostgreSQL/PostGIS schema and mount cache fixture read-only except generated-tile staging.
**Teardown procedure**: Drop schema and delete generated staging volume.
**Data isolation strategy**: Per-run mission ID, schema, and staging directory.
@@ -1,69 +0,0 @@
# MAVLink And GCS Integration
## 1. High-Level Overview
**Purpose**: Subscribe to flight-controller telemetry, emit `GPS_INPUT`, and send downsampled QGroundControl status/failsafe messages.
**Architectural Pattern**: Protocol adapter.
**Upstream dependencies**: ArduPilot Plane FC, safety/anchor wrapper.
**Downstream consumers**: VIO adapter, safety/anchor wrapper, QGC, FDR.
## 2. Internal Interfaces
### Interface: `MavlinkGateway`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `subscribe_telemetry` | `TelemetrySubscriptionRequest` | `TelemetrySample` | Yes | `MavlinkDisconnected` |
| `emit_gps_input` | `PositionEstimate` | `EmitResult` | Yes | `MavlinkDisconnected`, `InvalidGpsInput` |
| `emit_status` | `GcsStatusMessage` | `EmitResult` | Yes | `MavlinkDisconnected` |
## 3. Data Access Patterns
No persistent data ownership; telemetry and emitted packets are mirrored to FDR.
## 4. Implementation Details
**State Management**: Maintains MAVLink connection status, source/system IDs, and rate limiters for QGC status.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| MAVSDK | Telemetry subscriptions |
| pymavlink | Exact `GPS_INPUT` field emission |
**Error Handling Strategy**:
- Invalid `GPS_INPUT` fields are rejected before emission.
- Connection loss is surfaced to wrapper/FDR and does not silently drop safety events.
## 5. Caveats & Edge Cases
**Known limitations**:
- v1 emits `GPS_INPUT` only, not velocity-target navigation commands.
- Plane parameter configuration must be validated in SITL before hardware use.
**Performance bottlenecks**:
- Status text must be rate-limited to avoid telemetry noise.
## 6. Dependency Graph
**Must be implemented after**: position estimate DTO and MAVLink output contract.
**Can be implemented in parallel with**: Tile Manager, camera ingest.
**Blocks**: SITL integration and production FC output.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | MAVLink disconnected | `mavlink_disconnected endpoint=...` |
| WARN | Invalid output rejected | `gps_input_invalid reason=...` |
| INFO | FC link established | `mavlink_connected system_id=...` |
**Log format**: FDR structured event.
**Log storage**: FDR segment and optional tlog.
@@ -1,176 +0,0 @@
# Test Specification — MAVLink And GCS Integration
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-4.3 | v1 GPS_INPUT only for ArduPilot Plane | IT-01, AT-01 | Covered |
| AC-4.4 | Frame-by-frame streaming | PT-01 | Covered |
| AC-4.5 | Updated estimates/corrections | IT-02 | Covered |
| AC-5.1 | FC state initialization telemetry | IT-03 | Covered |
| AC-5.2 | Plane SITL fallback | IT-04 | Covered |
| AC-6.1 | QGC status 1-2 Hz | IT-05, PT-02 | Covered |
| AC-6.2 | GCS command ingress | IT-06, ST-01 | Covered |
| AC-6.3 | WGS84 output | IT-01 | Covered |
| AC-NEW-2 | Spoofing promotion <3 s | IT-04 | Covered |
| AC-NEW-8 | Blackout/failsafe status | IT-05 | Covered |
## Blackbox Tests
### IT-01: GPS_INPUT Field Mapping
**Summary**: Verify `PositionEstimate` maps to valid MAVLink `GPS_INPUT`.
**Traces to**: AC-4.3, AC-6.3
**Input data**: Position estimates across all source labels.
**Expected result**: v1 emits `GPS_INPUT` only, no `ODOMETRY`; WGS84 lat/lon/alt, fix type, ignore flags, and accuracy fields match contract.
**Max execution time**: 2 minutes.
---
### IT-02: Correction Emission
**Summary**: Verify updated estimates can be emitted without batching.
**Traces to**: AC-4.5
**Input data**: Original VO estimate followed by anchor-corrected estimate.
**Expected result**: Both estimates are emitted in order with updated accuracy/source label.
**Max execution time**: 2 minutes.
---
### IT-03: FC Telemetry Subscription
**Summary**: Verify telemetry needed for initialization and VIO is available.
**Traces to**: AC-5.1
**Input data**: Plane SITL or MAVLink replay with EKF position, IMU, attitude, airspeed, altitude.
**Expected result**: Normalized `TelemetrySample` stream includes required fields and timestamps.
**Max execution time**: 5 minutes.
---
### IT-04: Spoofing And Fallback In Plane SITL
**Summary**: Verify spoofing and no-estimate behavior in ArduPilot Plane SITL.
**Traces to**: AC-5.2, AC-NEW-2
**Input data**: Plane SITL production parameter set and spoofing trace.
**Expected result**: Own estimate promotion occurs within <3 s; fallback/no-estimate behavior matches Plane parameters.
**Max execution time**: 10 minutes.
---
### IT-05: QGC Blackout Status
**Summary**: Verify degraded-mode messages are visible at required rate.
**Traces to**: AC-6.1, AC-NEW-8
**Input data**: Safety wrapper emits blackout and failsafe statuses.
**Expected result**: QGC observer sees `VISUAL_BLACKOUT_IMU_ONLY` at 1-2 Hz and `VISUAL_BLACKOUT_FAILSAFE` at threshold.
**Max execution time**: 10 minutes.
---
### IT-06: Operator Relocalization Hint
**Summary**: Verify GCS command ingress can carry approximate relocalization hints.
**Traces to**: AC-6.2
**Input data**: STATUSTEXT/NAMED_VALUE_FLOAT/custom dialect hint fixture.
**Expected result**: Valid hint is parsed and forwarded to retrieval/safety logic; invalid hint is rejected.
**Max execution time**: 5 minutes.
## Performance Tests
### PT-01: Frame-Rate Emission
**Summary**: Verify output is streamed frame-by-frame and not batched.
**Traces to**: AC-4.4
**Load scenario**:
- Input estimate rate: target frame rate.
- Duration: 30 minutes.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Output delay p95 | <=25 ms after wrapper output | >100 ms |
| Missing messages | 0 except upstream dropped frames | Any silent drop |
---
### PT-02: QGC Status Rate Limit
**Summary**: Verify QGC status is downsampled without losing critical transitions.
**Traces to**: AC-6.1
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Status rate | 1-2 Hz while active | <1 Hz or >2 Hz sustained |
| Critical transition delay | <=1 s | >2 s |
## Security Tests
### ST-01: MAVLink Source And Command Validation
**Summary**: Verify unauthorized or malformed MAVLink messages are rejected.
**Traces to**: AC-6.2
**Attack vector**: Malicious source sends spoofed command or GPS data.
**Test procedure**:
1. Send valid command from allowed source.
2. Send same command from disallowed source/system ID.
3. Send malformed values.
**Expected behavior**: Allowed command is accepted; disallowed/malformed messages are rejected and logged.
**Pass criteria**: 0 unauthorized commands affect localization state.
## Acceptance Tests
### AT-01: Plane SITL Output Acceptance
**Summary**: Verify ArduPilot Plane receives and uses v1 `GPS_INPUT` as configured.
**Traces to**: AC-4.3
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Start Plane SITL with production params | FC accepts external GPS substitute config |
| 2 | Emit `GPS_INPUT` estimate | Message is received with expected fields |
| 3 | Observe wire | `ODOMETRY` is absent in v1 |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `sitl_spoofing_scenarios` | GPS loss/spoofing traces | Generated SITL | Small |
| `mavlink_output_fixtures` | PositionEstimate cases | Generated fixture | Small |
**Setup procedure**: Start SITL/QGC observer or replay MAVLink log.
**Teardown procedure**: Stop processes and archive tlogs.
**Data isolation strategy**: Unique MAVLink ports and run IDs per test.
@@ -1,79 +0,0 @@
# FDR And Observability
## 1. High-Level Overview
**Purpose**: Record bounded, replayable mission evidence and expose runtime health/status events for analysis and operator awareness.
**Architectural Pattern**: Append-only event sink + exporter.
**Upstream dependencies**: All runtime components.
**Downstream consumers**: Validation harness, post-flight audit tools, QGC status through MAVLink component.
## 2. Internal Interfaces
### Interface: `FlightRecorder`
| Method | Input | Output | Async | Error Types |
|--------|-------|--------|-------|-------------|
| `append_event` | `FdrEvent` | `AppendResult` | Yes | `RecorderUnavailable`, `StorageFull` |
| `rollover` | `RolloverRequest` | `FdrSegmentInfo` | No | `RolloverFailed` |
| `export` | `ExportRequest` | `ExportResult` | Yes | `ExportFailed` |
## 3. Data Access Patterns
| Query | Frequency | Hot Path | Index Needed |
|-------|-----------|----------|--------------|
| Append event | High | Yes | Append index only |
| Export by time/type | Post-flight | No | Time/type index |
### Storage Estimates
| Table/Collection | Est. Row Count | Row Size | Total Size | Growth Rate |
|------------------|----------------|----------|------------|-------------|
| FDR events | Flight-dependent | Mixed | <=64 GB per 8 h | Per flight |
## 4. Implementation Details
**State Management**: Owns active segment, rollover policy, and export state.
**Key Dependencies**:
| Library | Purpose |
|---------|---------|
| PostgreSQL client | Event metadata, time/type indexes, mission query surface |
| CBOR writer | Bounded runtime payload segments |
| Parquet writer | Optional post-flight export |
**Error Handling Strategy**:
- Storage-full emits critical status and starts rollover/retention behavior.
- Append failures are surfaced to the caller and health system.
## 5. Caveats & Edge Cases
**Known limitations**:
- Raw frames are not retained by default; only metadata, decisions, hashes, and occlusion/blackout status are recorded.
- PostgreSQL availability is required for indexed FDR metadata; CBOR payload segments preserve bounded append behavior for high-volume data.
**Performance bottlenecks**:
- FDR appends must not block hot-path localization.
## 6. Dependency Graph
**Must be implemented after**: event schema and key DTOs.
**Can be implemented in parallel with**: MAVLink integration.
**Blocks**: release evidence and most validation reports.
## 7. Logging Strategy
| Log Level | When | Example |
|-----------|------|---------|
| ERROR | Recorder unavailable | `fdr_unavailable path=...` |
| WARN | Rollover occurs | `fdr_rollover segment=...` |
| INFO | Export complete | `fdr_export_complete format=parquet` |
**Log format**: FDR event metadata plus local health logs.
**Log storage**: PostgreSQL FDR event tables plus CBOR segment payloads.
@@ -1,166 +0,0 @@
# Test Specification — FDR And Observability
## Acceptance Criteria Traceability
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|-------|---------------------|----------|----------|
| AC-1.3 | Anchor age/drift evidence | IT-01 | Covered |
| AC-1.4 | Confidence/source label retained | IT-01 | Covered |
| AC-4.4 | Per-frame local stream evidence | IT-01, PT-01 | Covered |
| AC-5.2 | Failure logging | IT-02 | Covered |
| AC-6.1 | QGC/status evidence | IT-03 | Covered |
| AC-8.4 | Generated tile audit | IT-04 | Covered |
| AC-8.5 | No raw frame retention | ST-01 | Covered |
| AC-NEW-3 | FDR retention and 64 GB cap | PT-01, AT-01 | Covered |
| AC-NEW-4 | False-position forensics | IT-05 | Covered |
| AC-NEW-5 | Thermal/throttle logging | IT-06 | Covered |
| AC-NEW-8 | Blackout/failsafe logging | IT-02, IT-03 | Covered |
## Blackbox Tests
### IT-01: Per-Estimate Event Capture
**Summary**: Verify every estimate stores covariance, source label, anchor age, and emitted output metadata.
**Traces to**: AC-1.3, AC-1.4, AC-4.4
**Input data**: Position estimate stream with satellite, VO, and dead-reckoned labels.
**Expected result**: PostgreSQL event index and CBOR payload segments contain all required fields with monotonic timestamps.
**Max execution time**: 5 minutes.
---
### IT-02: Failure And Blackout Logging
**Summary**: Verify no-estimate and blackout transitions are recorded.
**Traces to**: AC-5.2, AC-NEW-8
**Input data**: No-estimate gap and total blackout sequence.
**Expected result**: FDR records start, every degraded estimate, failsafe threshold, and recovery reason.
**Max execution time**: 10 minutes.
---
### IT-03: QGC Status Audit
**Summary**: Verify operator-visible status has matching FDR evidence.
**Traces to**: AC-6.1, AC-NEW-8
**Input data**: QGC status messages from MAVLink component.
**Expected result**: FDR contains status text, timestamp, and mode context.
**Max execution time**: 5 minutes.
---
### IT-04: Generated Tile Audit Trail
**Summary**: Verify tile-write decisions are recorded with parent covariance and trust level.
**Traces to**: AC-8.4
**Input data**: Accepted and rejected generated tile write decisions.
**Expected result**: FDR includes tile ID, parent covariance, trust level, sidecar hash, and rejection reason where applicable.
**Max execution time**: 5 minutes.
---
### IT-05: False-Position Investigation Bundle
**Summary**: Verify enough evidence exists to investigate a false-position event.
**Traces to**: AC-NEW-4
**Input data**: Simulated false anchor rejection and covariance growth sequence.
**Expected result**: Export includes estimates, anchor decisions, residuals, covariance, and emitted MAVLink fields.
**Max execution time**: 5 minutes.
---
### IT-06: Thermal/Throttle Event Capture
**Summary**: Verify resource health events are recorded.
**Traces to**: AC-NEW-5
**Input data**: Synthetic thermal/throttle metric stream.
**Expected result**: FDR records CPU/GPU/temp/throttle status and QGC warning trigger.
**Max execution time**: 5 minutes.
## Performance Tests
### PT-01: 8-Hour FDR Load
**Summary**: Verify FDR storage and append behavior under full mission load.
**Traces to**: AC-4.4, AC-NEW-3
**Load scenario**:
- Duration: 8 hours synthetic.
- Inputs: 3 Hz estimates, full-rate IMU, MAVLink tlog, health metrics, tile events.
| Metric | Target | Failure Threshold |
|--------|--------|-------------------|
| Total FDR size | <=64 GB | >64 GB without rollover |
| Append latency p95 | <=10 ms async enqueue | >25 ms |
| Silent payload loss | 0 | Any unlogged loss |
**Resource limits**: FDR must not block hot-path localization.
## Security Tests
### ST-01: Raw Frame Retention Audit
**Summary**: Verify FDR does not store raw full-resolution frames.
**Traces to**: AC-8.5
**Attack vector**: Debug logging accidentally persists raw camera frames.
**Test procedure**:
1. Run normal replay and failed tile-generation replay.
2. Inspect FDR payloads and output directories.
**Expected behavior**: Only metadata, hashes, estimates, tiles, and allowed low-rate failed-frame thumbnails are retained.
**Pass criteria**: No raw nav/AI camera frame payloads in normal FDR.
## Acceptance Tests
### AT-01: FDR Export
**Summary**: Verify post-flight export creates usable audit artifacts.
**Traces to**: AC-NEW-3
| Step | Action | Expected Result |
|------|--------|-----------------|
| 1 | Complete synthetic flight | Segment rollover is logged and cap respected |
| 2 | Export FDR summary | Markdown/CSV/Parquet optional artifacts are produced |
| 3 | Query PostgreSQL index | Events can be filtered by time/type/mission |
## Test Data Management
| Data Set | Description | Source | Size |
|----------|-------------|--------|------|
| `fdr_synthetic_load` | Estimate, IMU, MAVLink, health, tile events | Generated fixture | Large |
| `incident_fixture` | False-position and blackout evidence | Generated fixture | Small |
**Setup procedure**: Create isolated PostgreSQL schema and FDR segment directory.
**Teardown procedure**: Export report, then remove schema and segment directory.
**Data isolation strategy**: Per-run mission ID, schema, and FDR directory.