feat(commander): uncommanded altitude loss detection with parachute f…#26837
feat(commander): uncommanded altitude loss detection with parachute f…#26837
Conversation
e340af4 to
91a4720
Compare
🔎 FLASH Analysispx4_fmu-v5x [Total VM Diff: 752 byte (0.04 %)]px4_fmu-v6x [Total VM Diff: 744 byte (0.04 %)]Updated: 2026-03-30T09:38:55 |
8fea79c to
68e47df
Compare
bresch
left a comment
There was a problem hiding this comment.
Did you check if this also doesn't trigger when the EKF does an altitude reset?
| bool fd_esc_arming_failure # ESC failed to arm | ||
| bool fd_imbalanced_prop # Imbalanced propeller detected | ||
| bool fd_motor_failure # Motor failure | ||
| bool fd_alt_loss # Uncommanded altitude loss (rotary-wing, altitude-controlled flight) |
There was a problem hiding this comment.
why only rotary-wing and not on all platforms?
There was a problem hiding this comment.
The vtol in fw mode has this already, but if you think it can be useful for all fw to have it then I can unify the detection logic and we have one check for all vehicles
There was a problem hiding this comment.
The altitude reset guard is not there yet for the detection in rotary wing vehicles, once we decide to unify or not I'll add it
|
Could you maybe take the opportunity to add a unit test for this? |
…ailsafe Detects when a rotary-wing vehicle drops more than FD_ALT_LOSS metres below a NED-z reference while altitude control is active, and immediately triggers flight termination (parachute deployment). Detection (FailureDetector): - FD_ALT_LOSS: drop threshold in metres (0 = disabled, default) - FD_ALT_LOSS_T: hysteresis time - Guards: rotary-wing only, altitude control active, z_valid, setpoint fresh (<1 s). Manual, Acro and FW/VTOL-FW modes are excluded. - Ratcheting reference: initialises to lpos.z on first sample below setpoint, preventing false triggers on new waypoints Failsafe action (commander): - New fd_alt_loss flag in FailsafeFlags.msg - COM_ALT_LOSS_ACT: -1=Disabled (default), 0=Terminate - Terminate fires immediately, cannot be overridden, and never clears until disarm (parachute deployment is irreversible)
68e47df to
8542f09
Compare
| uORB::Publication<vehicle_local_position_setpoint_s> _lpos_sp_pub{ORB_ID(vehicle_local_position_setpoint)}; | ||
| }; | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, no_trigger_when_disabled) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "no_trigger_when_disabled" according to Googletest FAQ
| EXPECT_FALSE(update(-90.f, -100.f)); | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, no_trigger_above_setpoint) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "no_trigger_above_setpoint" according to Googletest FAQ
| EXPECT_FALSE(update(-105.f, -100.f)); | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, no_trigger_within_threshold) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "no_trigger_within_threshold" according to Googletest FAQ
| EXPECT_FALSE(update(-97.f, -100.f)); | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, trigger_after_sustained_drop) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "trigger_after_sustained_drop" according to Googletest FAQ
| EXPECT_TRUE(update(-91.f, -100.f)); // 6m drop, triggers | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, ratchet_holds_on_partial_recovery) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "ratchet_holds_on_partial_recovery" according to Googletest FAQ
| EXPECT_TRUE(update(-90.f, -100.f)); // ratchet = -96, drop = 6m, triggers | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, reset_when_back_above_setpoint) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "reset_when_back_above_setpoint" according to Googletest FAQ
| EXPECT_FALSE(update(-95.f, -100.f)); // drop = 2m, no trigger | ||
| } | ||
|
|
||
| TEST_F(FailureDetectorAltitudeLossTest, no_trigger_on_ekf_z_reset) |
There was a problem hiding this comment.
[error] google-readability-avoid-underscore-in-googletest-name [error]
avoid using "_" in test name "no_trigger_on_ekf_z_reset" according to Googletest FAQ
🔎 FLASH Analysispx4_fmu-v5x [Total VM Diff: 840 byte (0.04 %)]px4_fmu-v6x [Total VM Diff: 928 byte (0.05 %)]Updated: 2026-04-13T09:08:56 |
Solved Problem
Rotary-wing vehicles with a parachute system have no dedicated failsafe
for uncommanded altitude loss (e.g. motor failure, structural failure).
The existing
fd_critical_failurepath covers attitude limits andexternal ATS, but not altitude drop while the vehicle is still
attitude-stable. This PR adds that missing detection path.
Solution
FailureDetector::updateAltitudeStatusis called each cycle whenattitude control is active. It compares
vehicle_local_position.zagainst
vehicle_local_position_setpoint.zusing a ratchetingreference that tracks the highest altitude reached while below the
setpoint. When the drop exceeds
FD_ALT_LOSSforFD_ALT_LOSS_Tseconds,
failure_detector_status.flags.altis set, which propagatesto
FailsafeFlags.fd_alt_lossand triggersAction::Terminatein thefailsafe framework. Commander then sets
actuator_armed.termination = trueand callssend_parachute_command()on the rising edge.Changelog Entry
New feature: uncommanded altitude loss detection for rotary-wing vehicles.
When FD_ALT_LOSS > 0, a drop exceeding the threshold while altitude
control is active immediately triggers flight termination and parachute
deployment via COM_ALT_LOSS_ACT.
New parameters: FD_ALT_LOSS, FD_ALT_LOSS_T, COM_ALT_LOSS_ACT
Test coverage
make px4_sitl_default,make px4_fmu-v6x_defaultmake tests TESTFILTER=failsafe_test