feat(failsafe): v1.101 — high-wind failsafe (sustained control saturation → RTL)#240
Merged
Merged
Conversation
…tion → RTL) The second PX4-parity expanded failsafe (gap-analysis #5): a wind disturbance beyond the rate loop's authority commands RTL. When the control allocation is SATURATED while the vehicle leans hard (but is NOT tumbling), it is at its limit and losing station — RTL home before it loses the fight. - FlightCore::max_motor(): the largest last commanded motor output (0..1) — the saturation signal. - FlightSupervisor: a debounced detector — airborne && max_motor >= WIND_SAT_ THRESHOLD (0.95) && tilt in [WIND_TILT_MIN, WIND_TILT_CEIL] (0.30..0.70 rad) for WIND_CYCLES (~0.5 s) → Event::Failsafe (the existing → Rtl/Land path; no new FSM state, no new invariant). The tilt band is capped BELOW TILT_RUNAWAY_LIMIT and the count RESETS above the ceiling, so a developing TUMBLE (measured to cross the band in ~47 cycles, far under the debounce) TERMINATES instead — the attitude-runaway path strictly dominates. Saturation alone (a level climb) is not high wind; saturation WHILE moderately tilted is. Tests: high_wind_saturation_commands_rtl — level airborne does NOT trip it; a sustained ~28° tilt with motors pinned fires the RTL-class failsafe (rtl_latched, Takeoff → Rtl/Land recovery) and does NOT terminate. attitude_runaway_terminates_ in_flight still reaches Terminated (the discrimination holds — the wind detector does not pre-empt a tumble). 39 falcon-core tests green. Distinct from SWREQ-FALCON-WIND-P01 (the position-loop integral that REJECTS in-authority wind); this is the failsafe for wind BEYOND authority. rivet: SWREQ-FALCON-WINDFS-P01 + FV-FALCON-WINDFS-001 (derives-from SYSREQ-011); FEAT-FALCON-v1.99 high-wind → DONE (only motor-failure reallocation remains). validate PASS, 0 error-gaps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…range lint Clean-room caught that falcon-hello does NOT depend on falcon-core, so the CI Clippy gate never actually covered falcon-core — where the v1.97–v1.101 flight-code changes live. Add falcon-core to the gate (it is clippy-clean under -D warnings) so this class of issue is caught in CI, not just locally. Doing so surfaced a real lint the gate would have missed: the high-wind detector's `tilt >= WIND_TILT_MIN && tilt <= WIND_TILT_CEIL` → `(MIN..=CEIL).contains(&tilt)` (manual RangeInclusive::contains). Behaviour-identical; the wind test still passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The second PX4-parity expanded failsafe (gap-analysis #5): wind beyond the rate loop's authority commands RTL. When the control allocation is saturated while the vehicle leans hard (but is not tumbling), it's at its limit and losing station → RTL home before it loses the fight.
FlightCore::max_motor()— the largest last commanded motor output (the saturation signal).FlightSupervisor— a debounced detector: airborne &&max_motor ≥ 0.95&& tilt in[0.30, 0.70] radfor ~0.5 s →Event::Failsafe(the existing → Rtl/Land path; no new FSM state or invariant). The tilt band is capped belowTILT_RUNAWAY_LIMITand the count resets above the ceiling, so a developing tumble (measured to cross the band in ~47 cycles, far under the debounce) terminates instead — the attitude-runaway path strictly dominates. Saturation alone (a level climb) isn't high wind; saturation while tilted is.Verification
high_wind_saturation_commands_rtl: level airborne does NOT trip it; a sustained ~28° tilt with motors pinned fires the RTL-class failsafe (rtl_latched, Takeoff → Rtl/Land recovery) and does NOT terminate.attitude_runaway_terminates_in_flightstill reaches Terminated — the wind detector does not pre-empt a real tumble (the discrimination holds). 39 falcon-core tests green.Distinct from
SWREQ-FALCON-WIND-P01(the position-loop integral that rejects in-authority wind); this is the failsafe for wind beyond authority.Traceability
SWREQ-FALCON-WINDFS-P01 → FV-FALCON-WINDFS-001 (derives-from SYSREQ-011); FEAT-FALCON-v1.99 high-wind → DONE.
rivet validatePASS, 0 error-gaps.Scope
This is the second of three FEAT-v1.99 failsafes. Only motor-failure → reallocation remains (multi-subsystem: ESC health voting + the attitude controller's yaw-authority gate +
mix_rotor_out— deferred).🤖 Generated with Claude Code