#pragma once
#include <AP_HAL/AP_HAL_Boards.h>
#include <AP_HAL/Semaphores.h>
#include <AP_Param/AP_Param.h>
#include <AP_GPS/AP_GPS_config.h>
#include <AP_BoardConfig/AP_BoardConfig_config.h>
#include "AP_Arming_config.h"
#include "AP_InertialSensor/AP_InertialSensor_config.h"
#include "AP_Proximity/AP_Proximity_config.h"
class AP_Arming {
public:
AP_Arming();
CLASS_NO_COPY(AP_Arming);
static AP_Arming *get_singleton();
__INITFUNC__ void init(void);
void update();
enum class Check {
BARO = (1U << 1),
COMPASS = (1U << 2),
GPS = (1U << 3),
INS = (1U << 4),
PARAMETERS = (1U << 5),
RC = (1U << 6),
VOLTAGE = (1U << 7),
BATTERY = (1U << 8),
AIRSPEED = (1U << 9),
LOGGING = (1U << 10),
SWITCH = (1U << 11),
GPS_CONFIG = (1U << 12),
SYSTEM = (1U << 13),
MISSION = (1U << 14),
RANGEFINDER = (1U << 15),
CAMERA = (1U << 16),
AUX_AUTH = (1U << 17),
VISION = (1U << 18),
FFT = (1U << 19),
OSD = (1U << 20),
CHECK_LAST = (1U << 21),
};
enum class Method {
RUDDER = 0,
MAVLINK = 1,
AUXSWITCH = 2,
MOTORTEST = 3,
SCRIPTING = 4,
TERMINATION = 5,
CPUFAILSAFE = 6,
BATTERYFAILSAFE = 7,
SOLOPAUSEWHENLANDED = 8,
AFS = 9,
ADSBCOLLISIONACTION = 10,
PARACHUTE_RELEASE = 11,
CRASH = 12,
LANDED = 13,
MISSIONEXIT = 14,
FENCEBREACH = 15,
RADIOFAILSAFE = 16,
DISARMDELAY = 17,
GCSFAILSAFE = 18,
TERRRAINFAILSAFE = 19,
FAILSAFE_ACTION_TERMINATE = 20,
TERRAINFAILSAFE = 21,
MOTORDETECTDONE = 22,
BADFLOWOFCONTROL = 23,
EKFFAILSAFE = 24,
GCS_FAILSAFE_SURFACEFAILED = 25,
GCS_FAILSAFE_HOLDFAILED = 26,
TAKEOFFTIMEOUT = 27,
AUTOLANDED = 28,
PILOT_INPUT_FAILSAFE = 29,
TOYMODELANDTHROTTLE = 30,
TOYMODELANDFORCE = 31,
LANDING = 32,
DEADRECKON_FAILSAFE = 33,
BLACKBOX = 34,
DDS = 35,
AUTO_ARM_ONCE = 36,
TURTLE_MODE = 37,
TOYMODE = 38,
UNKNOWN = 100,
};
enum class Required {
NO = 0,
YES_MIN_PWM = 1,
YES_ZERO_PWM = 2,
YES_AUTO_ARM_MIN_PWM = 3,
YES_AUTO_ARM_ZERO_PWM = 4,
};
Required arming_required() const;
virtual bool arm(AP_Arming::Method method, bool do_arming_checks=true);
virtual bool arm_force(AP_Arming::Method method) { return arm(method, false); }
virtual bool disarm(AP_Arming::Method method, bool do_disarm_checks=true);
bool is_armed() const;
bool is_armed_and_safety_off() const;
uint64_t arm_time_us() const { return is_armed() ? last_arm_time_us : 0; }
uint32_t get_enabled_checks() const;
bool all_checks_enabled() const;
bool should_skip_all_checks() const { return get_enabled_checks() == 0; }
virtual bool pre_arm_checks(bool report);
bool get_last_prearm_checks_result() const { return last_prearm_checks_result; }
virtual bool arm_checks(AP_Arming::Method method);
uint16_t compass_magfield_expected() const;
enum class RudderArming {
IS_DISABLED = 0,
ARMONLY = 1,
ARMDISARM = 2
};
RudderArming get_rudder_arming_type() const { return (RudderArming)_rudder_arming.get(); }
#if AP_ARMING_AUX_AUTH_ENABLED
bool get_aux_auth_id(uint8_t& auth_id);
void set_aux_auth_passed(uint8_t auth_id);
void set_aux_auth_failed(uint8_t auth_id, const char* fail_msg);
void reset_all_aux_auths();
#endif
static const struct AP_Param::GroupInfo var_info[];
Method last_disarm_method() const { return _last_disarm_method; }
Method last_arm_method() const { return _last_arm_method; }
enum class Option : int32_t {
DISABLE_PREARM_DISPLAY = (1U << 0),
DISABLE_STATUSTEXT_ON_STATE_CHANGE = (1U << 1),
SKIP_IMU_CONSISTENCY_ICE_RUNNING = (1U << 2),
};
bool option_enabled(Option option) const {
return (_arming_options & uint32_t(option)) != 0;
}
void send_arm_disarm_statustext(const char *string) const;
static bool method_is_GCS(Method method) {
return (method == Method::MAVLINK || method == Method::DDS);
}
enum class RequireLocation : uint8_t {
NO = 0,
YES = 1,
};
protected:
AP_Enum<Required> require;
AP_Int32 checks_to_skip;
AP_Float accel_error_threshold;
AP_Int8 _rudder_arming;
AP_Int32 _required_mission_items;
AP_Int32 _arming_options;
AP_Int16 magfield_error_threshold;
AP_Enum<RequireLocation> require_location;
bool armed;
uint32_t last_accel_pass_ms;
uint32_t last_gyro_pass_ms;
virtual bool barometer_checks(bool report);
bool airspeed_checks(bool report);
bool logging_checks(bool report);
#if AP_INERTIALSENSOR_ENABLED
virtual bool ins_checks(bool report);
#endif
bool compass_checks(bool report);
virtual bool gps_checks(bool report);
bool battery_checks(bool report);
bool hardware_safety_check(bool report);
virtual bool board_voltage_checks(bool report);
virtual bool rc_calibration_checks(bool report);
bool rc_in_calibration_check(bool report);
bool rc_arm_checks(AP_Arming::Method method);
bool manual_transmitter_checks(bool report);
virtual bool mission_checks(bool report);
bool terrain_checks(bool report) const;
virtual bool terrain_database_required() const;
bool rangefinder_checks(bool report);
bool fence_checks(bool report);
#if HAL_HAVE_IMU_HEATER
bool heater_min_temperature_checks(bool report);
#endif
bool camera_checks(bool display_failure);
bool osd_checks(bool display_failure) const;
bool mount_checks(bool display_failure) const;
#if AP_ARMING_AUX_AUTH_ENABLED
bool aux_auth_checks(bool display_failure);
#endif
bool generator_checks(bool report) const;
bool opendroneid_checks(bool display_failure);
bool serial_protocol_checks(bool display_failure);
bool estop_checks(bool display_failure);
#if AP_ARMING_CRASHDUMP_ACK_ENABLED
bool crashdump_checks(bool report);
#endif
virtual bool system_checks(bool report);
bool can_checks(bool report);
bool fettec_checks(bool display_failure) const;
#if HAL_PROXIMITY_ENABLED
virtual bool proximity_checks(bool report) const;
#endif
bool servo_checks(bool report) const;
bool rc_checks_copter_sub(bool display_failure, const class RC_Channel *channels[4]) const;
bool visodom_checks(bool report) const;
bool disarm_switch_checks(bool report) const;
virtual bool mandatory_checks(bool report);
bool check_enabled(const AP_Arming::Check check) const;
void check_failed(const AP_Arming::Check check, bool report, const char *fmt, ...) const FMT_PRINTF(4, 5);
void check_failed(bool report, const char *fmt, ...) const FMT_PRINTF(3, 4);
void Log_Write_Arm(bool forced, AP_Arming::Method method);
void Log_Write_Disarm(bool forced, AP_Arming::Method method);
private:
static AP_Arming *_singleton;
#if AP_INERTIALSENSOR_ENABLED
bool ins_accels_consistent(const class AP_InertialSensor &ins);
bool ins_gyros_consistent(const class AP_InertialSensor &ins);
#endif
void check_forced_logging(const AP_Arming::Method method);
enum MIS_ITEM_CHECK {
MIS_ITEM_CHECK_LAND = (1 << 0),
MIS_ITEM_CHECK_VTOL_LAND = (1 << 1),
MIS_ITEM_CHECK_DO_LAND_START = (1 << 2),
MIS_ITEM_CHECK_TAKEOFF = (1 << 3),
MIS_ITEM_CHECK_VTOL_TAKEOFF = (1 << 4),
MIS_ITEM_CHECK_RALLY = (1 << 5),
MIS_ITEM_CHECK_RETURN_TO_LAUNCH = (1 << 6),
MIS_ITEM_CHECK_MAX
};
#if AP_ARMING_AUX_AUTH_ENABLED
static const uint8_t aux_auth_count_max = 3;
static const uint8_t aux_auth_str_len = 42;
enum class AuxAuthStates : uint8_t {
NO_RESPONSE = 0,
AUTH_FAILED,
AUTH_PASSED
} aux_auth_state[aux_auth_count_max] = {};
uint8_t aux_auth_count;
uint8_t aux_auth_fail_msg_source;
char* aux_auth_fail_msg;
bool aux_auth_error;
HAL_Semaphore aux_auth_sem;
#endif
Method _last_disarm_method = Method::UNKNOWN;
Method _last_arm_method = Method::UNKNOWN;
uint64_t last_arm_time_us;
uint32_t last_prearm_display_ms;
bool running_arming_checks;
bool last_prearm_checks_result;
bool report_immediately;
void update_arm_gpio();
#if !AP_GPS_BLENDED_ENABLED
bool blending_auto_switch_checks(bool report);
#endif
#if AP_ARMING_CRASHDUMP_ACK_ENABLED
struct CrashDump {
void check_reset();
AP_Int8 acked;
} crashdump_ack;
#endif
};
namespace AP {
AP_Arming &arming();
};