Skip to content
Docs
foxborne.comRequest a pilot

Failsafe

Flags the moment PX4 reports a failsafe in vehicle_status, with the cause from failsafe_flags and the mode PX4 chose. It observes PX4's decision, which PX4 times on its own status reports.

Rule referenceMarkdown
On this page9
failsafe_enteredv1.0On by default
Detects
vehicle_status reports a failsafe, with the cause from failsafe_flags.
Threshold
Any failsafe
Reads
Flight log
Report wording
Observed: failsafe entered, with its cause

What it reads#

The rule reads two topics from the flight log:

  • vehicle_status.failsafe: true while PX4 is in a failsafe state.
  • vehicle_status.nav_state: the mode now active.
  • failsafe_flags: one flag per condition. The rule takes the cause from the flag that is set, such as gcs_connection_lost.
VehicleStatus.msgPX4 v1.16.0, abridgedText
uint8 nav_state                                 # Currently active mode
uint8 NAVIGATION_STATE_AUTO_LOITER = 4          # Auto loiter mode
uint8 NAVIGATION_STATE_AUTO_RTL = 5             # Return mode
bool failsafe # true if system is in failsafe state (e.g. Return, Hover, Terminate, ...)

In PX4 v1.16.0 the commander sets failsafe while its failsafe state machine has selected an action other than none or a warning. The action for each condition comes from a parameter:

Flag in failsafe_flagsAction set byExample dataset
gcs_connection_lostNAV_DLL_ACT, after COM_DL_LOSS_T1 (Hold) on the T4, 2 (Return) on the Q4
offboard_control_signal_lostCOM_OBL_RC_ACT, after COM_OF_LOSS_T5 (Hold)
gnss_lostCOM_GNSSLOSS_ACT0 (Warning)

The vehicle page lists these values under Failsafe parameters, with the run they were read from.

When it fires#

The threshold reads Any failsafe: a finding is produced each time vehicle_status.failsafe turns true. The event records the cause, the action and how long PX4 took to act. In INC-0143 its title reads GCS connection loss: switching to Hold, the wording PX4 uses for a failsafe with a cause.

PX4's MAVLink receiver keeps heartbeat_type_gcs true in telemetry_status until 2.5 s pass without a ground station heartbeat (HEARTBEAT_TIMEOUT_US). It re-evaluates the flag on every heartbeat from a ground station or from its own system. Between heartbeats, it checks again once 1.25 s have passed since the last check.

The status topic goes out at least once a second, and the commander restarts its timer on every report that still says true. COM_DL_LOSS_T therefore counts from the last report with the heartbeat, not from the heartbeat:

src/modules/commander/Commander.cppPX4 v1.16.0, Commander::dataLinkCheck(), abridgedC++
if (telemetry.heartbeat_type_gcs) {
	...
	_datalink_last_heartbeat_gcs = telemetry.timestamp;
}
...
// GCS data link loss failsafe
if (!_vehicle_status.gcs_connection_lost) {
	if ((_datalink_last_heartbeat_gcs != 0)
	    && hrt_elapsed_time(&_datalink_last_heartbeat_gcs) > (_param_com_dl_loss_t.get() * 1_s)) {

		_vehicle_status.gcs_connection_lost = true;

COM_DL_LOSS_T is 10 s by default, from 5 s to 300 s. With the default, the failsafe lands about 11.5 s to 13.75 s after the last heartbeat, depending on how heartbeats and reports happen to fall.

Example data0 s2 s4 s6 s8 s10 s12 s10 stimeout 2.5 s+0.000 sLast GCS HEARTBEAT handled on TELEM2+1.874 sLast telemetry_status with heartbeat_type_gcs true+2.874 sFirst report with it false, 2.874 s after the heartbeat+11.874 sCOM_DL_LOSS_T (10 s) runs out, counted from row 2+11.881 sgcs_connection_lost; NAV_DLL_ACT 1 selects Hold0 s4 s8 s12 s10 s+0.000 sLast GCS heartbeat handled+1.874 sLast report with heartbeat_type_gcs true+2.874 sFirst report with it false+11.874 sCOM_DL_LOSS_T (10 s) runs out+11.881 sgcs_connection_lost: Hold
How PX4 reached Hold in INC-0143. Offsets run from the last ground station heartbeat PX4 handled, at 15:41:02.412. COM_DL_LOSS_T counts its 10 s from the last telemetry_status that still reported that heartbeat, 1.874 s later.

How PX4 chooses the action#

NAV_DLL_ACT selects what PX4 does once the ground link counts as lost. PX4's default is 0, which takes no action at all.

NAV_DLL_ACTAction
0Disabled
1Hold mode
2Return mode
3Land mode
5Terminate
6Disarm

COM_FAIL_ACT_T, 5 s by default, makes PX4 hold before it enters a Return or a Land. Hold itself is never delayed, and neither are Disarm and Terminate:

framework.cppPX4 v1.16.0, FailsafeBase::getSelectedAction(), abridgedC++
// Check if we should enter delayed Hold
const bool action_can_be_delayed = selected_action != Action::None &&
				   selected_action != Action::Warn &&
				   selected_action != Action::Disarm &&
				   selected_action != Action::Terminate &&
				   selected_action != Action::Hold;

Wording and evidence level#

Every finding reads Observed: failsafe entered, with its cause. The flight log shows directly that PX4 entered a failsafe and which flag it acted on, so the level is observed.

What the finding does not mean#

  • A late-looking failsafe is not a fault. A Hold 11.88 s after the last heartbeat, with COM_DL_LOSS_T at 10 s, is PX4 counting from its last status report as designed.
  • It does not say why the link was lost. The flag records what PX4 stopped hearing, not what broke. In INC-0143 the radio left the companion's USB bus, which device_disconnect records.
  • A set flag with no action is not a failsafe. With NAV_DLL_ACT at 0 (Disabled), PX4 does not treat a lost ground link as a failsafe, so failsafe stays false. INC-0137 ran that way by its test plan: the flight log shows gcs_connection_lost, PX4 continued the mission and this rule produced nothing.
  • Warnings never produce it. PX4 sets failsafe only for actions beyond a warning. The example vehicles run COM_GNSSLOSS_ACT at 0 (Warning), so a GNSS loss on them raises no failsafe.
  • PX4 ignores some losses. In v1.16.0 a lost ground link triggers nothing while the vehicle is disarmed or landing, including a precision landing. The same holds in any mode listed in COM_DLL_EXCEPT.
  • The first mode can differ from the action. With NAV_DLL_ACT at 2 (Return), the example Q4 setting, PX4 first holds for COM_FAIL_ACT_T, 5 s in the example, then returns. Read the nav_state records after the finding.

Threshold and overrides#

The threshold is Any failsafe, applied to All vehicles. The rule has no number of its own to tune, because PX4's parameters decide when a failsafe happens. The vehicle page's Changes between runs drawer shows when those parameters change, for example NAV_DLL_ACT 0 (Disabled) to 1 (Hold) on UGV-05 in R-0924.

Change the scope under Rules with Edit; the rule saves as failsafe_entered 1.1. See Thresholds, scopes and overrides.

Example finding#

In INC-0143, UGV-02's radio dropped off the companion's USB bus at 15:41:02.604 in Breach lane 2. PX4 had handled the last ground station heartbeat at 15:41:02.412. The last telemetry_status that still reported it came at 15:41:04.286, and the first without it at 15:41:05.286.

COM_DL_LOSS_T ran out at 15:41:14.286, and PX4 switched to Hold at 15:41:14.293. That is 11.88 s after the last heartbeat (15:41:14.293 minus 15:41:02.412) and 10.01 s after the last report (15:41:14.293 minus 15:41:04.286). The vehicle stopped 1.0 s later, and range control resumed the mission 56.2 s after the Hold.

The Findings row labels the finding Failsafe: Hold. On the event page, Failsafe decision walks through the same steps on the flight log clock, each with the PX4 source it follows. Its Parameters in effect list reads COM_DL_LOSS_T 10 s, NAV_DLL_ACT 1 (Hold) and COM_FAIL_ACT_T 5 s (not applied to Hold).

INC-0142 shows the opposite case. PX4 reported no ground station heartbeat on TELEM2 at 14:32:06.510, but the receive gap lasted 6.96 s, under COM_DL_LOSS_T. PX4 recorded no failsafe, and this rule produced nothing.