diff --git a/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.cpp b/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.cpp index a3abb2f3fa..4d8dca72be 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.cpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.cpp @@ -38,49 +38,64 @@ using namespace time_literals; void ParachuteChecks::checkAndReport(const Context &context, Report &reporter) { - if (!_param_com_parachute.get()) { - return; - } + const int action = _param_com_parachute.get(); - reporter.failsafeFlags().parachute_unhealthy = - !context.status().parachute_system_present || - !context.status().parachute_system_healthy; + if (action > 0) { + reporter.failsafeFlags().parachute_unhealthy = + !context.status().parachute_system_present || + !context.status().parachute_system_healthy; - if (!context.status().parachute_system_present) { - /* EVENT - * @description - * No MAVLink parachute heartbeat detected. Check connection, power, configuration. - * - * - * Enabled by COM_PARACHUTE - * - */ - reporter.healthFailure(NavModes::All, health_component_t::parachute, events::ID("check_parachute_missing"), - events::Log::Error, "Parachute system missing"); + // Values >= 2 block arming; value 1 is warning-only + const bool warn_only = (action == 1); + const events::Log log_level = warn_only ? events::Log::Warning : events::Log::Error; + const NavModes affected_modes = warn_only ? NavModes::None : NavModes::All; - if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Parachute system missing"); + if (!context.status().parachute_system_present) { + /* EVENT + * @description + * No MAVLink parachute heartbeat detected. Check connection, power, configuration. + * + * + * Configured by COM_PARACHUTE + * + */ + reporter.healthFailure(affected_modes, health_component_t::parachute, events::ID("check_parachute_missing"), + log_level, "Parachute system missing"); + + if (reporter.mavlink_log_pub()) { + if (warn_only) { + mavlink_log_warning(reporter.mavlink_log_pub(), "Parachute system missing"); + + } else { + mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Parachute system missing"); + } + } + + } else if (!context.status().parachute_system_healthy) { + + /* EVENT + * @description + * MAVLink parachute system reports unhealthy status. + * + * + * Configured by COM_PARACHUTE + * + */ + reporter.healthFailure(affected_modes, health_component_t::parachute, events::ID("check_parachute_unhealthy"), + log_level, "Parachute system not ready"); + + if (reporter.mavlink_log_pub()) { + if (warn_only) { + mavlink_log_warning(reporter.mavlink_log_pub(), "Parachute system not ready"); + + } else { + mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Parachute system not ready"); + } + } } - } else if (!context.status().parachute_system_healthy) { - - /* EVENT - * @description - * MAVLink parachute system reports unhealthy status. - * - * - * Enabled by COM_PARACHUTE - * - */ - reporter.healthFailure(NavModes::All, health_component_t::parachute, events::ID("check_parachute_unhealthy"), - events::Log::Error, "Parachute system not ready"); - - if (reporter.mavlink_log_pub()) { - mavlink_log_critical(reporter.mavlink_log_pub(), "Preflight Fail: Parachute system not ready"); + if (context.status().parachute_system_present) { + reporter.setIsPresent(health_component_t::parachute); } } - - if (context.status().parachute_system_present) { - reporter.setIsPresent(health_component_t::parachute); - } } diff --git a/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.hpp b/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.hpp index 162c03277c..ea849e31dd 100644 --- a/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.hpp +++ b/src/modules/commander/HealthAndArmingChecks/checks/parachuteCheck.hpp @@ -45,6 +45,6 @@ public: private: DEFINE_PARAMETERS_CUSTOM_PARENT(HealthAndArmingCheckBase, - (ParamBool) _param_com_parachute + (ParamInt) _param_com_parachute ) }; diff --git a/src/modules/commander/commander_params.yaml b/src/modules/commander/commander_params.yaml index 2ff924f4ad..a50638833b 100644 --- a/src/modules/commander/commander_params.yaml +++ b/src/modules/commander/commander_params.yaml @@ -510,9 +510,20 @@ parameters: max: 4 COM_PARACHUTE: description: - short: Require MAVLink parachute system to be present and healthy - type: boolean + short: Parachute system monitoring and failsafe action + long: |- + Configures whether a MAVLink parachute system is monitored and what action is + taken when it reports missing or unhealthy status. + From Error onwards the check also blocks arming. + type: enum + values: + 0: Disabled + 1: Warning only + 2: Error (blocks arming) + 3: Return + 4: Land default: 0 + increment: 1 COM_ARM_CHK_ESCS: description: short: Enable checks on ESCs that report telemetry diff --git a/src/modules/commander/failsafe/failsafe.cpp b/src/modules/commander/failsafe/failsafe.cpp index 6331b6576d..82eb0d4560 100644 --- a/src/modules/commander/failsafe/failsafe.cpp +++ b/src/modules/commander/failsafe/failsafe.cpp @@ -412,6 +412,36 @@ FailsafeBase::ActionOptions Failsafe::fromPosLowActParam(int param_value) return options; } +FailsafeBase::ActionOptions Failsafe::fromParachuteActParam(int param_value) +{ + ActionOptions options{}; + + switch (parachute_unhealthy_failsafe_mode(param_value)) { + case parachute_unhealthy_failsafe_mode::Disabled: + default: + options.action = Action::None; + break; + + case parachute_unhealthy_failsafe_mode::Warning: + case parachute_unhealthy_failsafe_mode::Error: + options.action = Action::Warn; + options.clear_condition = ClearCondition::WhenConditionClears; + break; + + case parachute_unhealthy_failsafe_mode::Return: + options.action = Action::RTL; + options.clear_condition = ClearCondition::OnModeChangeOrDisarm; + break; + + case parachute_unhealthy_failsafe_mode::Land: + options.action = Action::Land; + options.clear_condition = ClearCondition::OnModeChangeOrDisarm; + break; + } + + return options; +} + FailsafeBase::ActionOptions Failsafe::fromRemainingFlightTimeLowActParam(int param_value) { ActionOptions options{}; @@ -607,7 +637,7 @@ void Failsafe::checkStateAndMode(const hrt_abstime &time_us, const State &state, } // Parachute system health failsafe - CHECK_FAILSAFE(status_flags, parachute_unhealthy, Action::RTL); + CHECK_FAILSAFE(status_flags, parachute_unhealthy, ActionOptions(fromParachuteActParam(_param_com_parachute_act.get()))); // Remote ID (Open Drone ID) loss failsafe if (state.armed && _param_com_arm_odid.get() >= int32_t(open_drone_id_failsafe_mode::Return_mode)) { diff --git a/src/modules/commander/failsafe/failsafe.h b/src/modules/commander/failsafe/failsafe.h index f988ca607b..bca75918b1 100644 --- a/src/modules/commander/failsafe/failsafe.h +++ b/src/modules/commander/failsafe/failsafe.h @@ -166,6 +166,14 @@ private: Terminate = 5, }; + enum class parachute_unhealthy_failsafe_mode : int32_t { + Disabled = 0, + Warning = 1, + Error = 2, + Return = 3, + Land = 4, + }; + static ActionOptions fromNavDllOrRclActParam(int param_value); static ActionOptions fromGfActParam(int param_value); @@ -178,6 +186,7 @@ private: static ActionOptions fromPosLowActParam(int param_value); static ActionOptions fromRemainingFlightTimeLowActParam(int param_value); static ActionOptions fromOdidFailActParam(int param_value); + static ActionOptions fromParachuteActParam(int param_value); static bool isFailsafeIgnored(uint8_t user_intended_mode, int32_t exception_mask_parameter); @@ -220,7 +229,8 @@ private: (ParamInt) _param_com_wind_max_act, (ParamInt) _param_com_fltt_low_act, (ParamInt) _param_com_pos_low_act, - (ParamInt) _param_com_arm_odid + (ParamInt) _param_com_arm_odid, + (ParamInt) _param_com_parachute_act ); };