Skip to content

failsafe: Prevent Offboard to Position without RC#26289

Merged
sfuhrer merged 6 commits intoPX4:mainfrom
ttechnick:offboard_pos_rc_fix
Jan 29, 2026
Merged

failsafe: Prevent Offboard to Position without RC#26289
sfuhrer merged 6 commits intoPX4:mainfrom
ttechnick:offboard_pos_rc_fix

Conversation

@ttechnick
Copy link
Copy Markdown
Member

@ttechnick ttechnick commented Jan 16, 2026

Solved Problem

It was possible to failsafe from Offboard mode into Position mode by setting COM_OBL_RC_ACT to Position. If the offboard signal was lost and no RC was available (allowed by COM_RCL_EXCEPT during Offboard mode), the vehicle would still switch to Position mode, creating a dangerous situation.

Solution

Include a check in the offboard failsafe logic to prevent a switch to manual modes without RC.

Changelog Entry

Bugfix: Trigger RC loss failsafe when Offboard loss failsafe is set to Position mode but no RC present

Test coverage

Failsafe State Machine Simulation

Before:

image ## After: image

@ttechnick ttechnick requested a review from MaEtUgR January 16, 2026 10:22
Copy link
Copy Markdown
Member

@MaEtUgR MaEtUgR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this and finding a fix. I'm sure this works for the described issue case. That said I'm wondering why there's no fallback for e.g. FallbackPosCtrl and alike. Because what I imagine is that you run into the same issue for all cases that have Fallback... as action and no RC is present. So the only reason there might be no issue with those is that the user intention already needs to require stick input and we likely don't switch to them with the mode requirement is not met. 👀

So in summary I'm wondering if there's a way to run Fallback... through the typical ladder of mode requirement checks instead of handling the case specifically. If that's a big hassle I'm fine with this change.

@ttechnick
Copy link
Copy Markdown
Member Author

@MaEtUgR
The Fallback test of the modes are run in modeCanRun():

bool FailsafeBase::modeCanRun(const failsafe_flags_s &status_flags, uint8_t mode)
{
	uint32_t mode_mask = 1u << mode;
	// mode_req_wind_and_flight_time_compliance: does not need to be handled here (these are separate failsafe triggers)
	// mode_req_manual_control: is handled separately
	return
		(!status_flags.angular_velocity_invalid || ((status_flags.mode_req_angular_velocity & mode_mask) == 0)) &&
		(!status_flags.attitude_invalid || ((status_flags.mode_req_attitude & mode_mask) == 0)) &&
		(!status_flags.local_position_invalid || ((status_flags.mode_req_local_position & mode_mask) == 0)) &&
		(!status_flags.local_position_invalid_relaxed || ((status_flags.mode_req_local_position_relaxed & mode_mask) == 0)) &&
		(!status_flags.global_position_invalid || ((status_flags.mode_req_global_position & mode_mask) == 0)) &&
		(!status_flags.local_altitude_invalid || ((status_flags.mode_req_local_alt & mode_mask) == 0)) &&
		(!status_flags.auto_mission_missing || ((status_flags.mode_req_mission & mode_mask) == 0)) &&
		(!status_flags.offboard_control_signal_lost || ((status_flags.mode_req_offboard_signal & mode_mask) == 0)) &&
		(!status_flags.home_position_invalid || ((status_flags.mode_req_home_position & mode_mask) == 0)) &&
		((status_flags.mode_req_other & mode_mask) == 0);
}

// mode_req_manual_control: is handled separately is misleading here. @bkueng has written it, and may be able to explain a bit here?

@ttechnick ttechnick requested a review from bkueng January 27, 2026 13:13
@ttechnick
Copy link
Copy Markdown
Member Author

I checked with @bkueng, and adding the check for the Rc in canModeRun() is not possible, as it will result in a wrong mode switch, depending on the configuration of the RC loss parameter.
The only other thing I can think of is to repeat the check I implemented for all these three modes.

Copy link
Copy Markdown
Contributor

@sfuhrer sfuhrer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It fixes the imminent issue, and as no generic solution has been found let's go ahead.

@sfuhrer sfuhrer merged commit 03264ce into PX4:main Jan 29, 2026
66 of 69 checks passed
@ttechnick ttechnick deleted the offboard_pos_rc_fix branch January 29, 2026 17:37
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.

3 participants