mirror of
https://github.com/ArduPilot/ardupilot.git
synced 2026-10-06 19:00:27 +08:00
The ARMDISARM_UNUSED to ARMDISARM rewrite of stored RCn_OPTION values had no annotation: it calls set_and_save() directly rather than going through an AP_Param::convert_* helper, so an audit anchored on those helpers did not see it. Blimp has no release tags, so the release cannot be established by content the way it is for the other vehicles. The annotation names the cycle it was added in instead: Sep-2021, which is 4.2. No functional change.
274 lines
7.9 KiB
C++
274 lines
7.9 KiB
C++
#include "Blimp.h"
|
|
|
|
/*****************************************************************************
|
|
* The init_ardupilot function processes everything we need for an in - air restart
|
|
* We will determine later if we are actually on the ground and process a
|
|
* ground start in that case.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
static void failsafe_check_static()
|
|
{
|
|
blimp.failsafe_check();
|
|
}
|
|
|
|
void Blimp::init_ardupilot()
|
|
{
|
|
// initialise notify system
|
|
notify.init();
|
|
notify_flight_mode();
|
|
|
|
// initialise battery monitor
|
|
battery.init();
|
|
|
|
#if AP_RSSI_ENABLED
|
|
// Init RSSI
|
|
rssi.init();
|
|
#endif
|
|
|
|
barometer.init();
|
|
|
|
// setup telem slots with serial ports
|
|
gcs().setup_uarts();
|
|
|
|
init_rc_in(); // sets up rc channels from radio
|
|
|
|
// allocate the motors class
|
|
allocate_motors();
|
|
loiter = NEW_NOTHROW Loiter(blimp.scheduler.get_loop_rate_hz());
|
|
if (loiter == nullptr) {
|
|
AP_BoardConfig::allocation_error("Loiter");
|
|
}
|
|
AP_Param::load_object_from_eeprom(loiter, Loiter::var_info);
|
|
// reload lines from the defaults file that may now be accessible
|
|
AP_Param::reload_defaults_file(true);
|
|
// param count could have changed
|
|
AP_Param::invalidate_count();
|
|
|
|
// initialise rc channels including setting mode
|
|
// PARAMETER_CONVERSION - Added: Sep-2021 for ArduPilot-4.2
|
|
rc().convert_options(RC_Channel::AUX_FUNC::ARMDISARM_UNUSED, RC_Channel::AUX_FUNC::ARMDISARM);
|
|
rc().init();
|
|
|
|
// sets up motors and output to escs
|
|
init_rc_out();
|
|
|
|
|
|
// motors initialised so parameters can be sent
|
|
ap.initialised_params = true;
|
|
|
|
#if AP_RELAY_ENABLED
|
|
relay.init();
|
|
#endif
|
|
|
|
/*
|
|
* setup the 'main loop is dead' check. Note that this relies on
|
|
* the RC library being initialised.
|
|
*/
|
|
hal.scheduler->register_timer_failsafe(failsafe_check_static, 1000);
|
|
|
|
// Do GPS init
|
|
gps.set_log_gps_bit(MASK_LOG_GPS);
|
|
gps.init();
|
|
|
|
AP::compass().set_log_bit(MASK_LOG_COMPASS);
|
|
AP::compass().init();
|
|
|
|
// read Baro pressure at ground
|
|
//-----------------------------
|
|
barometer.set_log_baro_bit(MASK_LOG_IMU);
|
|
barometer.calibrate();
|
|
mode_auto.mission.init();
|
|
|
|
#if HAL_LOGGING_ENABLED
|
|
// initialise AP_Logger library
|
|
logger.setVehicle_Startup_Writer(FUNCTOR_BIND(&blimp, &Blimp::Log_Write_Vehicle_Startup_Messages, void));
|
|
#endif
|
|
|
|
startup_INS_ground();
|
|
|
|
ins.set_log_raw_bit(MASK_LOG_IMU_RAW);
|
|
|
|
// setup fin output
|
|
motors->setup_finsmotors();
|
|
|
|
// enable output to motors
|
|
if (arming.rc_calibration_checks(true)) {
|
|
enable_motor_output();
|
|
}
|
|
|
|
//Initialise velocity filters
|
|
vel_x_filter.init(scheduler.get_loop_rate_hz(), motors->freq_hz, 0.5f, 15.0f);
|
|
vel_y_filter.init(scheduler.get_loop_rate_hz(), motors->freq_hz, 0.5f, 15.0f);
|
|
vel_z_filter.init(scheduler.get_loop_rate_hz(), motors->freq_hz, 1.0f, 15.0f);
|
|
vel_yaw_filter.init(scheduler.get_loop_rate_hz(), motors->freq_hz, 5.0f, 15.0f);
|
|
|
|
// attempt to switch to MANUAL, if this fails then switch to Land
|
|
if (!set_mode((enum Mode::Number)g.initial_mode.get(), ModeReason::INITIALISED)) {
|
|
// set mode to MANUAL will trigger mode change notification to pilot
|
|
set_mode(Mode::Number::MANUAL, ModeReason::UNAVAILABLE);
|
|
} else {
|
|
// alert pilot to mode change
|
|
AP_Notify::events.failsafe_mode_change = 1;
|
|
}
|
|
|
|
// flag that initialisation has completed
|
|
ap.initialised = true;
|
|
}
|
|
|
|
|
|
//******************************************************************************
|
|
//This function does all the calibrations, etc. that we need during a ground start
|
|
//******************************************************************************
|
|
void Blimp::startup_INS_ground()
|
|
{
|
|
// initialise ahrs (may push imu calibration into the mpu6000 if using that device).
|
|
ahrs.init();
|
|
// No Blimp option, but AHRS requirements are similar to Copter's, so that is what we use.
|
|
ahrs.set_vehicle_class(AP_AHRS::VehicleClass::COPTER);
|
|
|
|
// Warm up and calibrate gyro offsets
|
|
ins.init(scheduler.get_loop_rate_hz());
|
|
|
|
// reset ahrs including gyro bias
|
|
ahrs.reset();
|
|
}
|
|
|
|
// position_ok - returns true if the horizontal absolute position is ok and home position is set
|
|
bool Blimp::position_ok() const
|
|
{
|
|
// return false if ekf failsafe has triggered
|
|
if (failsafe.ekf) {
|
|
return false;
|
|
}
|
|
|
|
// check ekf position estimate
|
|
return (ekf_has_absolute_position() || ekf_has_relative_position());
|
|
}
|
|
|
|
// ekf_has_absolute_position - returns true if the EKF can provide an absolute WGS-84 position estimate
|
|
bool Blimp::ekf_has_absolute_position() const
|
|
{
|
|
if (!ahrs.have_inertial_nav()) {
|
|
// do not allow navigation with dcm position
|
|
return false;
|
|
}
|
|
|
|
// if disarmed we accept a predicted horizontal position
|
|
if (!motors->armed()) {
|
|
if (ahrs.has_status(AP_AHRS::Status::HORIZ_POS_ABS)) {
|
|
return true;
|
|
}
|
|
if (ahrs.has_status(AP_AHRS::Status::PRED_HORIZ_POS_ABS)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
// once armed we require a good absolute position and EKF must not be in const_pos_mode
|
|
if (ahrs.has_status(AP_AHRS::Status::CONST_POS_MODE)) {
|
|
return false;
|
|
}
|
|
return ahrs.has_status(AP_AHRS::Status::HORIZ_POS_ABS);
|
|
}
|
|
|
|
// ekf_has_relative_position - returns true if the EKF can provide a position estimate relative to it's starting position
|
|
bool Blimp::ekf_has_relative_position() const
|
|
{
|
|
// return immediately if EKF not used
|
|
if (!ahrs.have_inertial_nav()) {
|
|
return false;
|
|
}
|
|
|
|
// return immediately if neither optflow nor visual odometry is enabled
|
|
bool enabled = false;
|
|
if (!enabled) {
|
|
return false;
|
|
}
|
|
|
|
// if disarmed we accept a predicted horizontal relative position
|
|
if (!motors->armed()) {
|
|
return ahrs.has_status(AP_AHRS::Status::PRED_HORIZ_POS_REL);
|
|
}
|
|
if (ahrs.has_status(AP_AHRS::Status::CONST_POS_MODE)) {
|
|
return false;
|
|
}
|
|
return ahrs.has_status(AP_AHRS::Status::HORIZ_POS_REL);
|
|
}
|
|
|
|
// returns true if the ekf has a good altitude estimate (required for modes which do AltHold)
|
|
bool Blimp::ekf_alt_ok() const
|
|
{
|
|
if (!ahrs.have_inertial_nav()) {
|
|
// do not allow alt control with only dcm
|
|
return false;
|
|
}
|
|
|
|
// require both vertical velocity and position
|
|
if (!ahrs.has_status(AP_AHRS::Status::VERT_VEL)) {
|
|
return false;
|
|
}
|
|
if (!ahrs.has_status(AP_AHRS::Status::VERT_POS)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// update_auto_armed - update status of auto_armed flag
|
|
void Blimp::update_auto_armed()
|
|
{
|
|
// disarm checks
|
|
if (ap.auto_armed) {
|
|
// if motors are disarmed, auto_armed should also be false
|
|
if (!motors->armed()) {
|
|
set_auto_armed(false);
|
|
return;
|
|
}
|
|
// if in a manual flight mode and throttle is zero, auto-armed should become false
|
|
if (flightmode->has_manual_throttle() && ap.throttle_zero && !failsafe.radio) {
|
|
set_auto_armed(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if HAL_LOGGING_ENABLED
|
|
/*
|
|
should we log a message type now?
|
|
*/
|
|
bool Blimp::should_log(uint32_t mask)
|
|
{
|
|
ap.logging_started = logger.logging_started();
|
|
return logger.should_log(mask);
|
|
}
|
|
#endif
|
|
|
|
// return MAV_TYPE
|
|
MAV_TYPE Blimp::get_frame_mav_type()
|
|
{
|
|
return MAV_TYPE_AIRSHIP;
|
|
}
|
|
|
|
// return string corresponding to frame_class
|
|
const char* Blimp::get_frame_string()
|
|
{
|
|
return motors->get_frame_string();
|
|
}
|
|
|
|
/*
|
|
allocate the motors class
|
|
*/
|
|
void Blimp::allocate_motors(void)
|
|
{
|
|
motors = NEW_NOTHROW Fins(blimp.scheduler.get_loop_rate_hz());
|
|
if (motors == nullptr) {
|
|
AP_BoardConfig::allocation_error("FRAME_CLASS=%u", (unsigned)g2.frame_class.get());
|
|
}
|
|
AP_Param::load_object_from_eeprom(motors, Fins::var_info);
|
|
|
|
// reload lines from the defaults file that may now be accessible
|
|
AP_Param::reload_defaults_file(true);
|
|
|
|
// param count could have changed
|
|
AP_Param::invalidate_count();
|
|
}
|