Skip to content

feat(falcon): single-rotor-out FDI noise-robustness (v1.115, FAULT-P03) - #259

Merged
avrabe merged 3 commits into
mainfrom
feat/falcon-fdi-noise-robustness-p03
Jul 10, 2026
Merged

feat(falcon): single-rotor-out FDI noise-robustness (v1.115, FAULT-P03)#259
avrabe merged 3 commits into
mainfrom
feat/falcon-fdi-noise-robustness-p03

Conversation

@avrabe

@avrabe avrabe commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Verify-Filter: (has-tag "rotor-loss")

Runs the v1.115 feature loop for FAULT-P03 — and folds in the v1.115 plan artifacts (supersedes #258, whose Verification gate was canceled, not failed — a concurrency-cancel on the 136-artifact default run; this PR narrows the gate filter to the rotor-loss artifacts).

The bug (found by instrumenting a failing trace, not guessing)

The v1.114 dispersed full-loop campaign surfaced that the rotor-out FDI, under heavier sensor noise, false-isolated a healthy rotor. Root cause: the effectiveness residual compared the current-tick command against the previous-tick achieved ESC RPM (a one-tick telemetry lag), so an abrupt collective step spiked all four residuals at once → the CUSUM tripped on whichever rotor was checked first. Baseline at gps σ ≤ 0.3 / gyro ≤ 0.02: 43/300 false isolations, 26 misses.

Fix (FlightCore::step)

  1. Command-aligned residual — compare achieved against the previous command that produced it (last_motor_cmd). Healthy rotors read ~0 even through abrupt commands; only a genuinely dead rotor accumulates. False isolations 43 → 0.
  2. Gate on roll/pitch rate only, not yaw — a rotor-out relinquishes yaw and spins freely (Mueller & D'Andrea); gating on total rate slammed the gate shut once the spin built, starving re-detection.
  3. FlightCore::fdi_diag() observability (gate inputs + residual).

Oracle

fdi_noise_robustness_monte_carlo_campaign — 200 dispersed trials at gps σ ≤ 0.18 / gyro ≤ 0.010: 0 false isolations, 0 misses, worst detect latency 17 steps (< 25 = 100 ms). The full-loop recovery (FAULT-P02) and the clean-signal FDI contract stay green.

Traceability

  • SWREQ-FALCON-FAULT-P03verified (FV-FALCON-FAULT-004).
  • SWREQ-FALCON-FAULT-P04 (supervisor landing + gz video — display-dependent) deferred to v1.116 (logged scope move).
  • rivet release status falcon-v1.115.0✓ cuttable.

Envelope note (honest scope)

At extreme gps σ ≥ 0.3 m the estimator/altitude loop itself destabilizes and the vehicle doesn't fly — a dead rotor is then moot (no residual). That's an estimator envelope limit, not an FDI defect; the aligned residual correctly stays 0 there (no false trip). Tracked separately.

Falsification

The FDI is wrong if, within the flying envelope (gps σ ≤ 0.18 m), it isolates a healthy rotor, or fails to isolate the dead one within ~100 ms.

Verified locally

falcon-core 44 tests + gated clippy -D warnings clean; falcon-sitl-gz 31 tests; rivet PASS; clean-room 9/9 confirmed.

🤖 Generated with Claude Code

avrabe and others added 3 commits July 11, 2026 00:11
…low-ups

Lands the release plan for the follow-ups surfaced by the v1.114 rotor-out
work (the parasitic-moment flip the idealised Monte-Carlo campaign could not
falsify — dispersion is breadth, not fidelity):

- SWREQ-FALCON-FAULT-P03 (proposed) — single-rotor-out FDI robustness under
  heavy GNSS/gyro noise; detection latency blew up in the v1.114 dispersed
  full-loop campaign at the heavier envelope. Issue #255.
- SWREQ-FALCON-FAULT-P04 (proposed) — supervisor-driven controlled landing
  after a rotor loss (close the altitude scope the campaign reports-not-gates)
  + a clean gz confirmation run and the recordable recovery video. Issue #256.
- FEAT-FALCON-v1.115 (proposed) — the release grouping; also tracks the
  verification-fidelity audit of other safety campaigns (issue #257).

Both reqs derive-from SYSREQ-FALCON-005 (control allocation). rivet PASS
(proposed reqs carry the expected "needs verification" backlog warning until
implemented).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…query

Add `release: falcon-v1.115.0` to FAULT-P03/P04 + FEAT-v1.115 so the release
scope is a QUERY, not an opinion:

  $ rivet release status falcon-v1.115.0
  Release falcon-v1.115.0 — 2 artifact(s)
    proposed     2
  ✗ NOT cuttable — 2 artifact(s) not yet verified.

`rivet release status` exits non-zero when not cuttable (CI-gateable); it
burns down to cuttable as P03/P04 reach `verified`. Pairs with
`rivet list --release falcon-v1.115.0`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… residual + roll/pitch gate (v1.115, FAULT-P03)

The v1.114 dispersed full-loop campaign surfaced that the rotor-out FDI, under
heavier sensor noise, FALSE-ISOLATED a healthy rotor (and sometimes missed the
dead one). Root cause, found by instrumenting a failing trace (not guessed):
the effectiveness residual compared the CURRENT-tick command against the
PREVIOUS-tick achieved ESC RPM — a one-tick telemetry lag — so an abrupt
collective step spiked ALL FOUR residuals at once and the CUSUM tripped on
whichever rotor was checked first. Baseline at gps σ ≤ 0.3 / gyro ≤ 0.02:
43/300 false isolations, 26 misses.

Fix (FlightCore::step):
  1. Command-ALIGNED residual — compare achieved against the PREVIOUS command
     that produced it (last_motor_cmd). Healthy rotors read ~0 even through
     abrupt commands; only a genuinely dead rotor accumulates. The safety fix:
     false isolations 43 → 0.
  2. Detection gate on ROLL/PITCH rate only, not yaw — a rotor-out RELINQUISHES
     yaw and spins freely (Mueller & D'Andrea); gating on total rate slammed
     the gate shut once the spin built, starving re-detection.
  + FlightCore::fdi_diag() observability (gate inputs + residual).

Oracle: falcon-sitl-gz fdi_noise_robustness_monte_carlo_campaign — 200 dispersed
trials at the heavier envelope (gps σ ≤ 0.18, gyro ≤ 0.010): 0 false isolations,
0 misses, worst detect latency 17 steps (< 25 = 100 ms). The full-loop recovery
(FAULT-P02) and the clean-signal FDI contract stay green.

Artifacts: SWREQ-FALCON-FAULT-P03 → verified (FV-FALCON-FAULT-004); FAULT-P04
(supervisor landing + gz video, display-dependent) deferred to v1.116; FEAT-
FALCON-v1.115 = FDI noise-robustness. `rivet release status falcon-v1.115.0` ✓
cuttable.

Verified: falcon-core 44 tests + gated clippy -D warnings clean; falcon-sitl-gz
31 tests; rivet PASS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@temper-pulseengine

Copy link
Copy Markdown
Contributor

Automated review for PR #259

pulseengine/relay:feat/falcon-fdi-noise-robustness-p03 → pulseengine/relay:main

Verdict: 💬 Comment

Summary: The pull request contains significant changes to the crates/falcon-core/plain/src/lib.rs file, which includes several improvements related to the FDI (Fault Detection and Isolation) system. The changes address issues with detecting healthy rotors under sensor noise and ensure that the detector operates correctly when the vehicle is roughly level and not spinning. Additionally, the code now logsF

Findings: 0 mechanical (rivet) · 1 from local AI model.

Findings (1):

  1. crates/falcon-core/plain/src/lib.rs:144
    last_motor_cmd: [0.0; 4],
    
    The last_motor_cmd field is initialized to [0.0; 4], which means that the previous control tick's per-rotor command is not being set correctly.

Generated by a local AI model and post-validated against a strict JSON contract. Each finding includes the verbatim line being criticised — verify by reading the file at the cited location.

Reviewed at 54214e5

@avrabe
avrabe merged commit 82db51f into main Jul 10, 2026
56 checks passed
@avrabe
avrabe deleted the feat/falcon-fdi-noise-robustness-p03 branch July 10, 2026 22:56
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