refactor(offboarding-check): report specific failures (#26938)
Build all targets / Scan for Board Targets (push) Has been cancelled
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Has been cancelled
Build all targets / Upload Artifacts (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_fmu-v5_default) (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_sitl_default) (push) Has been cancelled
Checks / build (check_format) (push) Has been cancelled
Checks / build (check_newlines) (push) Has been cancelled
Checks / build (module_documentation) (push) Has been cancelled
Checks / build (px4_fmu-v2_default stack_check) (push) Has been cancelled
Checks / build (px4_sitl_allyes) (push) Has been cancelled
Checks / build (shellcheck_all) (push) Has been cancelled
Checks / build (tests) (push) Has been cancelled
Checks / build (tests_coverage) (push) Has been cancelled
Checks / build (validate_module_configs) (push) Has been cancelled
Static Analysis / Clang-Tidy (push) Has been cancelled
MacOS build / build (px4_fmu-v5_default) (push) Has been cancelled
MacOS build / build (px4_sitl) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Has been cancelled
Container build / Set Tags and Variables (push) Has been cancelled
Container build / Build Container (amd64) (push) Has been cancelled
Container build / Build Container (arm64) (push) Has been cancelled
Container build / Deploy To Registry (push) Has been cancelled
Docs - Orchestrator / T1: Detect Changes (push) Has been cancelled
Docs - Orchestrator / T2: PR Metadata (push) Has been cancelled
Docs - Orchestrator / T2: Metadata Sync (push) Has been cancelled
Docs - Orchestrator / T2: Link Check (push) Has been cancelled
Docs - Orchestrator / T3: Build Site (push) Has been cancelled
Docs - Orchestrator / T4: Deploy (push) Has been cancelled
Docs - Crowdin - Upload Guide sources (en) / upload-to-crowdin (push) Has been cancelled
EKF Update Change Indicator / unit_tests (push) Has been cancelled
Failsafe Simulator Build / build (failsafe_web) (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Has been cancelled
FLASH usage analysis / Publish Results (push) Has been cancelled
ITCM check / Checking nxp_mr-tropic (push) Has been cancelled
ITCM check / Checking nxp_tropic-community (push) Has been cancelled
ITCM check / Checking px4_fmu-v5x (push) Has been cancelled
ITCM check / Checking px4_fmu-v6xrt (push) Has been cancelled
MAVROS Mission Tests / build (push) Has been cancelled
MAVROS Offboard Tests / build (push) Has been cancelled
Nuttx Target with extra env config / build (px4_fmu-v5_default) (push) Has been cancelled
Python CI Checks / build (push) Has been cancelled
ROS Integration Tests / build (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:humble ubuntu:jammy]) (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:jazzy ubuntu:noble]) (push) Has been cancelled
SITL Tests / Testing PX4 iris (push) Has been cancelled
Handle stale issues and PRs / stale (push) Has been cancelled
Fuzzing / Fuzzing (push) Has been cancelled

* offboard: report specific failures

Figuring out offboard failures is quite difficult because the user currently
gets a single, very generic error message that does not identify the actual
missing requirement.

This change aims to improve the user experience by:

- moving offboard failure reporting into OffboardChecks, where the exact cause is known
- reporting specific arming failures for missing local position, local velocity and attitude estimates
- keeping the generic offboard signal error only as a fallback for true signal-loss cases
- removing the duplicate offboard check from ModeChecks (as already invoked by HealthAndArmingChecks)

Signed-off-by: Onur Özkan <work@onurozkan.dev>

* offboard: handle attitude mode in offboard check

Signed-off-by: Onur Özkan <work@onurozkan.dev>

---------

Signed-off-by: Onur Özkan <work@onurozkan.dev>
This commit is contained in:
Onur Özkan
2026-04-08 19:23:20 +03:00
committed by GitHub
parent 36c3bfcde8
commit aaace556cd
2 changed files with 52 additions and 13 deletions
@@ -141,17 +141,6 @@ void ModeChecks::checkAndReport(const Context &context, Report &reporter)
reporter.clearCanRunBits((NavModes)reporter.failsafeFlags().mode_req_mission);
}
if (reporter.failsafeFlags().offboard_control_signal_lost && reporter.failsafeFlags().mode_req_offboard_signal != 0) {
/* EVENT
* @description
* The offboard component is not sending setpoints or the required estimate (e.g. position) is missing.
*/
reporter.armingCheckFailure((NavModes)reporter.failsafeFlags().mode_req_offboard_signal, health_component_t::system,
events::ID("check_modes_offboard_signal"),
events::Log::Error, "No offboard signal");
reporter.clearCanRunBits((NavModes)reporter.failsafeFlags().mode_req_offboard_signal);
}
if (reporter.failsafeFlags().home_position_invalid && reporter.failsafeFlags().mode_req_home_position != 0) {
/* EVENT
*/
@@ -40,6 +40,9 @@ void OffboardChecks::checkAndReport(const Context &context, Report &reporter)
reporter.failsafeFlags().offboard_control_signal_lost = true;
offboard_control_mode_s offboard_control_mode;
const NavModes affected_modes = (NavModes)reporter.failsafeFlags().mode_req_offboard_signal;
const bool has_affected_modes = affected_modes != NavModes::None;
bool has_specific_reason = false;
if (_offboard_control_mode_sub.copy(&offboard_control_mode)) {
@@ -52,16 +55,63 @@ void OffboardChecks::checkAndReport(const Context &context, Report &reporter)
if (offboard_control_mode.position && reporter.failsafeFlags().local_position_invalid) {
offboard_available = false;
has_specific_reason = true;
if (has_affected_modes) {
/* EVENT
* @description
* Offboard position control requires a valid local position estimate.
*/
reporter.armingCheckFailure(affected_modes, health_component_t::system,
events::ID("check_modes_offboard_no_local_position"),
events::Log::Error, "Offboard requires local position");
reporter.clearCanRunBits(affected_modes);
}
} else if (offboard_control_mode.velocity && reporter.failsafeFlags().local_velocity_invalid) {
offboard_available = false;
has_specific_reason = true;
} else if (offboard_control_mode.acceleration && reporter.failsafeFlags().attitude_invalid) {
// OFFBOARD acceleration handled by position controller
if (has_affected_modes) {
/* EVENT
* @description
* Offboard velocity control requires a valid local velocity estimate.
*/
reporter.armingCheckFailure(affected_modes, health_component_t::system,
events::ID("check_modes_offboard_no_local_velocity"),
events::Log::Error, "Offboard requires local velocity");
reporter.clearCanRunBits(affected_modes);
}
} else if ((offboard_control_mode.acceleration || offboard_control_mode.attitude)
&& reporter.failsafeFlags().attitude_invalid) {
offboard_available = false;
has_specific_reason = true;
if (has_affected_modes) {
/* EVENT
* @description
* Offboard acceleration and attitude control require a valid attitude estimate.
*/
reporter.armingCheckFailure(affected_modes, health_component_t::system,
events::ID("check_modes_offboard_no_attitude"),
events::Log::Error, "Offboard requires attitude estimate");
reporter.clearCanRunBits(affected_modes);
}
}
// This is a mode requirement, no need to report
reporter.failsafeFlags().offboard_control_signal_lost = !offboard_available;
}
if (reporter.failsafeFlags().offboard_control_signal_lost && !has_specific_reason && has_affected_modes) {
/* EVENT
* @description
* The offboard component is not sending recent setpoints.
*/
reporter.armingCheckFailure(affected_modes, health_component_t::system,
events::ID("check_modes_offboard_signal_lost"),
events::Log::Error, "No offboard signal");
reporter.clearCanRunBits(affected_modes);
}
}