mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
Copter: added optional AdvancedFailsafe for copter and heli
This commit is contained in:
parent
1181acc4e4
commit
f18e0dadc9
@ -128,6 +128,9 @@ const AP_Scheduler::Task Copter::scheduler_tasks[] = {
|
|||||||
SCHED_TASK(accel_cal_update, 10, 100),
|
SCHED_TASK(accel_cal_update, 10, 100),
|
||||||
#if ADSB_ENABLED == ENABLED
|
#if ADSB_ENABLED == ENABLED
|
||||||
SCHED_TASK(avoidance_adsb_update, 10, 100),
|
SCHED_TASK(avoidance_adsb_update, 10, 100),
|
||||||
|
#endif
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
SCHED_TASK(afs_fs_check, 10, 100),
|
||||||
#endif
|
#endif
|
||||||
SCHED_TASK(terrain_update, 10, 100),
|
SCHED_TASK(terrain_update, 10, 100),
|
||||||
#if EPM_ENABLED == ENABLED
|
#if EPM_ENABLED == ENABLED
|
||||||
|
@ -114,6 +114,10 @@
|
|||||||
#include <AP_Frsky_Telem/AP_Frsky_Telem.h>
|
#include <AP_Frsky_Telem/AP_Frsky_Telem.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
#include "afs_copter.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Local modules
|
// Local modules
|
||||||
#include "Parameters.h"
|
#include "Parameters.h"
|
||||||
#include "avoidance_adsb.h"
|
#include "avoidance_adsb.h"
|
||||||
@ -122,12 +126,17 @@
|
|||||||
#include <SITL/SITL.h>
|
#include <SITL/SITL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Copter : public AP_HAL::HAL::Callbacks {
|
class Copter : public AP_HAL::HAL::Callbacks {
|
||||||
public:
|
public:
|
||||||
friend class GCS_MAVLINK_Copter;
|
friend class GCS_MAVLINK_Copter;
|
||||||
friend class AP_Rally_Copter;
|
friend class AP_Rally_Copter;
|
||||||
friend class Parameters;
|
friend class Parameters;
|
||||||
|
friend class ParametersG2;
|
||||||
friend class AP_Avoidance_Copter;
|
friend class AP_Avoidance_Copter;
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
friend class AP_AdvancedFailsafe_Copter;
|
||||||
|
#endif
|
||||||
|
|
||||||
Copter(void);
|
Copter(void);
|
||||||
|
|
||||||
@ -592,6 +601,9 @@ private:
|
|||||||
// true if we are out of time in our event timeslice
|
// true if we are out of time in our event timeslice
|
||||||
bool gcs_out_of_time;
|
bool gcs_out_of_time;
|
||||||
|
|
||||||
|
// last valid RC input time
|
||||||
|
uint32_t last_radio_update_ms;
|
||||||
|
|
||||||
// Top-level logic
|
// Top-level logic
|
||||||
// setup the var_info table
|
// setup the var_info table
|
||||||
AP_Param param_loader;
|
AP_Param param_loader;
|
||||||
@ -818,6 +830,9 @@ private:
|
|||||||
void autotune_updating_p_up_d_down(float &tune_d, float tune_d_min, float tune_d_step_ratio, float &tune_p, float tune_p_min, float tune_p_max, float tune_p_step_ratio, float target, float measurement_min, float measurement_max);
|
void autotune_updating_p_up_d_down(float &tune_d, float tune_d_min, float tune_d_step_ratio, float &tune_p, float tune_p_min, float tune_p_max, float tune_p_step_ratio, float target, float measurement_min, float measurement_max);
|
||||||
void autotune_twitching_measure_acceleration(float &rate_of_change, float rate_measurement, float &rate_measurement_max);
|
void autotune_twitching_measure_acceleration(float &rate_of_change, float rate_measurement, float &rate_measurement_max);
|
||||||
void avoidance_adsb_update(void);
|
void avoidance_adsb_update(void);
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
void afs_fs_check(void);
|
||||||
|
#endif
|
||||||
bool brake_init(bool ignore_checks);
|
bool brake_init(bool ignore_checks);
|
||||||
void brake_run();
|
void brake_run();
|
||||||
void brake_timeout_to_loiter_ms(uint32_t timeout_ms);
|
void brake_timeout_to_loiter_ms(uint32_t timeout_ms);
|
||||||
|
@ -995,10 +995,26 @@ const AP_Param::GroupInfo ParametersG2::var_info[] = {
|
|||||||
// @User: Advanced
|
// @User: Advanced
|
||||||
AP_GROUPINFO("GND_EFFECT_COMP", 5, ParametersG2, gndeffect_comp_enabled, 0),
|
AP_GROUPINFO("GND_EFFECT_COMP", 5, ParametersG2, gndeffect_comp_enabled, 0),
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
// @Group: AFS_
|
||||||
|
// @Path: ../libraries/AP_AdvancedFailsafe/AP_AdvancedFailsafe.cpp
|
||||||
|
AP_SUBGROUPINFO(afs, "AFS_", 6, ParametersG2, AP_AdvancedFailsafe),
|
||||||
|
#endif
|
||||||
|
|
||||||
AP_GROUPEND
|
AP_GROUPEND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
constructor for g2 object
|
||||||
|
*/
|
||||||
|
ParametersG2::ParametersG2(void)
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLE
|
||||||
|
: afs(copter.mission, copter.barometer, copter.gps, copter.rcmap)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
AP_Param::setup_object_defaults(this, var_info);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is a conversion table from old parameter values to new
|
This is a conversion table from old parameter values to new
|
||||||
|
@ -540,7 +540,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
class ParametersG2 {
|
class ParametersG2 {
|
||||||
public:
|
public:
|
||||||
ParametersG2(void) { AP_Param::setup_object_defaults(this, var_info); }
|
ParametersG2(void);
|
||||||
|
|
||||||
// var_info for holding Parameter information
|
// var_info for holding Parameter information
|
||||||
static const struct AP_Param::GroupInfo var_info[];
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
@ -557,6 +557,11 @@ public:
|
|||||||
|
|
||||||
// ground effect compensation enable/disable
|
// ground effect compensation enable/disable
|
||||||
AP_Int8 gndeffect_comp_enabled;
|
AP_Int8 gndeffect_comp_enabled;
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
// advanced failsafe library
|
||||||
|
AP_AdvancedFailsafe_Copter afs;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const AP_Param::Info var_info[];
|
extern const AP_Param::Info var_info[];
|
||||||
|
74
ArduCopter/afs_copter.cpp
Normal file
74
ArduCopter/afs_copter.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
/*
|
||||||
|
copter specific AP_AdvancedFailsafe class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Copter.h"
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
AP_AdvancedFailsafe_Copter::AP_AdvancedFailsafe_Copter(AP_Mission &_mission, AP_Baro &_baro, const AP_GPS &_gps, const RCMapper &_rcmap) :
|
||||||
|
AP_AdvancedFailsafe(_mission, _baro, _gps, _rcmap)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
setup radio_out values for all channels to termination values
|
||||||
|
*/
|
||||||
|
void AP_AdvancedFailsafe_Copter::terminate_vehicle(void)
|
||||||
|
{
|
||||||
|
// stop motors
|
||||||
|
copter.motors.set_desired_spool_state(AP_Motors::DESIRED_SHUT_DOWN);
|
||||||
|
copter.motors.output();
|
||||||
|
|
||||||
|
// disarm as well
|
||||||
|
copter.init_disarm_motors();
|
||||||
|
|
||||||
|
// and set all aux channels
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_heli_rsc, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_heli_tail_rsc, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_engine_run_enable, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_ignition, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_none, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_limit(RC_Channel_aux::k_manual, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
|
||||||
|
RC_Channel_aux::output_ch_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AP_AdvancedFailsafe_Copter::setup_IO_failsafe(void)
|
||||||
|
{
|
||||||
|
// setup failsafe for all aux channels
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_heli_rsc, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_heli_tail_rsc, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_engine_run_enable, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_ignition, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_none, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
RC_Channel_aux::set_servo_failsafe(RC_Channel_aux::k_manual, RC_Channel::RC_CHANNEL_LIMIT_TRIM);
|
||||||
|
|
||||||
|
#if FRAME_CONFIG != HELI_FRAME
|
||||||
|
// setup AP_Motors outputs for failsafe
|
||||||
|
uint16_t mask = copter.motors.get_motor_mask();
|
||||||
|
hal.rcout->set_failsafe_pwm(mask, copter.motors.get_pwm_output_min());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
return an AFS_MODE for current control mode
|
||||||
|
*/
|
||||||
|
AP_AdvancedFailsafe::control_mode AP_AdvancedFailsafe_Copter::afs_mode(void)
|
||||||
|
{
|
||||||
|
switch (copter.control_mode) {
|
||||||
|
case AUTO:
|
||||||
|
case GUIDED:
|
||||||
|
case RTL:
|
||||||
|
case LAND:
|
||||||
|
return AP_AdvancedFailsafe::AFS_AUTO;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return AP_AdvancedFailsafe::AFS_STABILIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ADVANCED_FAILSAFE
|
45
ArduCopter/afs_copter.h
Normal file
45
ArduCopter/afs_copter.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||||
|
/*
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
advanced failsafe support for copter
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
#include <AP_AdvancedFailsafe/AP_AdvancedFailsafe.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
a plane specific AP_AdvancedFailsafe class
|
||||||
|
*/
|
||||||
|
class AP_AdvancedFailsafe_Copter : public AP_AdvancedFailsafe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AP_AdvancedFailsafe_Copter(AP_Mission &_mission, AP_Baro &_baro, const AP_GPS &_gps, const RCMapper &_rcmap);
|
||||||
|
|
||||||
|
// called to set all outputs to termination state
|
||||||
|
void terminate_vehicle(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// setup failsafe values for if FMU firmware stops running
|
||||||
|
void setup_IO_failsafe(void);
|
||||||
|
|
||||||
|
// return the AFS mapped control mode
|
||||||
|
enum control_mode afs_mode(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ADVANCED_FAILSAFE
|
||||||
|
|
@ -668,3 +668,7 @@
|
|||||||
#ifndef FRSKY_TELEM_ENABLED
|
#ifndef FRSKY_TELEM_ENABLED
|
||||||
# define FRSKY_TELEM_ENABLED ENABLED
|
# define FRSKY_TELEM_ENABLED ENABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ADVANCED_FAILSAFE
|
||||||
|
# define ADVANCED_FAILSAFE DISABLE
|
||||||
|
#endif
|
||||||
|
@ -71,3 +71,15 @@ void Copter::failsafe_check()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
/*
|
||||||
|
check for AFS failsafe check
|
||||||
|
*/
|
||||||
|
void Copter::afs_fs_check(void)
|
||||||
|
{
|
||||||
|
// perform AFS failsafe checks
|
||||||
|
g2.afs.check(failsafe.last_heartbeat_ms, fence.get_breaches() != 0, last_radio_update_ms);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -267,6 +267,16 @@ void Copter::init_disarm_motors()
|
|||||||
// motors_output - send output to motors library which will adjust and send to ESCs and servos
|
// motors_output - send output to motors library which will adjust and send to ESCs and servos
|
||||||
void Copter::motors_output()
|
void Copter::motors_output()
|
||||||
{
|
{
|
||||||
|
#if ADVANCED_FAILSAFE == ENABLED
|
||||||
|
// this is to allow the failsafe module to deliberately crash
|
||||||
|
// the vehicle. Only used in extreme circumstances to meet the
|
||||||
|
// OBC rules
|
||||||
|
if (g2.afs.should_crash_vehicle()) {
|
||||||
|
g2.afs.terminate_vehicle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update arming delay state
|
// Update arming delay state
|
||||||
if (ap.in_arming_delay && (!motors.armed() || millis()-arm_time_ms > ARMING_DELAY_SEC*1.0e3f || control_mode == THROW)) {
|
if (ap.in_arming_delay && (!motors.armed() || millis()-arm_time_ms > ARMING_DELAY_SEC*1.0e3f || control_mode == THROW)) {
|
||||||
ap.in_arming_delay = false;
|
ap.in_arming_delay = false;
|
||||||
|
@ -97,7 +97,6 @@ void Copter::enable_motor_output()
|
|||||||
|
|
||||||
void Copter::read_radio()
|
void Copter::read_radio()
|
||||||
{
|
{
|
||||||
static uint32_t last_update_ms = 0;
|
|
||||||
uint32_t tnow_ms = millis();
|
uint32_t tnow_ms = millis();
|
||||||
|
|
||||||
if (hal.rcin->new_input()) {
|
if (hal.rcin->new_input()) {
|
||||||
@ -118,11 +117,11 @@ void Copter::read_radio()
|
|||||||
// pass pilot input through to motors (used to allow wiggling servos while disarmed on heli, single, coax copters)
|
// pass pilot input through to motors (used to allow wiggling servos while disarmed on heli, single, coax copters)
|
||||||
radio_passthrough_to_motors();
|
radio_passthrough_to_motors();
|
||||||
|
|
||||||
float dt = (tnow_ms - last_update_ms)*1.0e-3f;
|
float dt = (tnow_ms - last_radio_update_ms)*1.0e-3f;
|
||||||
rc_throttle_control_in_filter.apply(g.rc_3.get_control_in(), dt);
|
rc_throttle_control_in_filter.apply(g.rc_3.get_control_in(), dt);
|
||||||
last_update_ms = tnow_ms;
|
last_radio_update_ms = tnow_ms;
|
||||||
}else{
|
}else{
|
||||||
uint32_t elapsed = tnow_ms - last_update_ms;
|
uint32_t elapsed = tnow_ms - last_radio_update_ms;
|
||||||
// turn on throttle failsafe if no update from the RC Radio for 500ms or 2000ms if we are using RC_OVERRIDE
|
// turn on throttle failsafe if no update from the RC Radio for 500ms or 2000ms if we are using RC_OVERRIDE
|
||||||
if (((!failsafe.rc_override_active && (elapsed >= FS_RADIO_TIMEOUT_MS)) || (failsafe.rc_override_active && (elapsed >= FS_RADIO_RC_OVERRIDE_TIMEOUT_MS))) &&
|
if (((!failsafe.rc_override_active && (elapsed >= FS_RADIO_TIMEOUT_MS)) || (failsafe.rc_override_active && (elapsed >= FS_RADIO_RC_OVERRIDE_TIMEOUT_MS))) &&
|
||||||
(g.failsafe_throttle && (ap.rc_receiver_present||motors.armed()) && !failsafe.radio)) {
|
(g.failsafe_throttle && (ap.rc_receiver_present||motors.armed()) && !failsafe.radio)) {
|
||||||
|
@ -29,6 +29,7 @@ def build(bld):
|
|||||||
'AP_Relay',
|
'AP_Relay',
|
||||||
'AP_ServoRelayEvents',
|
'AP_ServoRelayEvents',
|
||||||
'AP_Avoidance',
|
'AP_Avoidance',
|
||||||
|
'AP_AdvancedFailsafe'
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user