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/Blimp/mode.cpp
Views: 1798
#include "Blimp.h"12/*3* High level calls to set and update flight modes logic for individual4* flight modes is in control_acro.cpp, control_stabilize.cpp, etc5*/67#include <AP_Vehicle/AP_MultiCopter.h>89/*10constructor for Mode object11*/12Mode::Mode(void) :13g(blimp.g),14g2(blimp.g2),15inertial_nav(blimp.inertial_nav),16ahrs(blimp.ahrs),17motors(blimp.motors),18loiter(blimp.loiter),19channel_right(blimp.channel_right),20channel_front(blimp.channel_front),21channel_up(blimp.channel_up),22channel_yaw(blimp.channel_yaw),23G_Dt(blimp.G_Dt)24{ };2526// return the static controller object corresponding to supplied mode27Mode *Blimp::mode_from_mode_num(const Mode::Number mode)28{29Mode *ret = nullptr;3031switch (mode) {32case Mode::Number::LAND:33ret = &mode_land;34break;35case Mode::Number::MANUAL:36ret = &mode_manual;37break;38case Mode::Number::VELOCITY:39ret = &mode_velocity;40break;41case Mode::Number::LOITER:42ret = &mode_loiter;43break;44case Mode::Number::RTL:45ret = &mode_rtl;46break;47default:48break;49}5051return ret;52}535455// set_mode - change flight mode and perform any necessary initialisation56// optional force parameter used to force the flight mode change (used only first time mode is set)57// returns true if mode was successfully set58// Some modes can always be set successfully but the return state of other flight modes should be checked and the caller should deal with failures appropriately59bool Blimp::set_mode(Mode::Number mode, ModeReason reason)60{6162// return immediately if we are already in the desired mode63if (mode == control_mode) {64control_mode_reason = reason;65return true;66}6768Mode *new_flightmode = mode_from_mode_num((Mode::Number)mode);69if (new_flightmode == nullptr) {70notify_no_such_mode((uint8_t)mode);71return false;72}7374bool ignore_checks = !motors->armed(); // allow switching to any mode if disarmed. We rely on the arming check to perform7576if (!ignore_checks &&77new_flightmode->requires_GPS() &&78!blimp.position_ok()) {79gcs().send_text(MAV_SEVERITY_WARNING, "Mode change failed: %s requires position", new_flightmode->name());80LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));81return false;82}8384// check for valid altitude if old mode did not require it but new one does85// we only want to stop changing modes if it could make things worse86if (!ignore_checks &&87!blimp.ekf_alt_ok() &&88flightmode->has_manual_throttle() &&89!new_flightmode->has_manual_throttle()) {90gcs().send_text(MAV_SEVERITY_WARNING, "Mode change failed: %s need alt estimate", new_flightmode->name());91LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));92return false;93}9495if (!new_flightmode->init(ignore_checks)) {96gcs().send_text(MAV_SEVERITY_WARNING,"Flight mode change failed %s", new_flightmode->name());97LOGGER_WRITE_ERROR(LogErrorSubsystem::FLIGHT_MODE, LogErrorCode(mode));98return false;99}100101// perform any cleanup required by previous flight mode102exit_mode(flightmode, new_flightmode);103104// update flight mode105flightmode = new_flightmode;106control_mode = mode;107control_mode_reason = reason;108#if HAL_LOGGING_ENABLED109logger.Write_Mode((uint8_t)control_mode, reason);110#endif111gcs().send_message(MSG_HEARTBEAT);112113// update notify object114notify_flight_mode();115116// return success117return true;118}119120bool Blimp::set_mode(const uint8_t new_mode, const ModeReason reason)121{122static_assert(sizeof(Mode::Number) == sizeof(new_mode), "The new mode can't be mapped to the vehicles mode number");123#ifdef DISALLOW_GCS_MODE_CHANGE_DURING_RC_FAILSAFE124if (reason == ModeReason::GCS_COMMAND && blimp.failsafe.radio) {125// don't allow mode changes while in radio failsafe126return false;127}128#endif129return blimp.set_mode(static_cast<Mode::Number>(new_mode), reason);130}131132// update_flight_mode - calls the appropriate attitude controllers based on flight mode133// called at 100hz or more134void Blimp::update_flight_mode()135{136flightmode->run();137}138139// exit_mode - high level call to organise cleanup as a flight mode is exited140void Blimp::exit_mode(Mode *&old_flightmode,141Mode *&new_flightmode) {}142143// notify_flight_mode - sets notify object based on current flight mode. Only used for OreoLED notify device144void Blimp::notify_flight_mode()145{146AP_Notify::flags.autopilot_mode = flightmode->is_autopilot();147AP_Notify::flags.flight_mode = (uint8_t)control_mode;148notify.set_flight_mode_str(flightmode->name4());149}150151void Mode::update_navigation()152{153// run autopilot to make high level decisions about control modes154run_autopilot();155}156157// returns desired thrust/acceleration158void Mode::get_pilot_input(Vector3f &pilot, float &yaw)159{160// throttle failsafe check161if (blimp.failsafe.radio || !rc().has_ever_seen_rc_input()) {162pilot.y = 0;163pilot.x = 0;164pilot.z = 0;165yaw = 0;166return;167}168// fetch pilot inputs169pilot.y = channel_right->get_control_in() / float(RC_SCALE);170pilot.x = channel_front->get_control_in() / float(RC_SCALE);171//TODO: need to make this channel_up instead, and then have it .negative. before being sent to pilot.z -> this is "throttle" channel, so higher = up.172pilot.z = -channel_up->get_control_in() / float(RC_SCALE);173yaw = channel_yaw->get_control_in() / float(RC_SCALE);174}175176bool Mode::is_disarmed_or_landed() const177{178if (!motors->armed() || !blimp.ap.auto_armed || blimp.ap.land_complete) {179return true;180}181return false;182}183184bool Mode::set_mode(Mode::Number mode, ModeReason reason)185{186return blimp.set_mode(mode, reason);187}188189GCS_Blimp &Mode::gcs()190{191return blimp.gcs();192}193194195