mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-23 03:01:12 +00:00
[AZ-385] C5 SourceLabelStateMachine + spoof-promotion gate
Implements Invariants 5 + 8 + AC-NEW-2 / AC-NEW-8: the EstimatorOutput.source_label now reflects a real state machine (DEAD_RECKONED → SATELLITE_ANCHORED ↔ VISUAL_PROPAGATED) governed by a spoof-promotion gate that latches closed on FC SPOOFED GPS health and re-opens only when BOTH conditions hold — ≥10 s STABLE_NON_SPOOFED AND next anchor within spoof_promotion_visual_consistency_tol_m. Every reject emits a c5.state.spoof_rejected FDR record plus a subscriber-fan-out STATUSTEXT (severity WARNING, 50-char cap per MAVLink). FDR and subscriber paths bypass the standard logger so silencing logs cannot suppress the spoof trail (R07 / AC-6). GtsamIsam2StateEstimator now eagerly builds the SM from C5StateConfig in __init__; new public methods notify_gps_health() (delegates to SM, called by composition root from C8 inbound) and subscribe_spoof_rejection() (composition root attaches C8's QgcTelemetryAdapter here). health_snapshot.spoof_promotion_blocked + current_estimate.source_label now flow from the live SM. 25 new unit tests across all 12 ACs plus cancellation, subscriber exception isolation, and estimator wire-up integration cases. One AZ-384 test renamed + updated to expect DEAD_RECKONED before any anchor (was VISUAL_PROPAGATED placeholder pre-AZ-385). Full suite: 632 passed, 2 skipped. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -412,13 +412,16 @@ def test_ac9_state_machine_drives_source_label() -> None:
|
||||
assert out.source_label == PoseSourceLabel.SATELLITE_ANCHORED
|
||||
|
||||
|
||||
def test_ac9_default_source_label_is_visual_propagated() -> None:
|
||||
def test_ac9_default_source_label_is_dead_reckoned_before_any_anchor() -> None:
|
||||
# AZ-385 superseded the AZ-384 default: the auto-constructed
|
||||
# SourceLabelStateMachine returns DEAD_RECKONED until the first
|
||||
# satellite anchor is observed (AC-1 of AZ-385 + Invariant 5).
|
||||
estimator = _build_estimator()
|
||||
_seed_prior(estimator)
|
||||
|
||||
out = estimator.current_estimate()
|
||||
|
||||
assert out.source_label == PoseSourceLabel.VISUAL_PROPAGATED
|
||||
assert out.source_label == PoseSourceLabel.DEAD_RECKONED
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user