Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/ArduPlane/events.cpp
Views: 1798
#include "Plane.h"12// returns true if the vehicle is in landing sequence. Intended only3// for use in failsafe code.4bool Plane::failsafe_in_landing_sequence() const5{6if (flight_stage == AP_FixedWing::FlightStage::LAND) {7return true;8}9#if HAL_QUADPLANE_ENABLED10if (quadplane.in_vtol_land_sequence()) {11return true;12}13#endif14if (mission.get_in_landing_sequence_flag()) {15return true;16}17return false;18}1920void Plane::failsafe_short_on_event(enum failsafe_state fstype, ModeReason reason)21{22// This is how to handle a short loss of control signal failsafe.23failsafe.state = fstype;24failsafe.short_timer_ms = millis();25failsafe.saved_mode_number = control_mode->mode_number();26switch (control_mode->mode_number())27{28case Mode::Number::MANUAL:29case Mode::Number::STABILIZE:30case Mode::Number::ACRO:31case Mode::Number::FLY_BY_WIRE_A:32case Mode::Number::AUTOTUNE:33case Mode::Number::FLY_BY_WIRE_B:34case Mode::Number::CRUISE:35case Mode::Number::TRAINING:36if(plane.emergency_landing) {37set_mode(mode_fbwa, reason); // emergency landing switch overrides normal action to allow out of range landing38break;39}40if(g.fs_action_short == FS_ACTION_SHORT_FBWA) {41set_mode(mode_fbwa, reason);42} else if (g.fs_action_short == FS_ACTION_SHORT_FBWB) {43set_mode(mode_fbwb, reason);44} else {45set_mode(mode_circle, reason); // circle if action = 0 or 146}47break;4849#if HAL_QUADPLANE_ENABLED50case Mode::Number::QSTABILIZE:51case Mode::Number::QLOITER:52case Mode::Number::QHOVER:53#if QAUTOTUNE_ENABLED54case Mode::Number::QAUTOTUNE:55#endif56case Mode::Number::QACRO:57if (quadplane.option_is_set(QuadPlane::OPTION::FS_RTL)) {58set_mode(mode_rtl, reason);59} else if (quadplane.option_is_set(QuadPlane::OPTION::FS_QRTL)) {60set_mode(mode_qrtl, reason);61} else {62set_mode(mode_qland, reason);63}64break;65#endif // HAL_QUADPLANE_ENABLED6667case Mode::Number::AUTO:68#if MODE_AUTOLAND_ENABLED69case Mode::Number::AUTOLAND:70#endif71{72if (failsafe_in_landing_sequence()) {73// don't failsafe in a landing sequence74break;75}76FALLTHROUGH;77}78case Mode::Number::AVOID_ADSB:79case Mode::Number::GUIDED:80case Mode::Number::LOITER:81case Mode::Number::THERMAL:82if (g.fs_action_short != FS_ACTION_SHORT_BESTGUESS) { // if acton = 0(BESTGUESS) this group of modes take no action83failsafe.saved_mode_number = control_mode->mode_number();84if (g.fs_action_short == FS_ACTION_SHORT_FBWA) {85set_mode(mode_fbwa, reason);86} else if (g.fs_action_short == FS_ACTION_SHORT_FBWB) {87set_mode(mode_fbwb, reason);88} else {89set_mode(mode_circle, reason);90}91}92break;93case Mode::Number::CIRCLE: // these modes never take any short failsafe action and continue94case Mode::Number::TAKEOFF:95case Mode::Number::RTL:96#if HAL_QUADPLANE_ENABLED97case Mode::Number::QLAND:98case Mode::Number::QRTL:99case Mode::Number::LOITER_ALT_QLAND:100#endif101case Mode::Number::INITIALISING:102break;103}104if (failsafe.saved_mode_number != control_mode->mode_number()) {105gcs().send_text(MAV_SEVERITY_WARNING, "RC Short Failsafe: switched to %s", control_mode->name());106} else {107gcs().send_text(MAV_SEVERITY_WARNING, "RC Short Failsafe On");108}109}110111void Plane::failsafe_long_on_event(enum failsafe_state fstype, ModeReason reason)112{113114// This is how to handle a long loss of control signal failsafe.115// If the GCS is locked up we allow control to revert to RC116RC_Channels::clear_overrides();117failsafe.state = fstype;118switch (control_mode->mode_number())119{120case Mode::Number::MANUAL:121case Mode::Number::STABILIZE:122case Mode::Number::ACRO:123case Mode::Number::FLY_BY_WIRE_A:124case Mode::Number::AUTOTUNE:125case Mode::Number::FLY_BY_WIRE_B:126case Mode::Number::CRUISE:127case Mode::Number::TRAINING:128case Mode::Number::CIRCLE:129case Mode::Number::LOITER:130case Mode::Number::THERMAL:131case Mode::Number::TAKEOFF:132if (plane.flight_stage == AP_FixedWing::FlightStage::TAKEOFF && !(g.fs_action_long == FS_ACTION_LONG_GLIDE || g.fs_action_long == FS_ACTION_LONG_PARACHUTE)) {133// don't failsafe if in inital climb of TAKEOFF mode and FS action is not parachute or glide134// long failsafe will be re-called if still in fs after initial climb135long_failsafe_pending = true;136break;137}138139if(plane.emergency_landing) {140set_mode(mode_fbwa, reason); // emergency landing switch overrides normal action to allow out of range landing141break;142}143if(g.fs_action_long == FS_ACTION_LONG_PARACHUTE) {144#if HAL_PARACHUTE_ENABLED145parachute_release();146#endif147} else if (g.fs_action_long == FS_ACTION_LONG_GLIDE) {148set_mode(mode_fbwa, reason);149} else if (g.fs_action_long == FS_ACTION_LONG_AUTO) {150set_mode(mode_auto, reason);151#if MODE_AUTOLAND_ENABLED152} else if (g.fs_action_long == FS_ACTION_LONG_AUTOLAND) {153if (!set_mode(mode_autoland, reason)) {154set_mode(mode_rtl, reason);155}156#endif157} else {158set_mode(mode_rtl, reason);159}160break;161162#if HAL_QUADPLANE_ENABLED163case Mode::Number::QSTABILIZE:164case Mode::Number::QHOVER:165case Mode::Number::QLOITER:166case Mode::Number::QACRO:167#if QAUTOTUNE_ENABLED168case Mode::Number::QAUTOTUNE:169#endif170if (quadplane.option_is_set(QuadPlane::OPTION::FS_RTL)) {171set_mode(mode_rtl, reason);172} else if (quadplane.option_is_set(QuadPlane::OPTION::FS_QRTL)) {173set_mode(mode_qrtl, reason);174} else {175set_mode(mode_qland, reason);176}177break;178#endif // HAL_QUADPLANE_ENABLED179180case Mode::Number::AUTO:181if (failsafe_in_landing_sequence()) {182// don't failsafe in a landing sequence183break;184}185186#if HAL_QUADPLANE_ENABLED187if (quadplane.in_vtol_takeoff()) {188set_mode(mode_qland, reason);189// QLAND if in VTOL takeoff190break;191}192#endif193FALLTHROUGH;194195case Mode::Number::AVOID_ADSB:196case Mode::Number::GUIDED:197198if(g.fs_action_long == FS_ACTION_LONG_PARACHUTE) {199#if HAL_PARACHUTE_ENABLED200parachute_release();201#endif202} else if (g.fs_action_long == FS_ACTION_LONG_GLIDE) {203set_mode(mode_fbwa, reason);204} else if (g.fs_action_long == FS_ACTION_LONG_AUTO) {205set_mode(mode_auto, reason);206#if MODE_AUTOLAND_ENABLED207} else if (g.fs_action_long == FS_ACTION_LONG_AUTOLAND) {208if (!set_mode(mode_autoland, reason)) {209set_mode(mode_rtl, reason);210}211#endif212} else if (g.fs_action_long == FS_ACTION_LONG_RTL) {213set_mode(mode_rtl, reason);214}215break;216case Mode::Number::RTL:217if (g.fs_action_long == FS_ACTION_LONG_AUTO) {218set_mode(mode_auto, reason);219#if MODE_AUTOLAND_ENABLED220} else if (g.fs_action_long == FS_ACTION_LONG_AUTOLAND) {221set_mode(mode_autoland, reason);222#endif223}224break;225#if HAL_QUADPLANE_ENABLED226case Mode::Number::QLAND:227case Mode::Number::QRTL:228case Mode::Number::LOITER_ALT_QLAND:229#endif230case Mode::Number::INITIALISING:231#if MODE_AUTOLAND_ENABLED232case Mode::Number::AUTOLAND:233#endif234break;235}236gcs().send_text(MAV_SEVERITY_WARNING, "%s Failsafe On: %s", (reason == ModeReason:: GCS_FAILSAFE) ? "GCS" : "RC Long", control_mode->name());237}238239void Plane::failsafe_short_off_event(ModeReason reason)240{241// We're back in radio contact242gcs().send_text(MAV_SEVERITY_WARNING, "Short Failsafe Cleared");243failsafe.state = FAILSAFE_NONE;244// restore entry mode if desired but check that our current mode is still due to failsafe245if (control_mode_reason == ModeReason::RADIO_FAILSAFE) {246set_mode_by_number(failsafe.saved_mode_number, ModeReason::RADIO_FAILSAFE_RECOVERY);247gcs().send_text(MAV_SEVERITY_INFO,"Flight mode %s restored",control_mode->name());248}249}250251void Plane::failsafe_long_off_event(ModeReason reason)252{253long_failsafe_pending = false;254// We're back in radio contact with RC or GCS255if (reason == ModeReason:: GCS_FAILSAFE) {256gcs().send_text(MAV_SEVERITY_WARNING, "GCS Failsafe Off");257}258else {259gcs().send_text(MAV_SEVERITY_WARNING, "RC Long Failsafe Cleared");260}261failsafe.state = FAILSAFE_NONE;262}263264void Plane::handle_battery_failsafe(const char *type_str, const int8_t action)265{266switch ((Failsafe_Action)action) {267#if HAL_QUADPLANE_ENABLED268case Failsafe_Action_Loiter_alt_QLand:269if (quadplane.available()) {270plane.set_mode(mode_loiter_qland, ModeReason::BATTERY_FAILSAFE);271break;272}273FALLTHROUGH;274275case Failsafe_Action_QLand:276if (quadplane.available()) {277plane.set_mode(mode_qland, ModeReason::BATTERY_FAILSAFE);278break;279}280FALLTHROUGH;281#endif // HAL_QUADPLANE_ENABLED282case Failsafe_Action_Land: {283bool already_landing = flight_stage == AP_FixedWing::FlightStage::LAND;284#if HAL_QUADPLANE_ENABLED285if (control_mode == &mode_qland || control_mode == &mode_loiter_qland) {286already_landing = true;287}288#endif289if (!already_landing && plane.have_position) {290// never stop a landing if we were already committed291if (plane.mission.is_best_land_sequence(plane.current_loc)) {292// continue mission as it will reach a landing in less distance293plane.mission.set_in_landing_sequence_flag(true);294break;295}296if (plane.mission.jump_to_landing_sequence(plane.current_loc)) {297plane.set_mode(mode_auto, ModeReason::BATTERY_FAILSAFE);298break;299}300}301FALLTHROUGH;302}303case Failsafe_Action_RTL: {304bool already_landing = flight_stage == AP_FixedWing::FlightStage::LAND;305#if HAL_QUADPLANE_ENABLED306if (control_mode == &mode_qland || control_mode == &mode_loiter_qland ||307quadplane.in_vtol_land_sequence()) {308already_landing = true;309}310#endif311if (!already_landing) {312// never stop a landing if we were already committed313if ((g.rtl_autoland == RtlAutoland::RTL_IMMEDIATE_DO_LAND_START) && plane.have_position && plane.mission.is_best_land_sequence(plane.current_loc)) {314// continue mission as it will reach a landing in less distance315plane.mission.set_in_landing_sequence_flag(true);316break;317}318set_mode(mode_rtl, ModeReason::BATTERY_FAILSAFE);319aparm.throttle_cruise.load();320}321break;322}323324case Failsafe_Action_Terminate:325#if AP_ADVANCEDFAILSAFE_ENABLED326char battery_type_str[17];327snprintf(battery_type_str, 17, "%s battery", type_str);328afs.gcs_terminate(true, battery_type_str);329#else330arming.disarm(AP_Arming::Method::FAILSAFE_ACTION_TERMINATE);331#endif332break;333334case Failsafe_Action_Parachute:335#if HAL_PARACHUTE_ENABLED336parachute_release();337#endif338break;339340case Failsafe_Action_None:341// don't actually do anything, however we should still flag the system as having hit a failsafe342// and ensure all appropriate flags are going off to the user343break;344}345}346347348