diff --git a/ArduPlane/Plane.h b/ArduPlane/Plane.h index ba7a32096c..b1c6182430 100644 --- a/ArduPlane/Plane.h +++ b/ArduPlane/Plane.h @@ -1100,6 +1100,9 @@ private: void update_soaring(); #endif + // RC_Channel.cpp + bool emergency_landing; + // vehicle specific waypoint info helpers bool get_wp_distance_m(float &distance) const override; bool get_wp_bearing_deg(float &bearing) const override; diff --git a/ArduPlane/RC_Channel.cpp b/ArduPlane/RC_Channel.cpp index 93540d7f9e..8a3dcf6df8 100644 --- a/ArduPlane/RC_Channel.cpp +++ b/ArduPlane/RC_Channel.cpp @@ -164,6 +164,7 @@ void RC_Channel_Plane::init_aux_function(const RC_Channel::aux_func_t ch_option, case AUX_FUNC::ARMDISARM_AIRMODE: #endif case AUX_FUNC::TRIM_TO_CURRENT_SERVO_RC: + case AUX_FUNC::EMERGENCY_LANDING_EN: break; case AUX_FUNC::SOARING: @@ -354,6 +355,19 @@ case AUX_FUNC::ARSPD_CALIBRATE: } break; + case AUX_FUNC::EMERGENCY_LANDING_EN: + switch (ch_flag) { + case AuxSwitchPos::HIGH: + plane.emergency_landing = true; + break; + case AuxSwitchPos::MIDDLE: + break; + case AuxSwitchPos::LOW: + plane.emergency_landing = false; + break; + } + break; + default: return RC_Channel::do_aux_function(ch_option, ch_flag); diff --git a/ArduPlane/events.cpp b/ArduPlane/events.cpp index bc4a500825..ae6a60e550 100644 --- a/ArduPlane/events.cpp +++ b/ArduPlane/events.cpp @@ -33,6 +33,10 @@ void Plane::failsafe_short_on_event(enum failsafe_state fstype, ModeReason reaso case Mode::Number::TRAINING: failsafe.saved_mode_number = control_mode->mode_number(); failsafe.saved_mode_set = true; + if(plane.emergency_landing) { + set_mode(mode_fbwa, reason); // emergency landing switch overrides normal action to allow out of range landing + break; + } if(g.fs_action_short == FS_ACTION_SHORT_FBWA) { set_mode(mode_fbwa, reason); } else if (g.fs_action_short == FS_ACTION_SHORT_FBWB) { @@ -116,6 +120,10 @@ void Plane::failsafe_long_on_event(enum failsafe_state fstype, ModeReason reason case Mode::Number::CIRCLE: case Mode::Number::LOITER: case Mode::Number::THERMAL: + if(plane.emergency_landing) { + set_mode(mode_fbwa, reason); // emergency landing switch overrides normal action to allow out of range landing + break; + } if(g.fs_action_long == FS_ACTION_LONG_PARACHUTE) { #if PARACHUTE == ENABLED parachute_release();