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/ArduCopter/mode.h
Views: 1798
#pragma once12#include "Copter.h"3#include <AP_Math/chirp.h>4#include <AP_ExternalControl/AP_ExternalControl_config.h> // TODO why is this needed if Copter.h includes this56#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED7#include "afs_copter.h"8#endif910class Parameters;11class ParametersG2;1213class GCS_Copter;1415// object shared by both Guided and Auto for takeoff.16// position controller controls vehicle but the user can control the yaw.17class _AutoTakeoff {18public:19void run();20void start(float complete_alt_cm, bool terrain_alt);21bool get_completion_pos(Vector3p& pos_neu_cm);2223bool complete; // true when takeoff is complete2425private:26// altitude above-ekf-origin below which auto takeoff does not control horizontal position27bool no_nav_active;28float no_nav_alt_cm;2930// auto takeoff variables31float complete_alt_cm; // completion altitude expressed in cm above ekf origin or above terrain (depending upon auto_takeoff_terrain_alt)32bool terrain_alt; // true if altitudes are above terrain33Vector3p complete_pos; // target takeoff position as offset from ekf origin in cm34};3536#if AC_PAYLOAD_PLACE_ENABLED37class PayloadPlace {38public:39void run();40void start_descent();41bool verify();4243enum class State : uint8_t {44FlyToLocation,45Descent_Start,46Descent,47Release,48Releasing,49Delay,50Ascent_Start,51Ascent,52Done,53};5455// these are set by the Mission code:56State state = State::Descent_Start; // records state of payload place57float descent_max_cm;5859private:6061uint32_t descent_established_time_ms; // milliseconds62uint32_t place_start_time_ms; // milliseconds63float descent_thrust_level;64float descent_start_altitude_cm;65float descent_speed_cms;66};67#endif6869class Mode {70friend class PayloadPlace;7172public:7374// Auto Pilot Modes enumeration75enum class Number : uint8_t {76STABILIZE = 0, // manual airframe angle with manual throttle77ACRO = 1, // manual body-frame angular rate with manual throttle78ALT_HOLD = 2, // manual airframe angle with automatic throttle79AUTO = 3, // fully automatic waypoint control using mission commands80GUIDED = 4, // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands81LOITER = 5, // automatic horizontal acceleration with automatic throttle82RTL = 6, // automatic return to launching point83CIRCLE = 7, // automatic circular flight with automatic throttle84LAND = 9, // automatic landing with horizontal position control85DRIFT = 11, // semi-autonomous position, yaw and throttle control86SPORT = 13, // manual earth-frame angular rate control with manual throttle87FLIP = 14, // automatically flip the vehicle on the roll axis88AUTOTUNE = 15, // automatically tune the vehicle's roll and pitch gains89POSHOLD = 16, // automatic position hold with manual override, with automatic throttle90BRAKE = 17, // full-brake using inertial/GPS system, no pilot input91THROW = 18, // throw to launch mode using inertial/GPS system, no pilot input92AVOID_ADSB = 19, // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft93GUIDED_NOGPS = 20, // guided mode but only accepts attitude and altitude94SMART_RTL = 21, // SMART_RTL returns to home by retracing its steps95FLOWHOLD = 22, // FLOWHOLD holds position with optical flow without rangefinder96FOLLOW = 23, // follow attempts to follow another vehicle or ground station97ZIGZAG = 24, // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B98SYSTEMID = 25, // System ID mode produces automated system identification signals in the controllers99AUTOROTATE = 26, // Autonomous autorotation100AUTO_RTL = 27, // Auto RTL, this is not a true mode, AUTO will report as this mode if entered to perform a DO_LAND_START Landing sequence101TURTLE = 28, // Flip over after crash102103// Mode number 30 reserved for "offboard" for external/lua control.104105// Mode number 127 reserved for the "drone show mode" in the Skybrush106// fork at https://github.com/skybrush-io/ardupilot107};108109// constructor110Mode(void);111112// do not allow copying113CLASS_NO_COPY(Mode);114115friend class _AutoTakeoff;116117// returns a unique number specific to this mode118virtual Number mode_number() const = 0;119120// child classes should override these methods121virtual bool init(bool ignore_checks) {122return true;123}124virtual void exit() {};125virtual void run() = 0;126virtual bool requires_GPS() const = 0;127virtual bool has_manual_throttle() const = 0;128virtual bool allows_arming(AP_Arming::Method method) const = 0;129virtual bool is_autopilot() const { return false; }130virtual bool has_user_takeoff(bool must_navigate) const { return false; }131virtual bool in_guided_mode() const { return false; }132virtual bool logs_attitude() const { return false; }133virtual bool allows_save_trim() const { return false; }134virtual bool allows_autotune() const { return false; }135virtual bool allows_flip() const { return false; }136virtual bool crash_check_enabled() const { return true; }137138#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED139// Return the type of this mode for use by advanced failsafe140virtual AP_AdvancedFailsafe_Copter::control_mode afs_mode() const { return AP_AdvancedFailsafe_Copter::control_mode::AFS_STABILIZED; }141#endif142143// Return true if the throttle high arming check can be skipped when arming from GCS or Scripting144virtual bool allows_GCS_or_SCR_arming_with_throttle_high() const { return false; }145146#if FRAME_CONFIG == HELI_FRAME147virtual bool allows_inverted() const { return false; };148#endif149150// return a string for this flightmode151virtual const char *name() const = 0;152virtual const char *name4() const = 0;153154bool do_user_takeoff(float takeoff_alt_cm, bool must_navigate);155virtual bool is_taking_off() const;156static void takeoff_stop() { takeoff.stop(); }157158virtual bool is_landing() const { return false; }159160// mode requires terrain to be present to be functional161virtual bool requires_terrain_failsafe() const { return false; }162163// functions for reporting to GCS164virtual bool get_wp(Location &loc) const { return false; };165virtual int32_t wp_bearing() const { return 0; }166virtual uint32_t wp_distance() const { return 0; }167virtual float crosstrack_error() const { return 0.0f;}168169// functions to support MAV_CMD_DO_CHANGE_SPEED170virtual bool set_speed_xy(float speed_xy_cms) {return false;}171virtual bool set_speed_up(float speed_xy_cms) {return false;}172virtual bool set_speed_down(float speed_xy_cms) {return false;}173174int32_t get_alt_above_ground_cm(void);175176// pilot input processing177void get_pilot_desired_lean_angles(float &roll_out_cd, float &pitch_out_cd, float angle_max_cd, float angle_limit_cd) const;178Vector2f get_pilot_desired_velocity(float vel_max) const;179float get_pilot_desired_yaw_rate() const;180float get_pilot_desired_throttle() const;181182// returns climb target_rate reduced to avoid obstacles and183// altitude fence184float get_avoidance_adjusted_climbrate(float target_rate);185186// send output to the motors, can be overridden by subclasses187virtual void output_to_motors();188189// returns true if pilot's yaw input should be used to adjust vehicle's heading190virtual bool use_pilot_yaw() const {return true; }191192// pause and resume a mode193virtual bool pause() { return false; };194virtual bool resume() { return false; };195196// handle situations where the vehicle is on the ground waiting for takeoff197void make_safe_ground_handling(bool force_throttle_unlimited = false);198199// true if weathervaning is allowed in the current mode200#if WEATHERVANE_ENABLED201virtual bool allows_weathervaning() const { return false; }202#endif203204protected:205206// helper functions207bool is_disarmed_or_landed() const;208void zero_throttle_and_relax_ac(bool spool_up = false);209void zero_throttle_and_hold_attitude();210211// Return stopping point as a location with above origin alt frame212Location get_stopping_point() const;213214// functions to control normal landing. pause_descent is true if vehicle should not descend215void land_run_horizontal_control();216void land_run_vertical_control(bool pause_descent = false);217void land_run_horiz_and_vert_control(bool pause_descent = false) {218land_run_horizontal_control();219land_run_vertical_control(pause_descent);220}221222#if AC_PAYLOAD_PLACE_ENABLED223// payload place flight behaviour:224static PayloadPlace payload_place;225#endif226227// run normal or precision landing (if enabled)228// pause_descent is true if vehicle should not descend229void land_run_normal_or_precland(bool pause_descent = false);230231#if AC_PRECLAND_ENABLED232// Go towards a position commanded by prec land state machine in order to retry landing233// The passed in location is expected to be NED and in meters234void precland_retry_position(const Vector3f &retry_pos);235236// Run precland statemachine. This function should be called from any mode that wants to do precision landing.237// This handles everything from prec landing, to prec landing failures, to retries and failsafe measures238void precland_run();239#endif240241// return expected input throttle setting to hover:242virtual float throttle_hover() const;243244// Alt_Hold based flight mode states used in Alt_Hold, Loiter, and Sport245enum class AltHoldModeState {246MotorStopped,247Takeoff,248Landed_Ground_Idle,249Landed_Pre_Takeoff,250Flying251};252AltHoldModeState get_alt_hold_state(float target_climb_rate_cms);253254// convenience references to avoid code churn in conversion:255Parameters &g;256ParametersG2 &g2;257AC_WPNav *&wp_nav;258AC_Loiter *&loiter_nav;259AC_PosControl *&pos_control;260AP_InertialNav &inertial_nav;261AP_AHRS &ahrs;262AC_AttitudeControl *&attitude_control;263MOTOR_CLASS *&motors;264RC_Channel *&channel_roll;265RC_Channel *&channel_pitch;266RC_Channel *&channel_throttle;267RC_Channel *&channel_yaw;268float &G_Dt;269270// note that we support two entirely different automatic takeoffs:271272// "user-takeoff", which is available in modes such as ALT_HOLD273// (see has_user_takeoff method). "user-takeoff" is a simple274// reach-altitude-based-on-pilot-input-or-parameter routine.275276// "auto-takeoff" is used by both Guided and Auto, and is277// basically waypoint navigation with pilot yaw permitted.278279// user-takeoff support; takeoff state is shared across all mode instances280class _TakeOff {281public:282void start(float alt_cm);283void stop();284void do_pilot_takeoff(float& pilot_climb_rate);285bool triggered(float target_climb_rate) const;286287bool running() const { return _running; }288private:289bool _running;290float take_off_start_alt;291float take_off_complete_alt;292};293294static _TakeOff takeoff;295296virtual bool do_user_takeoff_start(float takeoff_alt_cm);297298static _AutoTakeoff auto_takeoff;299300public:301// Navigation Yaw control302class AutoYaw {303304public:305306// Autopilot Yaw Mode enumeration307enum class Mode {308HOLD = 0, // hold zero yaw rate309LOOK_AT_NEXT_WP = 1, // point towards next waypoint (no pilot input accepted)310ROI = 2, // point towards a location held in roi (no pilot input accepted)311FIXED = 3, // point towards a particular angle (no pilot input accepted)312LOOK_AHEAD = 4, // point in the direction the copter is moving313RESETTOARMEDYAW = 5, // point towards heading at time motors were armed314ANGLE_RATE = 6, // turn at a specified rate from a starting angle315RATE = 7, // turn at a specified rate (held in auto_yaw_rate)316CIRCLE = 8, // use AC_Circle's provided yaw (used during Loiter-Turns commands)317PILOT_RATE = 9, // target rate from pilot stick318WEATHERVANE = 10, // yaw into wind319};320321// mode(): current method of determining desired yaw:322Mode mode() const { return _mode; }323void set_mode_to_default(bool rtl);324void set_mode(Mode new_mode);325Mode default_mode(bool rtl) const;326327void set_rate(float new_rate_cds);328329// set_roi(...): set a "look at" location:330void set_roi(const Location &roi_location);331332void set_fixed_yaw(float angle_deg,333float turn_rate_dps,334int8_t direction,335bool relative_angle);336337void set_yaw_angle_rate(float yaw_angle_d, float yaw_rate_ds);338339void set_yaw_angle_offset(const float yaw_angle_offset_d);340341bool reached_fixed_yaw_target();342343#if WEATHERVANE_ENABLED344void update_weathervane(const int16_t pilot_yaw_cds);345#endif346347AC_AttitudeControl::HeadingCommand get_heading();348349private:350351// yaw_cd(): main product of AutoYaw; the heading:352float yaw_cd();353354// rate_cds(): desired yaw rate in centidegrees/second:355float rate_cds();356357// returns a yaw in degrees, direction of vehicle travel:358float look_ahead_yaw();359360float roi_yaw() const;361362// auto flight mode's yaw mode363Mode _mode = Mode::LOOK_AT_NEXT_WP;364Mode _last_mode;365366// Yaw will point at this location if mode is set to Mode::ROI367Vector3f roi;368369// yaw used for YAW_FIXED yaw_mode370float _fixed_yaw_offset_cd;371372// Deg/s we should turn373float _fixed_yaw_slewrate_cds;374375// time of the last yaw update376uint32_t _last_update_ms;377378// heading when in yaw_look_ahead_yaw379float _look_ahead_yaw;380381// turn rate (in cds) when auto_yaw_mode is set to AUTO_YAW_RATE382float _yaw_angle_cd;383float _yaw_rate_cds;384float _pilot_yaw_rate_cds;385};386static AutoYaw auto_yaw;387388// pass-through functions to reduce code churn on conversion;389// these are candidates for moving into the Mode base390// class.391float get_pilot_desired_climb_rate(float throttle_control);392float get_non_takeoff_throttle(void);393void update_simple_mode(void);394bool set_mode(Mode::Number mode, ModeReason reason);395void set_land_complete(bool b);396GCS_Copter &gcs();397uint16_t get_pilot_speed_dn(void);398// end pass-through functions399};400401402#if MODE_ACRO_ENABLED403class ModeAcro : public Mode {404405public:406// inherit constructor407using Mode::Mode;408Number mode_number() const override { return Number::ACRO; }409410enum class Trainer {411OFF = 0,412LEVELING = 1,413LIMITED = 2,414};415416enum class AcroOptions {417AIR_MODE = 1 << 0,418RATE_LOOP_ONLY = 1 << 1,419};420421virtual void run() override;422423bool requires_GPS() const override { return false; }424bool has_manual_throttle() const override { return true; }425bool allows_arming(AP_Arming::Method method) const override { return true; };426bool is_autopilot() const override { return false; }427bool init(bool ignore_checks) override;428void exit() override;429// whether an air-mode aux switch has been toggled430void air_mode_aux_changed();431bool allows_save_trim() const override { return true; }432bool allows_flip() const override { return true; }433bool crash_check_enabled() const override { return false; }434435protected:436437const char *name() const override { return "ACRO"; }438const char *name4() const override { return "ACRO"; }439440// get_pilot_desired_angle_rates - transform pilot's normalised roll pitch and yaw input into a desired lean angle rates441// inputs are -1 to 1 and the function returns desired angle rates in centi-degrees-per-second442void get_pilot_desired_angle_rates(float roll_in, float pitch_in, float yaw_in, float &roll_out, float &pitch_out, float &yaw_out);443444float throttle_hover() const override;445446private:447bool disable_air_mode_reset;448};449#endif450451#if FRAME_CONFIG == HELI_FRAME452class ModeAcro_Heli : public ModeAcro {453454public:455// inherit constructor456using ModeAcro::Mode;457458bool init(bool ignore_checks) override;459void run() override;460void virtual_flybar( float &roll_out, float &pitch_out, float &yaw_out, float pitch_leak, float roll_leak);461462protected:463private:464};465#endif466467468class ModeAltHold : public Mode {469470public:471// inherit constructor472using Mode::Mode;473Number mode_number() const override { return Number::ALT_HOLD; }474475bool init(bool ignore_checks) override;476void run() override;477478bool requires_GPS() const override { return false; }479bool has_manual_throttle() const override { return false; }480bool allows_arming(AP_Arming::Method method) const override { return true; };481bool is_autopilot() const override { return false; }482bool has_user_takeoff(bool must_navigate) const override {483return !must_navigate;484}485bool allows_autotune() const override { return true; }486bool allows_flip() const override { return true; }487#if FRAME_CONFIG == HELI_FRAME488bool allows_inverted() const override { return true; };489#endif490protected:491492const char *name() const override { return "ALT_HOLD"; }493const char *name4() const override { return "ALTH"; }494495private:496497};498499class ModeAuto : public Mode {500501public:502friend class PayloadPlace; // in case wp_run is accidentally required503504// inherit constructor505using Mode::Mode;506Number mode_number() const override { return auto_RTL? Number::AUTO_RTL : Number::AUTO; }507508bool init(bool ignore_checks) override;509void exit() override;510void run() override;511512bool requires_GPS() const override;513bool has_manual_throttle() const override { return false; }514bool allows_arming(AP_Arming::Method method) const override;515bool is_autopilot() const override { return true; }516bool in_guided_mode() const override { return _mode == SubMode::NAVGUIDED || _mode == SubMode::NAV_SCRIPT_TIME; }517#if FRAME_CONFIG == HELI_FRAME518bool allows_inverted() const override { return true; };519#endif520521#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED522// Return the type of this mode for use by advanced failsafe523AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }524#endif525526// Return true if the throttle high arming check can be skipped when arming from GCS or Scripting527bool allows_GCS_or_SCR_arming_with_throttle_high() const override { return true; }528529// Auto modes530enum class SubMode : uint8_t {531TAKEOFF,532WP,533LAND,534RTL,535CIRCLE_MOVE_TO_EDGE,536CIRCLE,537NAVGUIDED,538LOITER,539LOITER_TO_ALT,540#if AP_MISSION_NAV_PAYLOAD_PLACE_ENABLED && AC_PAYLOAD_PLACE_ENABLED541NAV_PAYLOAD_PLACE,542#endif543NAV_SCRIPT_TIME,544NAV_ATTITUDE_TIME,545};546547// set submode. returns true on success, false on failure548void set_submode(SubMode new_submode);549550// pause continue in auto mode551bool pause() override;552bool resume() override;553bool paused() const;554555bool loiter_start();556void rtl_start();557void takeoff_start(const Location& dest_loc);558bool wp_start(const Location& dest_loc);559void land_start();560void circle_movetoedge_start(const Location &circle_center, float radius_m, bool ccw_turn);561void circle_start();562void nav_guided_start();563564bool is_landing() const override;565566bool is_taking_off() const override;567bool use_pilot_yaw() const override;568569bool set_speed_xy(float speed_xy_cms) override;570bool set_speed_up(float speed_up_cms) override;571bool set_speed_down(float speed_down_cms) override;572573bool requires_terrain_failsafe() const override { return true; }574575void payload_place_start();576577// for GCS_MAVLink to call:578bool do_guided(const AP_Mission::Mission_Command& cmd);579580// Go straight to landing sequence via DO_LAND_START, if succeeds pretend to be Auto RTL mode581bool jump_to_landing_sequence_auto_RTL(ModeReason reason);582583// Join mission after DO_RETURN_PATH_START waypoint, if succeeds pretend to be Auto RTL mode584bool return_path_start_auto_RTL(ModeReason reason);585586// Try join return path else do land start587bool return_path_or_jump_to_landing_sequence_auto_RTL(ModeReason reason);588589// lua accessors for nav script time support590bool nav_script_time(uint16_t &id, uint8_t &cmd, float &arg1, float &arg2, int16_t &arg3, int16_t &arg4);591void nav_script_time_done(uint16_t id);592593AP_Mission mission{594FUNCTOR_BIND_MEMBER(&ModeAuto::start_command, bool, const AP_Mission::Mission_Command &),595FUNCTOR_BIND_MEMBER(&ModeAuto::verify_command, bool, const AP_Mission::Mission_Command &),596FUNCTOR_BIND_MEMBER(&ModeAuto::exit_mission, void)};597598// Mission change detector599AP_Mission_ChangeDetector mis_change_detector;600601// true if weathervaning is allowed in auto602#if WEATHERVANE_ENABLED603bool allows_weathervaning(void) const override;604#endif605606protected:607608const char *name() const override { return auto_RTL? "AUTO RTL" : "AUTO"; }609const char *name4() const override { return auto_RTL? "ARTL" : "AUTO"; }610611uint32_t wp_distance() const override;612int32_t wp_bearing() const override;613float crosstrack_error() const override { return wp_nav->crosstrack_error();}614bool get_wp(Location &loc) const override;615616private:617618enum class Option : int32_t {619AllowArming = (1 << 0U),620AllowTakeOffWithoutRaisingThrottle = (1 << 1U),621IgnorePilotYaw = (1 << 2U),622AllowWeatherVaning = (1 << 7U),623};624bool option_is_enabled(Option option) const;625626// Enter auto rtl pseudo mode627bool enter_auto_rtl(ModeReason reason);628629bool start_command(const AP_Mission::Mission_Command& cmd);630bool verify_command(const AP_Mission::Mission_Command& cmd);631void exit_mission();632633bool check_for_mission_change(); // detect external changes to mission634635void takeoff_run();636void wp_run();637void land_run();638void rtl_run();639void circle_run();640void nav_guided_run();641void loiter_run();642void loiter_to_alt_run();643void nav_attitude_time_run();644645// return the Location portion of a command. If the command's lat and lon and/or alt are zero the default_loc's lat,lon and/or alt are returned instead646Location loc_from_cmd(const AP_Mission::Mission_Command& cmd, const Location& default_loc) const;647648SubMode _mode = SubMode::TAKEOFF; // controls which auto controller is run649650bool shift_alt_to_current_alt(Location& target_loc) const;651652// subtract position controller offsets from target location653// should be used when the location will be used as a target for the position controller654void subtract_pos_offsets(Location& target_loc) const;655656void do_takeoff(const AP_Mission::Mission_Command& cmd);657void do_nav_wp(const AP_Mission::Mission_Command& cmd);658bool set_next_wp(const AP_Mission::Mission_Command& current_cmd, const Location &default_loc);659void do_land(const AP_Mission::Mission_Command& cmd);660void do_loiter_unlimited(const AP_Mission::Mission_Command& cmd);661void do_circle(const AP_Mission::Mission_Command& cmd);662void do_loiter_time(const AP_Mission::Mission_Command& cmd);663void do_loiter_to_alt(const AP_Mission::Mission_Command& cmd);664void do_spline_wp(const AP_Mission::Mission_Command& cmd);665void get_spline_from_cmd(const AP_Mission::Mission_Command& cmd, const Location& default_loc, Location& dest_loc, Location& next_dest_loc, bool& next_dest_loc_is_spline);666#if AC_NAV_GUIDED667void do_nav_guided_enable(const AP_Mission::Mission_Command& cmd);668void do_guided_limits(const AP_Mission::Mission_Command& cmd);669#endif670void do_nav_delay(const AP_Mission::Mission_Command& cmd);671void do_wait_delay(const AP_Mission::Mission_Command& cmd);672void do_within_distance(const AP_Mission::Mission_Command& cmd);673void do_yaw(const AP_Mission::Mission_Command& cmd);674void do_change_speed(const AP_Mission::Mission_Command& cmd);675void do_set_home(const AP_Mission::Mission_Command& cmd);676void do_roi(const AP_Mission::Mission_Command& cmd);677void do_mount_control(const AP_Mission::Mission_Command& cmd);678#if HAL_PARACHUTE_ENABLED679void do_parachute(const AP_Mission::Mission_Command& cmd);680#endif681#if AP_WINCH_ENABLED682void do_winch(const AP_Mission::Mission_Command& cmd);683#endif684void do_payload_place(const AP_Mission::Mission_Command& cmd);685void do_RTL(void);686#if AP_SCRIPTING_ENABLED687void do_nav_script_time(const AP_Mission::Mission_Command& cmd);688#endif689void do_nav_attitude_time(const AP_Mission::Mission_Command& cmd);690691bool verify_takeoff();692bool verify_land();693bool verify_payload_place();694bool verify_loiter_unlimited();695bool verify_loiter_time(const AP_Mission::Mission_Command& cmd);696bool verify_loiter_to_alt() const;697bool verify_RTL();698bool verify_wait_delay();699bool verify_within_distance();700bool verify_yaw();701bool verify_nav_wp(const AP_Mission::Mission_Command& cmd);702bool verify_circle(const AP_Mission::Mission_Command& cmd);703bool verify_spline_wp(const AP_Mission::Mission_Command& cmd);704#if AC_NAV_GUIDED705bool verify_nav_guided_enable(const AP_Mission::Mission_Command& cmd);706#endif707bool verify_nav_delay(const AP_Mission::Mission_Command& cmd);708#if AP_SCRIPTING_ENABLED709bool verify_nav_script_time();710#endif711bool verify_nav_attitude_time(const AP_Mission::Mission_Command& cmd);712713// Loiter control714uint16_t loiter_time_max; // How long we should stay in Loiter Mode for mission scripting (time in seconds)715uint32_t loiter_time; // How long have we been loitering - The start time in millis716717struct {718bool reached_destination_xy : 1;719bool loiter_start_done : 1;720bool reached_alt : 1;721float alt_error_cm;722int32_t alt;723} loiter_to_alt;724725// Delay the next navigation command726uint32_t nav_delay_time_max_ms; // used for delaying the navigation commands (eg land,takeoff etc.)727uint32_t nav_delay_time_start_ms;728729// Delay Mission Scripting Command730int32_t condition_value; // used in condition commands (eg delay, change alt, etc.)731uint32_t condition_start;732733// Land within Auto state734enum class State {735FlyToLocation = 0,736Descending = 1737};738State state = State::FlyToLocation;739740bool waiting_to_start; // true if waiting for vehicle to be armed or EKF origin before starting mission741742// True if we have entered AUTO to perform a DO_LAND_START landing sequence and we should report as AUTO RTL mode743bool auto_RTL;744745#if AP_SCRIPTING_ENABLED746// nav_script_time command variables747struct {748bool done; // true once lua script indicates it has completed749uint16_t id; // unique id to avoid race conditions between commands and lua scripts750uint32_t start_ms; // system time nav_script_time command was received (used for timeout)751uint8_t command; // command number provided by mission command752uint8_t timeout_s; // timeout (in seconds) provided by mission command753float arg1; // 1st argument provided by mission command754float arg2; // 2nd argument provided by mission command755int16_t arg3; // 3rd argument provided by mission command756int16_t arg4; // 4th argument provided by mission command757} nav_scripting;758#endif759760// nav attitude time command variables761struct {762int16_t roll_deg; // target roll angle in degrees. provided by mission command763int8_t pitch_deg; // target pitch angle in degrees. provided by mission command764int16_t yaw_deg; // target yaw angle in degrees. provided by mission command765float climb_rate; // climb rate in m/s. provided by mission command766uint32_t start_ms; // system time that nav attitude time command was received (used for timeout)767} nav_attitude_time;768769// desired speeds770struct {771float xy; // desired speed horizontally in m/s. 0 if unset772float up; // desired speed upwards in m/s. 0 if unset773float down; // desired speed downwards in m/s. 0 if unset774} desired_speed_override;775};776777#if AUTOTUNE_ENABLED778/*779wrapper class for AC_AutoTune780*/781782#if FRAME_CONFIG == HELI_FRAME783class AutoTune : public AC_AutoTune_Heli784#else785class AutoTune : public AC_AutoTune_Multi786#endif787{788public:789bool init() override;790void run() override;791792protected:793bool position_ok() override;794float get_pilot_desired_climb_rate_cms(void) const override;795void get_pilot_desired_rp_yrate_cd(float &roll_cd, float &pitch_cd, float &yaw_rate_cds) override;796void init_z_limits() override;797#if HAL_LOGGING_ENABLED798void log_pids() override;799#endif800};801802class ModeAutoTune : public Mode {803804// ParametersG2 sets a pointer within our autotune object:805friend class ParametersG2;806807public:808// inherit constructor809using Mode::Mode;810Number mode_number() const override { return Number::AUTOTUNE; }811812bool init(bool ignore_checks) override;813void exit() override;814void run() override;815816bool requires_GPS() const override { return false; }817bool has_manual_throttle() const override { return false; }818bool allows_arming(AP_Arming::Method method) const override { return false; }819bool is_autopilot() const override { return false; }820821AutoTune autotune;822823protected:824825const char *name() const override { return "AUTOTUNE"; }826const char *name4() const override { return "ATUN"; }827};828#endif829830831class ModeBrake : public Mode {832833public:834// inherit constructor835using Mode::Mode;836Number mode_number() const override { return Number::BRAKE; }837838bool init(bool ignore_checks) override;839void run() override;840841bool requires_GPS() const override { return true; }842bool has_manual_throttle() const override { return false; }843bool allows_arming(AP_Arming::Method method) const override { return false; };844bool is_autopilot() const override { return false; }845846void timeout_to_loiter_ms(uint32_t timeout_ms);847848protected:849850const char *name() const override { return "BRAKE"; }851const char *name4() const override { return "BRAK"; }852853private:854855uint32_t _timeout_start;856uint32_t _timeout_ms;857858};859860861class ModeCircle : public Mode {862863public:864// inherit constructor865using Mode::Mode;866Number mode_number() const override { return Number::CIRCLE; }867868bool init(bool ignore_checks) override;869void run() override;870871bool requires_GPS() const override { return true; }872bool has_manual_throttle() const override { return false; }873bool allows_arming(AP_Arming::Method method) const override { return false; };874bool is_autopilot() const override { return true; }875876protected:877878const char *name() const override { return "CIRCLE"; }879const char *name4() const override { return "CIRC"; }880881uint32_t wp_distance() const override;882int32_t wp_bearing() const override;883884private:885886// Circle887bool speed_changing = false; // true when the roll stick is being held to facilitate stopping at 0 rate888};889890891class ModeDrift : public Mode {892893public:894// inherit constructor895using Mode::Mode;896Number mode_number() const override { return Number::DRIFT; }897898bool init(bool ignore_checks) override;899void run() override;900901bool requires_GPS() const override { return true; }902bool has_manual_throttle() const override { return false; }903bool allows_arming(AP_Arming::Method method) const override { return true; };904bool is_autopilot() const override { return false; }905906protected:907908const char *name() const override { return "DRIFT"; }909const char *name4() const override { return "DRIF"; }910911private:912913float get_throttle_assist(float velz, float pilot_throttle_scaled);914915};916917918class ModeFlip : public Mode {919920public:921// inherit constructor922using Mode::Mode;923Number mode_number() const override { return Number::FLIP; }924925bool init(bool ignore_checks) override;926void run() override;927928bool requires_GPS() const override { return false; }929bool has_manual_throttle() const override { return false; }930bool allows_arming(AP_Arming::Method method) const override { return false; };931bool is_autopilot() const override { return false; }932bool crash_check_enabled() const override { return false; }933934protected:935936const char *name() const override { return "FLIP"; }937const char *name4() const override { return "FLIP"; }938939private:940941// Flip942Vector3f orig_attitude; // original vehicle attitude before flip943944enum class FlipState : uint8_t {945Start,946Roll,947Pitch_A,948Pitch_B,949Recover,950Abandon951};952FlipState _state; // current state of flip953Mode::Number orig_control_mode; // flight mode when flip was initated954uint32_t start_time_ms; // time since flip began955int8_t roll_dir; // roll direction (-1 = roll left, 1 = roll right)956int8_t pitch_dir; // pitch direction (-1 = pitch forward, 1 = pitch back)957};958959960#if MODE_FLOWHOLD_ENABLED961/*962class to support FLOWHOLD mode, which is a position hold mode using963optical flow directly, avoiding the need for a rangefinder964*/965966class ModeFlowHold : public Mode {967public:968// need a constructor for parameters969ModeFlowHold(void);970Number mode_number() const override { return Number::FLOWHOLD; }971972bool init(bool ignore_checks) override;973void run(void) override;974975bool requires_GPS() const override { return false; }976bool has_manual_throttle() const override { return false; }977bool allows_arming(AP_Arming::Method method) const override { return true; };978bool is_autopilot() const override { return false; }979bool has_user_takeoff(bool must_navigate) const override {980return !must_navigate;981}982bool allows_flip() const override { return true; }983984static const struct AP_Param::GroupInfo var_info[];985986protected:987const char *name() const override { return "FLOWHOLD"; }988const char *name4() const override { return "FHLD"; }989990private:991992// FlowHold states993enum FlowHoldModeState {994FlowHold_MotorStopped,995FlowHold_Takeoff,996FlowHold_Flying,997FlowHold_Landed998};9991000// calculate attitude from flow data1001void flow_to_angle(Vector2f &bf_angle);10021003LowPassFilterConstDtVector2f flow_filter;10041005bool flowhold_init(bool ignore_checks);1006void flowhold_run();1007void flowhold_flow_to_angle(Vector2f &angle, bool stick_input);1008void update_height_estimate(void);10091010// minimum assumed height1011const float height_min = 0.1f;10121013// maximum scaling height1014const float height_max = 3.0f;10151016AP_Float flow_max;1017AC_PI_2D flow_pi_xy{0.2f, 0.3f, 3000, 5, 0.0025f};1018AP_Float flow_filter_hz;1019AP_Int8 flow_min_quality;1020AP_Int8 brake_rate_dps;10211022float quality_filtered;10231024uint8_t log_counter;1025bool limited;1026Vector2f xy_I;10271028// accumulated INS delta velocity in north-east form since last flow update1029Vector2f delta_velocity_ne;10301031// last flow rate in radians/sec in north-east axis1032Vector2f last_flow_rate_rps;10331034// timestamp of last flow data1035uint32_t last_flow_ms;10361037float last_ins_height;1038float height_offset;10391040// are we braking after pilot input?1041bool braking;10421043// last time there was significant stick input1044uint32_t last_stick_input_ms;1045};1046#endif // MODE_FLOWHOLD_ENABLED104710481049class ModeGuided : public Mode {10501051public:1052#if AP_EXTERNAL_CONTROL_ENABLED1053friend class AP_ExternalControl_Copter;1054#endif10551056// inherit constructor1057using Mode::Mode;1058Number mode_number() const override { return Number::GUIDED; }10591060bool init(bool ignore_checks) override;1061void run() override;10621063bool requires_GPS() const override { return true; }1064bool has_manual_throttle() const override { return false; }1065bool allows_arming(AP_Arming::Method method) const override;1066bool is_autopilot() const override { return true; }1067bool has_user_takeoff(bool must_navigate) const override { return true; }1068bool in_guided_mode() const override { return true; }10691070bool requires_terrain_failsafe() const override { return true; }10711072#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED1073// Return the type of this mode for use by advanced failsafe1074AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }1075#endif10761077// Return true if the throttle high arming check can be skipped when arming from GCS or Scripting1078bool allows_GCS_or_SCR_arming_with_throttle_high() const override { return true; }10791080// Sets guided's angular target submode: Using a rotation quaternion, angular velocity, and climbrate or thrust (depends on user option)1081// attitude_quat: IF zero: ang_vel (angular velocity) must be provided even if all zeroes1082// IF non-zero: attitude_control is performed using both the attitude quaternion and angular velocity1083// ang_vel: angular velocity (rad/s)1084// climb_rate_cms_or_thrust: represents either the climb_rate (cm/s) or thrust scaled from [0, 1], unitless1085// use_thrust: IF true: climb_rate_cms_or_thrust represents thrust1086// IF false: climb_rate_cms_or_thrust represents climb_rate (cm/s)1087void set_angle(const Quaternion &attitude_quat, const Vector3f &ang_vel, float climb_rate_cms_or_thrust, bool use_thrust);10881089bool set_destination(const Vector3f& destination, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false, bool terrain_alt = false);1090bool set_destination(const Location& dest_loc, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false);1091bool get_wp(Location &loc) const override;1092void set_accel(const Vector3f& acceleration, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false, bool log_request = true);1093void set_velocity(const Vector3f& velocity, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false, bool log_request = true);1094void set_velaccel(const Vector3f& velocity, const Vector3f& acceleration, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false, bool log_request = true);1095bool set_destination_posvel(const Vector3f& destination, const Vector3f& velocity, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false);1096bool set_destination_posvelaccel(const Vector3f& destination, const Vector3f& velocity, const Vector3f& acceleration, bool use_yaw = false, float yaw_cd = 0.0, bool use_yaw_rate = false, float yaw_rate_cds = 0.0, bool yaw_relative = false);10971098// get position, velocity and acceleration targets1099const Vector3p& get_target_pos() const;1100const Vector3f& get_target_vel() const;1101const Vector3f& get_target_accel() const;11021103// returns true if GUIDED_OPTIONS param suggests SET_ATTITUDE_TARGET's "thrust" field should be interpreted as thrust instead of climb rate1104bool set_attitude_target_provides_thrust() const;1105bool stabilizing_pos_xy() const;1106bool stabilizing_vel_xy() const;1107bool use_wpnav_for_position_control() const;11081109void limit_clear();1110void limit_init_time_and_pos();1111void limit_set(uint32_t timeout_ms, float alt_min_cm, float alt_max_cm, float horiz_max_cm);1112bool limit_check();11131114bool is_taking_off() const override;11151116bool set_speed_xy(float speed_xy_cms) override;1117bool set_speed_up(float speed_up_cms) override;1118bool set_speed_down(float speed_down_cms) override;11191120// initialises position controller to implement take-off1121// takeoff_alt_cm is interpreted as alt-above-home (in cm) or alt-above-terrain if a rangefinder is available1122bool do_user_takeoff_start(float takeoff_alt_cm) override;11231124enum class SubMode {1125TakeOff,1126WP,1127Pos,1128PosVelAccel,1129VelAccel,1130Accel,1131Angle,1132};11331134SubMode submode() const { return guided_mode; }11351136void angle_control_start();1137void angle_control_run();11381139// return guided mode timeout in milliseconds. Only used for velocity, acceleration, angle control, and angular rate control1140uint32_t get_timeout_ms() const;11411142bool use_pilot_yaw() const override;11431144// pause continue in guided mode1145bool pause() override;1146bool resume() override;11471148// true if weathervaning is allowed in guided1149#if WEATHERVANE_ENABLED1150bool allows_weathervaning(void) const override;1151#endif11521153protected:11541155const char *name() const override { return "GUIDED"; }1156const char *name4() const override { return "GUID"; }11571158uint32_t wp_distance() const override;1159int32_t wp_bearing() const override;1160float crosstrack_error() const override;11611162private:11631164// enum for GUID_OPTIONS parameter1165enum class Option : uint32_t {1166AllowArmingFromTX = (1U << 0),1167// this bit is still available, pilot yaw was mapped to bit 2 for symmetry with auto1168IgnorePilotYaw = (1U << 2),1169SetAttitudeTarget_ThrustAsThrust = (1U << 3),1170DoNotStabilizePositionXY = (1U << 4),1171DoNotStabilizeVelocityXY = (1U << 5),1172WPNavUsedForPosControl = (1U << 6),1173AllowWeatherVaning = (1U << 7)1174};11751176// returns true if the Guided-mode-option is set (see GUID_OPTIONS)1177bool option_is_enabled(Option option) const;11781179// wp controller1180void wp_control_start();1181void wp_control_run();11821183void pva_control_start();1184void pos_control_start();1185void accel_control_start();1186void velaccel_control_start();1187void posvelaccel_control_start();1188void takeoff_run();1189void pos_control_run();1190void accel_control_run();1191void velaccel_control_run();1192void pause_control_run();1193void posvelaccel_control_run();1194void set_yaw_state(bool use_yaw, float yaw_cd, bool use_yaw_rate, float yaw_rate_cds, bool relative_angle);11951196// controls which controller is run (pos or vel):1197static SubMode guided_mode;1198static bool send_notification; // used to send one time notification to ground station1199static bool takeoff_complete; // true once takeoff has completed (used to trigger retracting of landing gear)12001201// guided mode is paused or not1202static bool _paused;1203};12041205#if AP_SCRIPTING_ENABLED1206// Mode which behaves as guided with custom mode number and name1207class ModeGuidedCustom : public ModeGuided {1208public:1209// constructor registers custom number and names1210ModeGuidedCustom(const Number _number, const char* _full_name, const char* _short_name);12111212bool init(bool ignore_checks) override;12131214Number mode_number() const override { return number; }12151216const char *name() const override { return full_name; }1217const char *name4() const override { return short_name; }12181219// State object which can be edited by scripting1220AP_Vehicle::custom_mode_state state;12211222private:1223const Number number;1224const char* full_name;1225const char* short_name;1226};1227#endif12281229class ModeGuidedNoGPS : public ModeGuided {12301231public:1232// inherit constructor1233using ModeGuided::Mode;1234Number mode_number() const override { return Number::GUIDED_NOGPS; }12351236bool init(bool ignore_checks) override;1237void run() override;12381239bool requires_GPS() const override { return false; }1240bool has_manual_throttle() const override { return false; }1241bool is_autopilot() const override { return true; }12421243protected:12441245const char *name() const override { return "GUIDED_NOGPS"; }1246const char *name4() const override { return "GNGP"; }12471248private:12491250};125112521253class ModeLand : public Mode {12541255public:1256// inherit constructor1257using Mode::Mode;1258Number mode_number() const override { return Number::LAND; }12591260bool init(bool ignore_checks) override;1261void run() override;12621263bool requires_GPS() const override { return false; }1264bool has_manual_throttle() const override { return false; }1265bool allows_arming(AP_Arming::Method method) const override { return false; };1266bool is_autopilot() const override { return true; }12671268bool is_landing() const override { return true; };12691270#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED1271// Return the type of this mode for use by advanced failsafe1272AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }1273#endif12741275void do_not_use_GPS();12761277// returns true if LAND mode is trying to control X/Y position1278bool controlling_position() const { return control_position; }12791280void set_land_pause(bool new_value) { land_pause = new_value; }12811282protected:12831284const char *name() const override { return "LAND"; }1285const char *name4() const override { return "LAND"; }12861287private:12881289void gps_run();1290void nogps_run();12911292bool control_position; // true if we are using an external reference to control position12931294uint32_t land_start_time;1295bool land_pause;1296};129712981299class ModeLoiter : public Mode {13001301public:1302// inherit constructor1303using Mode::Mode;1304Number mode_number() const override { return Number::LOITER; }13051306bool init(bool ignore_checks) override;1307void run() override;13081309bool requires_GPS() const override { return true; }1310bool has_manual_throttle() const override { return false; }1311bool allows_arming(AP_Arming::Method method) const override { return true; };1312bool is_autopilot() const override { return false; }1313bool has_user_takeoff(bool must_navigate) const override { return true; }1314bool allows_autotune() const override { return true; }13151316#if FRAME_CONFIG == HELI_FRAME1317bool allows_inverted() const override { return true; };1318#endif13191320#if AC_PRECLAND_ENABLED1321void set_precision_loiter_enabled(bool value) { _precision_loiter_enabled = value; }1322#endif13231324protected:13251326const char *name() const override { return "LOITER"; }1327const char *name4() const override { return "LOIT"; }13281329uint32_t wp_distance() const override;1330int32_t wp_bearing() const override;1331float crosstrack_error() const override { return pos_control->crosstrack_error();}13321333#if AC_PRECLAND_ENABLED1334bool do_precision_loiter();1335void precision_loiter_xy();1336#endif13371338private:13391340#if AC_PRECLAND_ENABLED1341bool _precision_loiter_enabled;1342bool _precision_loiter_active; // true if user has switched on prec loiter1343#endif13441345};134613471348class ModePosHold : public Mode {13491350public:1351// inherit constructor1352using Mode::Mode;1353Number mode_number() const override { return Number::POSHOLD; }13541355bool init(bool ignore_checks) override;1356void run() override;13571358bool requires_GPS() const override { return true; }1359bool has_manual_throttle() const override { return false; }1360bool allows_arming(AP_Arming::Method method) const override { return true; };1361bool is_autopilot() const override { return false; }1362bool has_user_takeoff(bool must_navigate) const override { return true; }1363bool allows_autotune() const override { return true; }13641365protected:13661367const char *name() const override { return "POSHOLD"; }1368const char *name4() const override { return "PHLD"; }13691370private:13711372void update_pilot_lean_angle(float &lean_angle_filtered, float &lean_angle_raw);1373float mix_controls(float mix_ratio, float first_control, float second_control);1374void update_brake_angle_from_velocity(float &brake_angle, float velocity);1375void init_wind_comp_estimate();1376void update_wind_comp_estimate();1377void get_wind_comp_lean_angles(float &roll_angle, float &pitch_angle);1378void roll_controller_to_pilot_override();1379void pitch_controller_to_pilot_override();13801381enum class RPMode {1382PILOT_OVERRIDE=0, // pilot is controlling this axis (i.e. roll or pitch)1383BRAKE, // this axis is braking towards zero1384BRAKE_READY_TO_LOITER, // this axis has completed braking and is ready to enter loiter mode (both modes must be this value before moving to next stage)1385BRAKE_TO_LOITER, // both vehicle's axis (roll and pitch) are transitioning from braking to loiter mode (braking and loiter controls are mixed)1386LOITER, // both vehicle axis are holding position1387CONTROLLER_TO_PILOT_OVERRIDE // pilot has input controls on this axis and this axis is transitioning to pilot override (other axis will transition to brake if no pilot input)1388};13891390RPMode roll_mode;1391RPMode pitch_mode;13921393// pilot input related variables1394float pilot_roll; // pilot requested roll angle (filtered to slow returns to zero)1395float pilot_pitch; // pilot requested roll angle (filtered to slow returns to zero)13961397// braking related variables1398struct {1399uint8_t time_updated_roll : 1; // true once we have re-estimated the braking time. This is done once as the vehicle begins to flatten out after braking1400uint8_t time_updated_pitch : 1; // true once we have re-estimated the braking time. This is done once as the vehicle begins to flatten out after braking14011402float gain; // gain used during conversion of vehicle's velocity to lean angle during braking (calculated from rate)1403float roll; // target roll angle during braking periods1404float pitch; // target pitch angle during braking periods1405int16_t timeout_roll; // number of cycles allowed for the braking to complete, this timeout will be updated at half-braking1406int16_t timeout_pitch; // number of cycles allowed for the braking to complete, this timeout will be updated at half-braking1407float angle_max_roll; // maximum lean angle achieved during braking. Used to determine when the vehicle has begun to flatten out so that we can re-estimate the braking time1408float angle_max_pitch; // maximum lean angle achieved during braking Used to determine when the vehicle has begun to flatten out so that we can re-estimate the braking time1409int16_t to_loiter_timer; // cycles to mix brake and loiter controls in POSHOLD_TO_LOITER1410} brake;14111412// loiter related variables1413int16_t controller_to_pilot_timer_roll; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT1414int16_t controller_to_pilot_timer_pitch; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT1415float controller_final_roll; // final roll angle from controller as we exit brake or loiter mode (used for mixing with pilot input)1416float controller_final_pitch; // final pitch angle from controller as we exit brake or loiter mode (used for mixing with pilot input)14171418// wind compensation related variables1419Vector2f wind_comp_ef; // wind compensation in earth frame, filtered lean angles from position controller1420float wind_comp_roll; // roll angle to compensate for wind1421float wind_comp_pitch; // pitch angle to compensate for wind1422uint16_t wind_comp_start_timer; // counter to delay start of wind compensation for a short time after loiter is engaged1423int8_t wind_comp_timer; // counter to reduce wind comp roll/pitch lean angle calcs to 10hz14241425// final output1426float roll; // final roll angle sent to attitude controller1427float pitch; // final pitch angle sent to attitude controller14281429};143014311432class ModeRTL : public Mode {14331434public:1435// inherit constructor1436using Mode::Mode;1437Number mode_number() const override { return Number::RTL; }14381439bool init(bool ignore_checks) override;1440void run() override {1441return run(true);1442}1443void run(bool disarm_on_land);14441445bool requires_GPS() const override { return true; }1446bool has_manual_throttle() const override { return false; }1447bool allows_arming(AP_Arming::Method method) const override { return false; };1448bool is_autopilot() const override { return true; }14491450bool requires_terrain_failsafe() const override { return true; }14511452#if AP_COPTER_ADVANCED_FAILSAFE_ENABLED1453// Return the type of this mode for use by advanced failsafe1454AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }1455#endif14561457// for reporting to GCS1458bool get_wp(Location &loc) const override;14591460bool use_pilot_yaw() const override;14611462bool set_speed_xy(float speed_xy_cms) override;1463bool set_speed_up(float speed_up_cms) override;1464bool set_speed_down(float speed_down_cms) override;14651466// RTL states1467enum class SubMode : uint8_t {1468STARTING,1469INITIAL_CLIMB,1470RETURN_HOME,1471LOITER_AT_HOME,1472FINAL_DESCENT,1473LAND1474};1475SubMode state() { return _state; }14761477// this should probably not be exposed1478bool state_complete() const { return _state_complete; }14791480virtual bool is_landing() const override;14811482void restart_without_terrain();14831484// enum for RTL_ALT_TYPE parameter1485enum class RTLAltType : int8_t {1486RELATIVE = 0,1487TERRAIN = 11488};1489ModeRTL::RTLAltType get_alt_type() const;14901491protected:14921493const char *name() const override { return "RTL"; }1494const char *name4() const override { return "RTL "; }14951496// for reporting to GCS1497uint32_t wp_distance() const override;1498int32_t wp_bearing() const override;1499float crosstrack_error() const override { return wp_nav->crosstrack_error();}15001501void descent_start();1502void descent_run();1503void land_start();1504void land_run(bool disarm_on_land);15051506void set_descent_target_alt(uint32_t alt) { rtl_path.descent_target.alt = alt; }15071508private:15091510void climb_start();1511void return_start();1512void climb_return_run();1513void loiterathome_start();1514void loiterathome_run();1515void build_path();1516void compute_return_target();15171518SubMode _state = SubMode::INITIAL_CLIMB; // records state of rtl (initial climb, returning home, etc)1519bool _state_complete = false; // set to true if the current state is completed15201521struct {1522// NEU w/ Z element alt-above-ekf-origin unless use_terrain is true in which case Z element is alt-above-terrain1523Location origin_point;1524Location climb_target;1525Location return_target;1526Location descent_target;1527bool land;1528} rtl_path;15291530// return target alt type1531enum class ReturnTargetAltType {1532RELATIVE = 0,1533RANGEFINDER = 1,1534TERRAINDATABASE = 21535};15361537// Loiter timer - Records how long we have been in loiter1538uint32_t _loiter_start_time;15391540bool terrain_following_allowed;15411542// enum for RTL_OPTIONS parameter1543enum class Options : int32_t {1544// First pair of bits are still available, pilot yaw was mapped to bit 2 for symmetry with auto1545IgnorePilotYaw = (1U << 2),1546};15471548};154915501551class ModeSmartRTL : public ModeRTL {15521553public:1554// inherit constructor1555using ModeRTL::Mode;1556Number mode_number() const override { return Number::SMART_RTL; }15571558bool init(bool ignore_checks) override;1559void run() override;15601561bool requires_GPS() const override { return true; }1562bool has_manual_throttle() const override { return false; }1563bool allows_arming(AP_Arming::Method method) const override { return false; }1564bool is_autopilot() const override { return true; }15651566void save_position();1567void exit() override;15681569bool is_landing() const override;1570bool use_pilot_yaw() const override;15711572// Safe RTL states1573enum class SubMode : uint8_t {1574WAIT_FOR_PATH_CLEANUP,1575PATH_FOLLOW,1576PRELAND_POSITION,1577DESCEND,1578LAND1579};15801581protected:15821583const char *name() const override { return "SMARTRTL"; }1584const char *name4() const override { return "SRTL"; }15851586// for reporting to GCS1587bool get_wp(Location &loc) const override;1588uint32_t wp_distance() const override;1589int32_t wp_bearing() const override;1590float crosstrack_error() const override { return wp_nav->crosstrack_error();}15911592private:15931594void wait_cleanup_run();1595void path_follow_run();1596void pre_land_position_run();1597void land();1598SubMode smart_rtl_state = SubMode::PATH_FOLLOW;15991600// keep track of how long we have failed to get another return1601// point while following our path home. If we take too long we1602// may choose to land the vehicle.1603uint32_t path_follow_last_pop_fail_ms;16041605// backup last popped point so that it can be restored to the path1606// if vehicle exits SmartRTL mode before reaching home. invalid if zero1607Vector3f dest_NED_backup;1608};160916101611class ModeSport : public Mode {16121613public:1614// inherit constructor1615using Mode::Mode;1616Number mode_number() const override { return Number::SPORT; }16171618bool init(bool ignore_checks) override;1619void run() override;16201621bool requires_GPS() const override { return false; }1622bool has_manual_throttle() const override { return false; }1623bool allows_arming(AP_Arming::Method method) const override { return true; };1624bool is_autopilot() const override { return false; }1625bool has_user_takeoff(bool must_navigate) const override {1626return !must_navigate;1627}16281629protected:16301631const char *name() const override { return "SPORT"; }1632const char *name4() const override { return "SPRT"; }16331634private:16351636};163716381639class ModeStabilize : public Mode {16401641public:1642// inherit constructor1643using Mode::Mode;1644Number mode_number() const override { return Number::STABILIZE; }16451646virtual void run() override;16471648bool requires_GPS() const override { return false; }1649bool has_manual_throttle() const override { return true; }1650bool allows_arming(AP_Arming::Method method) const override { return true; };1651bool is_autopilot() const override { return false; }1652bool allows_save_trim() const override { return true; }1653bool allows_autotune() const override { return true; }1654bool allows_flip() const override { return true; }16551656protected:16571658const char *name() const override { return "STABILIZE"; }1659const char *name4() const override { return "STAB"; }16601661private:16621663};16641665#if FRAME_CONFIG == HELI_FRAME1666class ModeStabilize_Heli : public ModeStabilize {16671668public:1669// inherit constructor1670using ModeStabilize::Mode;16711672bool init(bool ignore_checks) override;1673void run() override;16741675bool allows_inverted() const override { return true; };16761677protected:16781679private:16801681};1682#endif16831684class ModeSystemId : public Mode {16851686public:1687ModeSystemId(void);1688Number mode_number() const override { return Number::SYSTEMID; }16891690bool init(bool ignore_checks) override;1691void run() override;1692void exit() override;16931694bool requires_GPS() const override { return false; }1695bool has_manual_throttle() const override { return true; }1696bool allows_arming(AP_Arming::Method method) const override { return false; };1697bool is_autopilot() const override { return false; }1698bool logs_attitude() const override { return true; }16991700void set_magnitude(float input) { waveform_magnitude.set(input); }17011702static const struct AP_Param::GroupInfo var_info[];17031704Chirp chirp_input;17051706protected:17071708const char *name() const override { return "SYSTEMID"; }1709const char *name4() const override { return "SYSI"; }17101711private:17121713void log_data() const;1714bool is_poscontrol_axis_type() const;17151716enum class AxisType {1717NONE = 0, // none1718INPUT_ROLL = 1, // angle input roll axis is being excited1719INPUT_PITCH = 2, // angle pitch axis is being excited1720INPUT_YAW = 3, // angle yaw axis is being excited1721RECOVER_ROLL = 4, // angle roll axis is being excited1722RECOVER_PITCH = 5, // angle pitch axis is being excited1723RECOVER_YAW = 6, // angle yaw axis is being excited1724RATE_ROLL = 7, // rate roll axis is being excited1725RATE_PITCH = 8, // rate pitch axis is being excited1726RATE_YAW = 9, // rate yaw axis is being excited1727MIX_ROLL = 10, // mixer roll axis is being excited1728MIX_PITCH = 11, // mixer pitch axis is being excited1729MIX_YAW = 12, // mixer pitch axis is being excited1730MIX_THROTTLE = 13, // mixer throttle axis is being excited1731DISTURB_POS_LAT = 14, // lateral body axis measured position is being excited1732DISTURB_POS_LONG = 15, // longitudinal body axis measured position is being excited1733DISTURB_VEL_LAT = 16, // lateral body axis measured velocity is being excited1734DISTURB_VEL_LONG = 17, // longitudinal body axis measured velocity is being excited1735INPUT_VEL_LAT = 18, // lateral body axis commanded velocity is being excited1736INPUT_VEL_LONG = 19, // longitudinal body axis commanded velocity is being excited1737};17381739AP_Int8 axis; // Controls which axis are being excited. Set to non-zero to display other parameters1740AP_Float waveform_magnitude;// Magnitude of chirp waveform1741AP_Float frequency_start; // Frequency at the start of the chirp1742AP_Float frequency_stop; // Frequency at the end of the chirp1743AP_Float time_fade_in; // Time to reach maximum amplitude of chirp1744AP_Float time_record; // Time taken to complete the chirp waveform1745AP_Float time_fade_out; // Time to reach zero amplitude after chirp finishes17461747bool att_bf_feedforward; // Setting of attitude_control->get_bf_feedforward1748float waveform_time; // Time reference for waveform1749float waveform_sample; // Current waveform sample1750float waveform_freq_rads; // Instantaneous waveform frequency1751float time_const_freq; // Time at constant frequency before chirp starts1752int8_t log_subsample; // Subsample multiple for logging.1753Vector2f target_vel; // target velocity for position controller modes1754Vector2f target_pos; // target positon1755Vector2f input_vel_last; // last cycle input velocity1756// System ID states1757enum class SystemIDModeState {1758SYSTEMID_STATE_STOPPED,1759SYSTEMID_STATE_TESTING1760} systemid_state;1761};17621763class ModeThrow : public Mode {17641765public:1766// inherit constructor1767using Mode::Mode;1768Number mode_number() const override { return Number::THROW; }17691770bool init(bool ignore_checks) override;1771void run() override;17721773bool requires_GPS() const override { return true; }1774bool has_manual_throttle() const override { return false; }1775bool allows_arming(AP_Arming::Method method) const override { return true; };1776bool is_autopilot() const override { return false; }17771778// Throw types1779enum class ThrowType {1780Upward = 0,1781Drop = 11782};17831784enum class PreThrowMotorState {1785STOPPED = 0,1786RUNNING = 1,1787};17881789protected:17901791const char *name() const override { return "THROW"; }1792const char *name4() const override { return "THRW"; }17931794private:17951796bool throw_detected();1797bool throw_position_good() const;1798bool throw_height_good() const;1799bool throw_attitude_good() const;18001801// Throw stages1802enum ThrowModeStage {1803Throw_Disarmed,1804Throw_Detecting,1805Throw_Wait_Throttle_Unlimited,1806Throw_Uprighting,1807Throw_HgtStabilise,1808Throw_PosHold1809};18101811ThrowModeStage stage = Throw_Disarmed;1812ThrowModeStage prev_stage = Throw_Disarmed;1813uint32_t last_log_ms;1814bool nextmode_attempted;1815uint32_t free_fall_start_ms; // system time free fall was detected1816float free_fall_start_velz; // vertical velocity when free fall was detected1817};18181819#if MODE_TURTLE_ENABLED1820class ModeTurtle : public Mode {18211822public:1823// inherit constructors1824using Mode::Mode;1825Number mode_number() const override { return Number::TURTLE; }18261827bool init(bool ignore_checks) override;1828void run() override;1829void exit() override;18301831bool requires_GPS() const override { return false; }1832bool has_manual_throttle() const override { return true; }1833bool allows_arming(AP_Arming::Method method) const override;1834bool is_autopilot() const override { return false; }1835void change_motor_direction(bool reverse);1836void output_to_motors() override;18371838protected:1839const char *name() const override { return "TURTLE"; }1840const char *name4() const override { return "TRTL"; }18411842private:1843void arm_motors();1844void disarm_motors();18451846float motors_output;1847Vector2f motors_input;1848uint32_t last_throttle_warning_output_ms;1849};1850#endif18511852// modes below rely on Guided mode so must be declared at the end (instead of in alphabetical order)18531854class ModeAvoidADSB : public ModeGuided {18551856public:1857// inherit constructor1858using ModeGuided::Mode;1859Number mode_number() const override { return Number::AVOID_ADSB; }18601861bool init(bool ignore_checks) override;1862void run() override;18631864bool requires_GPS() const override { return true; }1865bool has_manual_throttle() const override { return false; }1866bool allows_arming(AP_Arming::Method method) const override { return false; }1867bool is_autopilot() const override { return true; }18681869bool set_velocity(const Vector3f& velocity_neu);18701871protected:18721873const char *name() const override { return "AVOID_ADSB"; }1874const char *name4() const override { return "AVOI"; }18751876private:18771878};18791880#if MODE_FOLLOW_ENABLED1881class ModeFollow : public ModeGuided {18821883public:18841885// inherit constructor1886using ModeGuided::Mode;1887Number mode_number() const override { return Number::FOLLOW; }18881889bool init(bool ignore_checks) override;1890void exit() override;1891void run() override;18921893bool requires_GPS() const override { return true; }1894bool has_manual_throttle() const override { return false; }1895bool allows_arming(AP_Arming::Method method) const override { return false; }1896bool is_autopilot() const override { return true; }18971898protected:18991900const char *name() const override { return "FOLLOW"; }1901const char *name4() const override { return "FOLL"; }19021903// for reporting to GCS1904bool get_wp(Location &loc) const override;1905uint32_t wp_distance() const override;1906int32_t wp_bearing() const override;19071908uint32_t last_log_ms; // system time of last time desired velocity was logging1909};1910#endif19111912class ModeZigZag : public Mode {19131914public:1915ModeZigZag(void);19161917// Inherit constructor1918using Mode::Mode;1919Number mode_number() const override { return Number::ZIGZAG; }19201921enum class Destination : uint8_t {1922A, // Destination A1923B, // Destination B1924};19251926enum class Direction : uint8_t {1927FORWARD, // moving forward from the yaw direction1928RIGHT, // moving right from the yaw direction1929BACKWARD, // moving backward from the yaw direction1930LEFT, // moving left from the yaw direction1931} zigzag_direction;19321933bool init(bool ignore_checks) override;1934void exit() override;1935void run() override;19361937// auto control methods. copter flies grid pattern1938void run_auto();1939void suspend_auto();1940void init_auto();19411942bool requires_GPS() const override { return true; }1943bool has_manual_throttle() const override { return false; }1944bool allows_arming(AP_Arming::Method method) const override { return true; }1945bool is_autopilot() const override { return true; }1946bool has_user_takeoff(bool must_navigate) const override { return true; }19471948// save current position as A or B. If both A and B have been saved move to the one specified1949void save_or_move_to_destination(Destination ab_dest);19501951// return manual control to the pilot1952void return_to_manual_control(bool maintain_target);19531954static const struct AP_Param::GroupInfo var_info[];19551956protected:19571958const char *name() const override { return "ZIGZAG"; }1959const char *name4() const override { return "ZIGZ"; }1960uint32_t wp_distance() const override;1961int32_t wp_bearing() const override;1962float crosstrack_error() const override;19631964private:19651966void auto_control();1967void manual_control();1968bool reached_destination();1969bool calculate_next_dest(Destination ab_dest, bool use_wpnav_alt, Vector3f& next_dest, bool& terrain_alt) const;1970void spray(bool b);1971bool calculate_side_dest(Vector3f& next_dest, bool& terrain_alt) const;1972void move_to_side();19731974Vector2f dest_A; // in NEU frame in cm relative to ekf origin1975Vector2f dest_B; // in NEU frame in cm relative to ekf origin1976Vector3f current_dest; // current target destination (use for resume after suspending)1977bool current_terr_alt;19781979// parameters1980AP_Int8 _auto_enabled; // top level enable/disable control1981#if HAL_SPRAYER_ENABLED1982AP_Int8 _spray_enabled; // auto spray enable/disable1983#endif1984AP_Int8 _wp_delay; // delay for zigzag waypoint1985AP_Float _side_dist; // sideways distance1986AP_Int8 _direction; // sideways direction1987AP_Int16 _line_num; // total number of lines19881989enum ZigZagState {1990STORING_POINTS, // storing points A and B, pilot has manual control1991AUTO, // after A and B defined, pilot toggle the switch from one side to the other, vehicle flies autonomously1992MANUAL_REGAIN // pilot toggle the switch to middle position, has manual control1993} stage;19941995enum AutoState {1996MANUAL, // not in ZigZag Auto1997AB_MOVING, // moving from A to B or from B to A1998SIDEWAYS, // moving to sideways1999} auto_stage;20002001uint32_t reach_wp_time_ms = 0; // time since vehicle reached destination (or zero if not yet reached)2002Destination ab_dest_stored; // store the current destination2003bool is_auto; // enable zigzag auto feature which is automate both AB and sideways2004uint16_t line_count = 0; // current line number2005int16_t line_num = 0; // target line number2006bool is_suspended; // true if zigzag auto is suspended2007};20082009#if MODE_AUTOROTATE_ENABLED2010class ModeAutorotate : public Mode {20112012public:20132014// inherit constructor2015using Mode::Mode;2016Number mode_number() const override { return Number::AUTOROTATE; }20172018bool init(bool ignore_checks) override;2019void run() override;20202021bool is_autopilot() const override { return true; }2022bool requires_GPS() const override { return false; }2023bool has_manual_throttle() const override { return false; }2024bool allows_arming(AP_Arming::Method method) const override { return false; };20252026static const struct AP_Param::GroupInfo var_info[];20272028protected:20292030const char *name() const override { return "AUTOROTATE"; }2031const char *name4() const override { return "AROT"; }20322033private:20342035// --- Internal variables ---2036float _initial_rpm; // Head speed recorded at initiation of flight mode (RPM)2037float _target_head_speed; // The terget head main rotor head speed. Normalised by main rotor set point2038float _desired_v_z; // Desired vertical2039int32_t _pitch_target; // Target pitch attitude to pass to attitude controller2040uint32_t _entry_time_start_ms; // Time remaining until entry phase moves on to glide phase2041float _hs_decay; // The head accerleration during the entry phase20422043enum class Autorotation_Phase {2044ENTRY,2045SS_GLIDE,2046FLARE,2047TOUCH_DOWN,2048LANDED } phase_switch;20492050enum class Navigation_Decision {2051USER_CONTROL_STABILISED,2052STRAIGHT_AHEAD,2053INTO_WIND,2054NEAREST_RALLY} nav_pos_switch;20552056// --- Internal flags ---2057struct controller_flags {2058bool entry_initial : 1;2059bool ss_glide_initial : 1;2060bool flare_initial : 1;2061bool touch_down_initial : 1;2062bool landed_initial : 1;2063bool straight_ahead_initial : 1;2064bool level_initial : 1;2065bool break_initial : 1;2066bool bad_rpm : 1;2067} _flags;20682069struct message_flags {2070bool bad_rpm : 1;2071} _msg_flags;20722073//--- Internal functions ---2074void warning_message(uint8_t message_n); //Handles output messages to the terminal20752076};2077#endif207820792080