Skip to content

feat(falcon): v1.121 — dual-M9N GNSS blend/failover + TF02 terrain-relative landing - #280

Merged
avrabe merged 1 commit into
mainfrom
feat/falcon-v1121-gnss-range
Jul 16, 2026
Merged

feat(falcon): v1.121 — dual-M9N GNSS blend/failover + TF02 terrain-relative landing#280
avrabe merged 1 commit into
mainfrom
feat/falcon-v1121-gnss-range

Conversation

@avrabe

@avrabe avrabe commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Verify-Filter: (has-tag "v1.121")

Implements GNSS-P02 + RANGEDRV-P01 (→ implemented; verify PR follows per the two-commit rule) — the two remaining hardware-register slices for the first vehicle's sensor complement (2× M9N, TF02-Pro). Both built by first un-orphaning verified leaves: relay-iekf::SpoofMonitor and relay_flowrange::range_to_altitude were verified but wired nowhere.

GNSS-P02 — dual-receiver selection (falcon-gnss-ubx/src/dual.rs)

  • Per-receiver health gate: fix type, sats ≥ 6, accuracy ceiling and floor, innovation gate vs the estimator (a jump is disqualified the same cycle).
  • Inverse-variance blend when both healthy; failover within one fix interval; sqrt-free decision path (squared gates).
  • Debounced, latched divergence flag → feeds nav_compromised() (with the now-wired SpoofMonitor CUSUM) → blocks pre-arm.
  • Kani GNSS-K05 (selector totality over all inputs, incl. NaN/∞) caught a real NaN: a denormal reported accuracy overflowed the 1/acc² blend weight into ∞−∞. Fixed with the accuracy floor + position sanity bound; the harness now proves the no-NaN claim outright.

RANGEDRV-P01 — TF02-Pro decode + terrain-relative landing (relay-flowrange/plain/src/tf02.rs)

  • 9-byte Benewake frame decode cross-validated against two independent parsers (ArduPilot AP_RangeFinder_Benewake, PX4 tfmini_parser — semantics quoted in the module doc; the external-reference rule). Strength/envelope quality gate lives in the decoder; streaming resync scanner.
  • Kani FLOWRANGE-K03/K04 — K03 caught 10 × 0.01f32 = 0.099999994 escaping the 0.1 m envelope bound; fixed by dividing (correctly-rounded quotient ⇒ exact bounds).
  • Landing integration is terrain-relative AGL, not z-state fusion (three absolute references — biased GNSS-z, biased baro, true range — would fight and settle metres off; the PX4 terrain-estimator role instead). Innovation-gated: an obstacle overflight's short return is rejected and can never fold the touchdown logic.

Oracles (falcon-core, +5 tests, 54/54)

  • Failover holds the estimate (< 1 m step, zero resets).
  • Divergence latches, blocks arming, estimate stays with the consistent receiver.
  • 40-trial LCG dispersion campaign (dropout / accuracy-collapse / divergence-walk / nominal): flag in 100% of walk trials, zero false flags, no discontinuous estimate steps.
  • Biased-vertical landing: baro and GNSS-z lying 2 m high (SimBackend now models receiver bias — zero-mean noise can't model the real failure) → touchdown within 15 cm of true ground with range assist, and provably not clean without (negative control kept).
  • Obstacle short-return rejected; altitude estimate unfolded.

Gate hygiene

Gates

cargo test: falcon-core 54 + flowrange 14 + gnss-ubx 12, 0 fail · cargo kani: flowrange 4/4, gnss-ubx 2/2 · clippy -D warnings clean on all four crates · rivet validate PASS.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HvusAXYbHLyv3uTzfBcMbG

…lative landing (GNSS-P02 + RANGEDRV-P01)

Two hardware-register slices for the first vehicle, both built by first
UN-ORPHANING verified leaves (the recurring pattern):

GNSS-P02 — falcon-gnss-ubx dual.rs: per-receiver health gating (fix,
sats, accuracy ceiling+floor, innovation gate vs the estimator),
inverse-variance blending, failover within one fix interval, and a
debounced LATCHED divergence flag. Sqrt-free decision path (squared
gates). Kani GNSS-K05 proved selector totality over ALL inputs — and
caught a real NaN: a denormal reported accuracy overflowed the 1/acc²
blend weight into ∞−∞ (fixed with accuracy floor + position sanity
bound). FlightCore runs the selector when the backend has two lanes
(read_gnss_dual seam, default None); the previously-ORPHANED
relay-iekf SpoofMonitor is now fed the position innovation, and
nav_compromised() (spoof ∨ divergence) blocks pre-arm.

RANGEDRV-P01 — relay-flowrange tf02.rs: Benewake TF02-Pro 9-byte frame
decode cross-validated against TWO independent parsers (ArduPilot
AP_RangeFinder_Benewake + PX4 tfmini_parser semantics quoted in the
module doc), strength/envelope quality gate IN the decoder, streaming
resync scanner. Kani FLOWRANGE-K03/K04 (decode totality + gate
soundness over all 9-byte patterns; scanner totality) — K03 caught
10 × 0.01f32 = 0.099999994 escaping the envelope (fixed: divide, the
correctly-rounded quotient makes the bounds exact). The previously-
ORPHANED range_to_altitude is now the LANDING-PHASE altitude
reference: terrain-relative AGL (the PX4 terrain-estimator role, NOT
z-state fusion — three absolute references would fight), innovation-
gated so an obstacle overflight can never fold the touchdown logic.

Oracles (falcon-core, +5 tests): failover holds the estimate (<1 m
step, no reset); divergence latches + blocks arming + estimate stays
with the consistent receiver; 40-trial LCG dispersion campaign (drop /
accuracy-collapse / divergence-walk / nominal — flag in 100% of walk
trials, 0 false flags, no estimate steps); biased-vertical landing
(baro AND GNSS-z lying 2 m high — the sim now models receiver BIAS,
which zero-mean noise cannot) touches down within 15 cm of TRUE ground
with range assist and provably NOT without; obstacle short-return
rejected by the gate, altitude estimate unfolded.

Also: CI clippy gate extended with relay-batt, relay-flowrange,
falcon-gnss-ubx (they were outside the linted crate list); a
pre-existing match-destructure lint in relay-flowrange fixed;
LoggingBackend forwards the two new backend reads (the v1.120
wrapper-default lesson; raw-lane logging = schema-v2, #277).

SWREQ-FALCON-GNSS-P02 + SWREQ-FALCON-RANGEDRV-P01 → implemented (the
verify PR follows per the two-commit rule).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvusAXYbHLyv3uTzfBcMbG
@avrabe
avrabe merged commit aece1cf into main Jul 16, 2026
58 checks passed
@avrabe
avrabe deleted the feat/falcon-v1121-gnss-range branch July 16, 2026 02:54
avrabe added a commit that referenced this pull request Jul 16, 2026
…TF02-Pro (#281)

Code-free promotion per the two-commit rule. Evidence on merged main
(aece1cf, impl PR #280 merged at 58/58 green), plus a FULL clean-room
pass: 12 falsifiable claims verified cold, 12/12 CONFIRMED — including
an independent re-fetch of both external parsers (ArduPilot
AP_RangeFinder_Benewake, PX4 tfmini_parser) to validate the TF02 frame
layout without trusting the module's own doc.

New FV-FALCON-GNSS-002 + FV-FALCON-RANGEDRV-001 (ids grepped free).
SWREQ-FALCON-GNSS-P02 + SWREQ-FALCON-RANGEDRV-P01: implemented → verified.


Claude-Session: https://claude.ai/code/session_01HvusAXYbHLyv3uTzfBcMbG

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant