Commander: replace arm requirements

This commit is contained in:
Matthias Grob
2022-06-16 10:25:32 -04:00
committed by Daniel Agar
parent 3b3d8b9942
commit 92b6862485
11 changed files with 58 additions and 110 deletions
@@ -42,7 +42,6 @@ transition_result_t ArmStateMachine::arming_state_transition(vehicle_status_s &s
const vehicle_control_mode_s &control_mode, const bool safety_button_available, const bool safety_off,
const arming_state_t new_arming_state, actuator_armed_s &armed, const bool fRunPreArmChecks,
orb_advert_t *mavlink_log_pub, vehicle_status_flags_s &status_flags,
const PreFlightCheck::arm_requirements_t &arm_requirements,
const hrt_abstime &time_since_boot, arm_disarm_reason_t calling_reason)
{
// Double check that our static arrays are still valid
@@ -70,10 +69,9 @@ transition_result_t ArmStateMachine::arming_state_transition(vehicle_status_s &s
if (!PreFlightCheck::preflightCheck(mavlink_log_pub, status, status_flags, control_mode,
true, // report_failures
true, // prearm
time_since_boot,
safety_button_available, safety_off,
arm_requirements)) {
true)) { // is_arm_attempt
feedback_provided = true; // Preflight checks report error messages
valid_transition = false;
}
@@ -57,7 +57,7 @@ public:
arming_state_transition(vehicle_status_s &status, const vehicle_control_mode_s &control_mode,
const bool safety_button_available, const bool safety_off, const arming_state_t new_arming_state,
actuator_armed_s &armed, const bool fRunPreArmChecks, orb_advert_t *mavlink_log_pub,
vehicle_status_flags_s &status_flags, const PreFlightCheck::arm_requirements_t &arm_requirements,
vehicle_status_flags_s &status_flags,
const hrt_abstime &time_since_boot, arm_disarm_reason_t calling_reason);
// Getters
@@ -250,8 +250,6 @@ TEST(ArmStateMachineTest, ArmingStateTransitionTest)
for (size_t i = 0; i < cArmingTransitionTests; i++) {
const ArmingTransitionTest_t *test = &rgArmingTransitionTests[i];
PreFlightCheck::arm_requirements_t arm_req{};
// Setup initial machine state
arm_state_machine.forceArmState(test->current_state.arming_state);
status.hil_state = test->hil_state;
@@ -271,7 +269,6 @@ TEST(ArmStateMachineTest, ArmingStateTransitionTest)
true /* enable pre-arm checks */,
nullptr /* no mavlink_log_pub */,
status_flags,
arm_req,
2e6, /* 2 seconds after boot, everything should be checked */
arm_disarm_reason_t::unit_test);
@@ -52,9 +52,9 @@ static constexpr unsigned max_mandatory_baro_count = 1;
bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status,
vehicle_status_flags_s &status_flags, const vehicle_control_mode_s &control_mode,
bool report_failures, const bool prearm, const hrt_abstime &time_since_boot,
bool report_failures, const hrt_abstime &time_since_boot,
const bool safety_button_available, const bool safety_off,
const arm_requirements_t &arm_requirements)
const bool is_arm_attempt)
{
report_failures = (report_failures && !status_flags.calibration_enabled);
@@ -143,7 +143,7 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
const float arming_max_airspeed_allowed = airspeed_trim / 2.0f; // set to half of trim airspeed
if (!airspeedCheck(mavlink_log_pub, status, optional, report_failures, prearm, (bool)max_airspeed_check_en,
if (!airspeedCheck(mavlink_log_pub, status, optional, report_failures, is_arm_attempt, (bool)max_airspeed_check_en,
arming_max_airspeed_allowed)
&& !(bool)optional) {
failed = true;
@@ -175,7 +175,7 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
/* ---- SYSTEM POWER ---- */
if (status_flags.power_input_valid && !status_flags.circuit_breaker_engaged_power_check) {
if (!powerCheck(mavlink_log_pub, status, report_failures, prearm)) {
if (!powerCheck(mavlink_log_pub, status, report_failures)) {
failed = true;
}
}
@@ -195,7 +195,7 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
if (estimator_type == 2) {
const bool in_grace_period = time_since_boot < 10_s;
const bool do_report_ekf2_failures = report_failures && (!in_grace_period || prearm);
const bool do_report_ekf2_failures = report_failures && (!in_grace_period);
const bool ekf_healthy = ekf2Check(mavlink_log_pub, status, false, do_report_ekf2_failures) &&
ekf2CheckSensorBias(mavlink_log_pub, do_report_ekf2_failures);
@@ -220,7 +220,7 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
}
/* ---- Failure Detector ---- */
if (!failureDetectorCheck(mavlink_log_pub, status, report_failures, prearm)) {
if (!failureDetectorCheck(mavlink_log_pub, status, report_failures)) {
failed = true;
}
@@ -229,7 +229,7 @@ bool PreFlightCheck::preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_statu
failed = failed || !cpuResourceCheck(mavlink_log_pub, report_failures);
failed = failed || !parachuteCheck(mavlink_log_pub, report_failures, status_flags);
failed = failed || !preArmCheck(mavlink_log_pub, status_flags, control_mode,
safety_button_available, safety_off, arm_requirements, status, report_failures);
safety_button_available, safety_off, status, report_failures, is_arm_attempt);
/* Report status */
return !failed;
@@ -56,44 +56,17 @@ public:
PreFlightCheck() = default;
~PreFlightCheck() = default;
struct arm_requirements_t {
bool arm_authorization = false;
bool esc_check = false;
bool global_position = false;
bool mission = false;
bool geofence = false;
};
/**
* Runs a preflight check on all sensors to see if they are properly calibrated and healthy
*
* The function won't fail the test if optional sensors are not found, however,
* it will fail the test if optional sensors are found but not in working condition.
* Runs a preflight check to determine if the system is ready to be armed
*
* @param mavlink_log_pub
* Mavlink output orb handle reference for feedback when a sensor fails
* @param checkMag
* true if the magneteometer should be checked
* @param checkAcc
* true if the accelerometers should be checked
* @param checkGyro
* true if the gyroscopes should be checked
* @param checkBaro
* true if the barometer should be checked
* @param checkAirspeed
* true if the airspeed sensor should be checked
* @param checkRC
* true if the Remote Controller should be checked
* @param checkGNSS
* true if the GNSS receiver should be checked
* @param checkPower
* true if the system power should be checked
**/
static bool preflightCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status,
vehicle_status_flags_s &status_flags, const vehicle_control_mode_s &control_mode,
bool reportFailures, const bool prearm, const hrt_abstime &time_since_boot,
bool reportFailures, const hrt_abstime &time_since_boot,
const bool safety_button_available, const bool safety_off,
const arm_requirements_t &arm_requirements);
const bool is_arm_attempt = false);
private:
static bool sensorAvailabilityCheck(const bool report_failure,
@@ -116,18 +89,14 @@ private:
const bool is_mandatory, bool &report_fail);
static bool imuConsistencyCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status, const bool report_status);
static bool airspeedCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status, const bool optional,
const bool report_fail, const bool prearm, const bool max_airspeed_check_en, const float arming_max_airspeed_allowed);
const bool report_fail, const bool is_arm_attempt, const bool max_airspeed_check_en,
const float arming_max_airspeed_allowed);
static int rcCalibrationCheck(orb_advert_t *mavlink_log_pub, bool report_fail);
static bool powerCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail,
const bool prearm);
static bool powerCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail);
static bool ekf2Check(orb_advert_t *mavlink_log_pub, vehicle_status_s &vehicle_status, const bool optional,
const bool report_fail);
static bool ekf2CheckSensorBias(orb_advert_t *mavlink_log_pub, const bool report_fail);
static bool failureDetectorCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail,
const bool prearm);
static bool failureDetectorCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail);
static bool manualControlCheck(orb_advert_t *mavlink_log_pub, const bool report_fail);
static bool modeCheck(orb_advert_t *mavlink_log_pub, const bool report_fail, const vehicle_status_s &status);
static bool airframeCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status);
@@ -137,6 +106,5 @@ private:
const vehicle_status_flags_s &status_flags);
static bool preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_flags_s &status_flags,
const vehicle_control_mode_s &control_mode, const bool safety_button_available, const bool safety_off,
const arm_requirements_t &arm_requirements, vehicle_status_s &status,
const bool report_fail);
vehicle_status_s &status, const bool report_fail, const bool is_arm_attempt);
};
@@ -43,7 +43,8 @@
using namespace time_literals;
bool PreFlightCheck::airspeedCheck(orb_advert_t *mavlink_log_pub, vehicle_status_s &status, const bool optional,
const bool report_fail, const bool prearm, const bool max_airspeed_check_en, const float arming_max_airspeed_allowed)
const bool report_fail, const bool is_arm_attempt, const bool max_airspeed_check_en,
const float arming_max_airspeed_allowed)
{
bool present = true;
bool success = true;
@@ -84,7 +85,7 @@ bool PreFlightCheck::airspeedCheck(orb_advert_t *mavlink_log_pub, vehicle_status
* might have been removed.
*/
if (max_airspeed_check_en && fabsf(airspeed_validated.calibrated_airspeed_m_s) > arming_max_airspeed_allowed
&& prearm) {
&& !is_arm_attempt) {
if (report_fail) {
mavlink_log_critical(mavlink_log_pub, "Preflight Fail: check Airspeed Cal or pitot");
}
@@ -36,13 +36,8 @@
#include <systemlib/mavlink_log.h>
bool PreFlightCheck::failureDetectorCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status,
const bool report_fail, const bool prearm)
const bool report_fail)
{
// Ignore failure detector check after arming
if (!prearm) {
return true;
}
if (status.failure_detector_status != vehicle_status_s::FAILURE_NONE) {
if (report_fail) {
if (status.failure_detector_status & vehicle_status_s::FAILURE_ROLL) {
@@ -42,16 +42,10 @@
using namespace time_literals;
bool PreFlightCheck::powerCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail,
const bool prearm)
bool PreFlightCheck::powerCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_s &status, const bool report_fail)
{
bool success = true;
if (!prearm) {
// Ignore power check after arming.
return true;
}
if (status.hil_state == vehicle_status_s::HIL_STATE_ON) {
// Ignore power check in HITL.
return true;
@@ -34,13 +34,14 @@
#include "../PreFlightCheck.hpp"
#include <ArmAuthorization.h>
#include <HealthFlags.h>
#include <lib/parameters/param.h>
#include <systemlib/mavlink_log.h>
#include <uORB/topics/vehicle_command_ack.h>
#include <HealthFlags.h>
bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_status_flags_s &status_flags,
const vehicle_control_mode_s &control_mode, const bool safety_button_available, const bool safety_off,
const arm_requirements_t &arm_requirements, vehicle_status_s &status, const bool report_fail)
vehicle_status_s &status, const bool report_fail, const bool is_arm_attempt)
{
bool prearm_ok = true;
@@ -117,8 +118,11 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
// Arm Requirements: mission
if (arm_requirements.mission) {
int32_t _param_com_arm_mis_req = 0;
param_get(param_find("COM_ARM_MIS_REQ"), &_param_com_arm_mis_req);
const bool mission_required = (_param_com_arm_mis_req == 1);
if (mission_required) {
if (!status_flags.auto_mission_available) {
if (prearm_ok) {
if (report_fail) { mavlink_log_critical(mavlink_log_pub, "Arming denied! No valid mission"); }
@@ -136,8 +140,11 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
}
if (arm_requirements.global_position && !status_flags.circuit_breaker_engaged_posfailure_check) {
int32_t _param_com_arm_wo_gps = 1;
param_get(param_find("COM_ARM_WO_GPS"), &_param_com_arm_wo_gps);
const bool global_position_required = (_param_com_arm_wo_gps == 0);
if (global_position_required && !status_flags.circuit_breaker_engaged_posfailure_check) {
if (!status_flags.global_position_valid) {
if (prearm_ok) {
if (report_fail) { mavlink_log_critical(mavlink_log_pub, "Arming denied! Global position required"); }
@@ -174,7 +181,11 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
if (arm_requirements.esc_check && status_flags.escs_error) {
int32_t _param_com_arm_chk_escs = 1;
param_get(param_find("COM_ARM_CHK_ESCS"), &_param_com_arm_chk_escs);
const bool esc_checks_required = (_param_com_arm_chk_escs == 0);
if (esc_checks_required && status_flags.escs_error) {
if (prearm_ok) {
if (report_fail) { mavlink_log_critical(mavlink_log_pub, "Arming denied! One or more ESCs are offline"); }
@@ -182,7 +193,7 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
}
if (arm_requirements.esc_check && status_flags.escs_failure) {
if (esc_checks_required && status_flags.escs_failure) {
if (prearm_ok) {
if (report_fail) { mavlink_log_critical(mavlink_log_pub, "Arming denied! One or more ESCs have a failure"); }
@@ -191,7 +202,6 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
if (status.is_vtol) {
if (status.in_transition_mode) {
if (prearm_ok) {
if (report_fail) { mavlink_log_critical(mavlink_log_pub, "Arming denied! Vehicle is in transition state"); }
@@ -210,7 +220,11 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
}
}
if (arm_requirements.geofence && status.geofence_violated) {
int32_t _param_gf_action = 0;
param_get(param_find("GF_ACTION"), &_param_gf_action);
const bool gefence_action_configured = (_param_gf_action != 0);
if (gefence_action_configured && status.geofence_violated) {
if (report_fail) {
mavlink_log_critical(mavlink_log_pub, "Arming denied, vehicle outside geofence");
}
@@ -218,9 +232,14 @@ bool PreFlightCheck::preArmCheck(orb_advert_t *mavlink_log_pub, const vehicle_st
prearm_ok = false;
}
int32_t _param_com_arm_auth_req = 0;
param_get(param_find("COM_ARM_AUTH_REQ"), &_param_com_arm_auth_req);
const bool arm_authorization_configured = (_param_com_arm_auth_req != 0);
// Arm Requirements: authorization
// check last, and only if everything else has passed
if (arm_requirements.arm_authorization && prearm_ok) {
// skip arm authorization check until actual arming attempt
if (arm_authorization_configured && prearm_ok && is_arm_attempt) {
if (arm_auth_check() != vehicle_command_ack_s::VEHICLE_RESULT_ACCEPTED) {
// feedback provided in arm_auth_check
prearm_ok = false;
+8 -28
View File
@@ -299,11 +299,9 @@ int Commander::custom_command(int argc, char *argv[])
bool preflight_check_res = PreFlightCheck::preflightCheck(nullptr, vehicle_status, vehicle_status_flags,
vehicle_control_mode,
true, // report_failures
true, // prearm
30_s,
false, // safety_buttton_available not known
false, // safety_off not known
PreFlightCheck::arm_requirements_t{});
false); // safety_off not known
PX4_INFO("Preflight check: %s", preflight_check_res ? "OK" : "FAILED");
print_health_flags(vehicle_status);
@@ -497,7 +495,7 @@ bool Commander::shutdown_if_allowed()
return TRANSITION_DENIED != _arm_state_machine.arming_state_transition(_vehicle_status, _vehicle_control_mode,
_safety.isButtonAvailable(), _safety.isSafetyOff(),
vehicle_status_s::ARMING_STATE_SHUTDOWN,
_actuator_armed, false /* fRunPreArmChecks */, &_mavlink_log_pub, _vehicle_status_flags, _arm_requirements,
_actuator_armed, false /* fRunPreArmChecks */, &_mavlink_log_pub, _vehicle_status_flags,
hrt_elapsed_time(&_boot_timestamp), arm_disarm_reason_t::shutdown);
}
@@ -750,7 +748,7 @@ transition_result_t Commander::arm(arm_disarm_reason_t calling_reason, bool run_
transition_result_t arming_res = _arm_state_machine.arming_state_transition(_vehicle_status, _vehicle_control_mode,
_safety.isButtonAvailable(), _safety.isSafetyOff(),
vehicle_status_s::ARMING_STATE_ARMED, _actuator_armed, run_preflight_checks,
&_mavlink_log_pub, _vehicle_status_flags, _arm_requirements, hrt_elapsed_time(&_boot_timestamp),
&_mavlink_log_pub, _vehicle_status_flags, hrt_elapsed_time(&_boot_timestamp),
calling_reason);
if (arming_res == TRANSITION_CHANGED) {
@@ -794,7 +792,7 @@ transition_result_t Commander::disarm(arm_disarm_reason_t calling_reason, bool f
transition_result_t arming_res = _arm_state_machine.arming_state_transition(_vehicle_status, _vehicle_control_mode,
_safety.isButtonAvailable(), _safety.isSafetyOff(),
vehicle_status_s::ARMING_STATE_STANDBY, _actuator_armed, false,
&_mavlink_log_pub, _vehicle_status_flags, _arm_requirements,
&_mavlink_log_pub, _vehicle_status_flags,
hrt_elapsed_time(&_boot_timestamp), calling_reason);
if (arming_res == TRANSITION_CHANGED) {
@@ -855,11 +853,9 @@ Commander::Commander() :
// run preflight immediately to find all relevant parameters, but don't report
PreFlightCheck::preflightCheck(&_mavlink_log_pub, _vehicle_status, _vehicle_status_flags, _vehicle_control_mode,
false, // report_failures
true, // prearm
hrt_elapsed_time(&_boot_timestamp),
false, // safety_buttton_available not known
false, // safety_off not known,
PreFlightCheck::arm_requirements_t{});
false); // safety_off not known
}
Commander::~Commander()
@@ -1412,7 +1408,6 @@ Commander::handle_command(const vehicle_command_s &cmd)
_safety.isButtonAvailable(), _safety.isSafetyOff(),
vehicle_status_s::ARMING_STATE_INIT, _actuator_armed,
false /* fRunPreArmChecks */, &_mavlink_log_pub, _vehicle_status_flags,
PreFlightCheck::arm_requirements_t{}, // arming requirements not relevant for switching to ARMING_STATE_INIT
30_s, // time since boot not relevant for switching to ARMING_STATE_INIT
(cmd.from_external ? arm_disarm_reason_t::command_external : arm_disarm_reason_t::command_internal))
) {
@@ -2110,11 +2105,6 @@ void Commander::updateParameters()
_vehicle_status_flags.avoidance_system_required = _param_com_obs_avoid.get();
_arm_requirements.arm_authorization = _param_arm_auth_required.get();
_arm_requirements.esc_check = _param_escs_checks_required.get();
_arm_requirements.global_position = !_param_arm_without_gps.get();
_arm_requirements.mission = _param_arm_mission_required.get();
_auto_disarm_killed.set_hysteresis_time_from(false, _param_com_kill_disarm.get() * 1_s);
_offboard_available.set_hysteresis_time_from(true, _param_com_of_loss_t.get() * 1_s);
@@ -2469,7 +2459,7 @@ Commander::run()
_safety.isButtonAvailable(), _safety.isSafetyOff(),
vehicle_status_s::ARMING_STATE_STANDBY, _actuator_armed,
true /* fRunPreArmChecks */, &_mavlink_log_pub, _vehicle_status_flags,
_arm_requirements, hrt_elapsed_time(&_boot_timestamp),
hrt_elapsed_time(&_boot_timestamp),
arm_disarm_reason_t::transition_to_standby);
}
@@ -2538,7 +2528,6 @@ Commander::run()
/* start geofence result check */
if (_geofence_result_sub.update(&_geofence_result)) {
_arm_requirements.geofence = (_geofence_result.geofence_action != geofence_result_s::GF_ACTION_NONE);
_vehicle_status.geofence_violated = _geofence_result.geofence_violated;
}
@@ -3007,17 +2996,12 @@ Commander::run()
// Evaluate current prearm status (skip during arm -> disarm transition)
if (!actuator_armed_prev.armed && !_arm_state_machine.isArmed() && !_vehicle_status_flags.calibration_enabled) {
perf_begin(_preflight_check_perf);
// skip arm authorization check until actual arming attempt
PreFlightCheck::arm_requirements_t arm_req = _arm_requirements;
arm_req.arm_authorization = false;
_vehicle_status_flags.pre_flight_checks_pass = PreFlightCheck::preflightCheck(nullptr, _vehicle_status,
_vehicle_status_flags,
_vehicle_control_mode,
false, // report_failures
true, // prearm
hrt_elapsed_time(&_boot_timestamp),
_safety.isButtonAvailable(), _safety.isSafetyOff(),
arm_req);
_safety.isButtonAvailable(), _safety.isSafetyOff());
perf_end(_preflight_check_perf);
set_health_flags(subsystem_info_s::SUBSYSTEM_TYPE_PREARM_CHECK, true, true,
@@ -3641,14 +3625,10 @@ void Commander::data_link_check()
if (!_arm_state_machine.isArmed() && !_vehicle_status_flags.calibration_enabled) {
// make sure to report preflight check failures to a connecting GCS
// skip arm authorization check until actual arming attempt
PreFlightCheck::arm_requirements_t arm_req = _arm_requirements;
arm_req.arm_authorization = false;
PreFlightCheck::preflightCheck(&_mavlink_log_pub, _vehicle_status, _vehicle_status_flags, _vehicle_control_mode,
true, // report_failures
false, // prearm
hrt_elapsed_time(&_boot_timestamp),
_safety.isButtonAvailable(), _safety.isSafetyOff(), arm_req);
_safety.isButtonAvailable(), _safety.isSafetyOff());
}
}
-4
View File
@@ -244,9 +244,6 @@ private:
// Engine failure
(ParamInt<px4::params::COM_ACT_FAIL_ACT>) _param_com_actuator_failure_act,
(ParamBool<px4::params::COM_ARM_WO_GPS>) _param_arm_without_gps,
(ParamBool<px4::params::COM_ARM_MIS_REQ>) _param_arm_mission_required,
(ParamBool<px4::params::COM_ARM_AUTH_REQ>) _param_arm_auth_required,
(ParamBool<px4::params::COM_ARM_CHK_ESCS>) _param_escs_checks_required,
(ParamInt<px4::params::COM_FLIGHT_UUID>) _param_flight_uuid,
@@ -295,7 +292,6 @@ private:
static constexpr uint64_t INAIR_RESTART_HOLDOFF_INTERVAL{500_ms};
ArmStateMachine _arm_state_machine{};
PreFlightCheck::arm_requirements_t _arm_requirements{};
hrt_abstime _valid_distance_sensor_time_us{0}; /**< Last time that distance sensor data arrived (usec) */