2016-03-21 01:33:42 -03:00
# pragma once
2019-05-09 23:18:49 -03:00
# include "Copter.h"
2016-03-21 01:33:42 -03:00
2019-09-07 20:33:56 -03:00
class Parameters ;
class ParametersG2 ;
class GCS_Copter ;
2017-12-10 23:51:13 -04:00
class Mode {
2019-04-18 19:49:09 -03:00
public :
2016-03-21 01:33:42 -03:00
2019-09-07 20:33:56 -03:00
// Auto Pilot Modes enumeration
enum class Number {
STABILIZE = 0 , // manual airframe angle with manual throttle
ACRO = 1 , // manual body-frame angular rate with manual throttle
ALT_HOLD = 2 , // manual airframe angle with automatic throttle
AUTO = 3 , // fully automatic waypoint control using mission commands
GUIDED = 4 , // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands
LOITER = 5 , // automatic horizontal acceleration with automatic throttle
RTL = 6 , // automatic return to launching point
CIRCLE = 7 , // automatic circular flight with automatic throttle
LAND = 9 , // automatic landing with horizontal position control
DRIFT = 11 , // semi-automous position, yaw and throttle control
SPORT = 13 , // manual earth-frame angular rate control with manual throttle
FLIP = 14 , // automatically flip the vehicle on the roll axis
AUTOTUNE = 15 , // automatically tune the vehicle's roll and pitch gains
POSHOLD = 16 , // automatic position hold with manual override, with automatic throttle
BRAKE = 17 , // full-brake using inertial/GPS system, no pilot input
THROW = 18 , // throw to launch mode using inertial/GPS system, no pilot input
AVOID_ADSB = 19 , // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft
GUIDED_NOGPS = 20 , // guided mode but only accepts attitude and altitude
SMART_RTL = 21 , // SMART_RTL returns to home by retracing its steps
FLOWHOLD = 22 , // FLOWHOLD holds position with optical flow without rangefinder
FOLLOW = 23 , // follow attempts to follow another vehicle or ground station
ZIGZAG = 24 , // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B
2019-07-29 04:55:40 -03:00
SYSTEMID = 25 , // System ID mode produces automated system identification signals in the controllers
2019-09-07 20:33:56 -03:00
} ;
2018-02-07 22:21:09 -04:00
// constructor
Mode ( void ) ;
2017-12-25 23:55:42 -04:00
2019-01-02 23:07:59 -04:00
// do not allow copying
Mode ( const Mode & other ) = delete ;
Mode & operator = ( const Mode & ) = delete ;
2019-04-18 20:41:30 -03:00
// child classes should override these methods
2019-04-18 19:49:09 -03:00
virtual bool init ( bool ignore_checks ) {
return true ;
}
virtual void run ( ) = 0 ;
2019-04-18 20:41:30 -03:00
virtual bool requires_GPS ( ) const = 0 ;
virtual bool has_manual_throttle ( ) const = 0 ;
virtual bool allows_arming ( bool from_gcs ) const = 0 ;
virtual bool is_autopilot ( ) const { return false ; }
virtual bool has_user_takeoff ( bool must_navigate ) const { return false ; }
virtual bool in_guided_mode ( ) const { return false ; }
2019-07-29 04:35:12 -03:00
virtual bool stop_attitude_logging ( ) const { return false ; }
2019-04-18 19:49:09 -03:00
2019-04-18 20:41:30 -03:00
// return a string for this flightmode
virtual const char * name ( ) const = 0 ;
virtual const char * name4 ( ) const = 0 ;
2017-12-25 23:55:42 -04:00
2017-12-12 05:45:40 -04:00
bool do_user_takeoff ( float takeoff_alt_cm , bool must_navigate ) ;
2019-04-18 19:49:09 -03:00
virtual bool is_taking_off ( ) const ;
static void takeoff_stop ( ) { takeoff . stop ( ) ; }
2017-12-12 05:45:40 -04:00
2019-04-18 19:49:09 -03:00
virtual bool landing_gear_should_be_deployed ( ) const { return false ; }
virtual bool is_landing ( ) const { return false ; }
2016-03-21 01:33:42 -03:00
2019-06-05 07:47:32 -03:00
// functions for reporting to GCS
2019-04-18 19:49:09 -03:00
virtual bool get_wp ( Location & loc ) { return false ; } ;
virtual int32_t wp_bearing ( ) const { return 0 ; }
virtual uint32_t wp_distance ( ) const { return 0 ; }
virtual float crosstrack_error ( ) const { return 0.0f ; }
2019-06-05 07:47:32 -03:00
2019-04-18 19:49:09 -03:00
void update_navigation ( ) ;
2017-12-06 07:18:34 -04:00
2019-04-18 19:49:09 -03:00
int32_t get_alt_above_ground_cm ( void ) ;
2016-03-21 01:33:42 -03:00
2019-04-18 19:49:09 -03:00
// pilot input processing
void get_pilot_desired_lean_angles ( float & roll_out , float & pitch_out , float angle_max , float angle_limit ) const ;
float get_pilot_desired_yaw_rate ( int16_t stick_angle ) ;
float get_pilot_desired_throttle ( ) const ;
2016-05-01 00:29:31 -03:00
2019-04-18 19:49:09 -03:00
const Vector3f & get_desired_velocity ( ) {
// note that position control isn't used in every mode, so
// this may return bogus data:
return pos_control - > get_desired_velocity ( ) ;
}
protected :
2018-03-13 21:23:30 -03:00
// navigation support functions
2017-12-05 21:28:32 -04:00
virtual void run_autopilot ( ) { }
2018-03-13 21:23:30 -03:00
// helper functions
2019-04-08 05:15:57 -03:00
bool is_disarmed_or_landed ( ) const ;
2019-01-08 06:43:51 -04:00
void zero_throttle_and_relax_ac ( bool spool_up = false ) ;
2019-02-28 05:03:23 -04:00
void zero_throttle_and_hold_attitude ( ) ;
2019-03-14 20:45:00 -03:00
void make_safe_spool_down ( ) ;
2018-03-13 21:23:30 -03:00
2018-03-19 14:26:35 -03:00
// functions to control landing
// in modes that support landing
void land_run_horizontal_control ( ) ;
void land_run_vertical_control ( bool pause_descent = false ) ;
2019-03-06 02:36:32 -04:00
// return expected input throttle setting to hover:
virtual float throttle_hover ( ) const ;
2019-02-28 05:03:23 -04:00
// Alt_Hold based flight mode states used in Alt_Hold, Loiter, and Sport
enum AltHoldModeState {
AltHold_MotorStopped ,
AltHold_Takeoff ,
AltHold_Landed_Ground_Idle ,
AltHold_Landed_Pre_Takeoff ,
AltHold_Flying
} ;
AltHoldModeState get_alt_hold_state ( float target_climb_rate_cms ) ;
2016-03-21 01:33:42 -03:00
// convenience references to avoid code churn in conversion:
Parameters & g ;
ParametersG2 & g2 ;
AC_WPNav * & wp_nav ;
2018-03-27 23:13:37 -03:00
AC_Loiter * & loiter_nav ;
2016-03-21 01:33:42 -03:00
AC_PosControl * & pos_control ;
AP_InertialNav & inertial_nav ;
AP_AHRS & ahrs ;
AC_AttitudeControl_t * & attitude_control ;
MOTOR_CLASS * & motors ;
RC_Channel * & channel_roll ;
RC_Channel * & channel_pitch ;
RC_Channel * & channel_throttle ;
RC_Channel * & channel_yaw ;
float & G_Dt ;
2017-12-12 06:34:49 -04:00
2018-06-26 00:31:40 -03:00
// note that we support two entirely different automatic takeoffs:
// "user-takeoff", which is available in modes such as ALT_HOLD
// (see has_user_takeoff method). "user-takeoff" is a simple
// reach-altitude-based-on-pilot-input-or-parameter routine.
// "auto-takeoff" is used by both Guided and Auto, and is
// basically waypoint navigation with pilot yaw permitted.
// user-takeoff support; takeoff state is shared across all mode instances
2018-03-16 03:22:14 -03:00
class _TakeOff {
public :
void start ( float alt_cm ) ;
void stop ( ) ;
void get_climb_rates ( float & pilot_climb_rate ,
float & takeoff_climb_rate ) ;
bool triggered ( float target_climb_rate ) const ;
bool running ( ) const { return _running ; }
private :
bool _running ;
2017-12-12 06:34:49 -04:00
float max_speed ;
float alt_delta ;
uint32_t start_ms ;
2018-03-16 03:22:14 -03:00
} ;
2017-12-12 06:34:49 -04:00
2018-03-16 03:22:14 -03:00
static _TakeOff takeoff ;
2017-12-12 06:34:49 -04:00
2017-12-12 06:09:48 -04:00
virtual bool do_user_takeoff_start ( float takeoff_alt_cm ) ;
2018-06-26 00:16:31 -03:00
// method shared by both Guided and Auto for takeoff. This is
// waypoint navigation but the user can control the yaw.
void auto_takeoff_run ( ) ;
2018-06-26 00:24:54 -03:00
void auto_takeoff_set_start_alt ( void ) ;
void auto_takeoff_attitude_run ( float target_yaw_rate ) ;
// altitude below which we do no navigation in auto takeoff
static float auto_takeoff_no_nav_alt_cm ;
2018-06-26 00:16:31 -03:00
2019-04-18 20:41:30 -03:00
public :
// Navigation Yaw control
class AutoYaw {
public :
// yaw(): main product of AutoYaw; the heading:
float yaw ( ) ;
// mode(): current method of determining desired yaw:
autopilot_yaw_mode mode ( ) const { return ( autopilot_yaw_mode ) _mode ; }
void set_mode_to_default ( bool rtl ) ;
void set_mode ( autopilot_yaw_mode new_mode ) ;
autopilot_yaw_mode default_mode ( bool rtl ) const ;
// rate_cds(): desired yaw rate in centidegrees/second:
float rate_cds ( ) const ;
void set_rate ( float new_rate_cds ) ;
// set_roi(...): set a "look at" location:
void set_roi ( const Location & roi_location ) ;
void set_fixed_yaw ( float angle_deg ,
float turn_rate_dps ,
int8_t direction ,
bool relative_angle ) ;
private :
float look_ahead_yaw ( ) ;
float roi_yaw ( ) ;
// auto flight mode's yaw mode
uint8_t _mode = AUTO_YAW_LOOK_AT_NEXT_WP ;
// Yaw will point at this location if mode is set to AUTO_YAW_ROI
Vector3f roi ;
// bearing from current location to the ROI
float _roi_yaw ;
// yaw used for YAW_FIXED yaw_mode
int32_t _fixed_yaw ;
// Deg/s we should turn
int16_t _fixed_yaw_slewrate ;
// heading when in yaw_look_ahead_yaw
float _look_ahead_yaw ;
// turn rate (in cds) when auto_yaw_mode is set to AUTO_YAW_RATE
float _rate_cds ;
// used to reduce update rate to 100hz:
uint8_t roi_yaw_counter ;
} ;
static AutoYaw auto_yaw ;
2016-03-21 01:33:42 -03:00
// pass-through functions to reduce code churn on conversion;
2017-12-10 23:51:13 -04:00
// these are candidates for moving into the Mode base
2016-03-21 01:33:42 -03:00
// class.
2018-02-07 22:21:09 -04:00
float get_pilot_desired_climb_rate ( float throttle_control ) ;
float get_non_takeoff_throttle ( void ) ;
void update_simple_mode ( void ) ;
2019-09-07 20:33:56 -03:00
bool set_mode ( Mode : : Number mode , mode_reason_t reason ) ;
2018-02-07 22:21:09 -04:00
void set_land_complete ( bool b ) ;
GCS_Copter & gcs ( ) ;
2019-02-01 07:30:00 -04:00
void Log_Write_Event ( Log_Event id ) ;
2018-02-07 22:21:09 -04:00
void set_throttle_takeoff ( void ) ;
float get_avoidance_adjusted_climbrate ( float target_rate ) ;
uint16_t get_pilot_speed_dn ( void ) ;
2016-03-21 01:33:42 -03:00
// end pass-through functions
} ;
2016-03-21 01:20:54 -03:00
2018-03-14 17:14:49 -03:00
# if MODE_ACRO_ENABLED == ENABLED
2017-12-10 23:51:13 -04:00
class ModeAcro : public Mode {
2016-03-21 01:20:54 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2018-02-08 18:50:59 -04:00
2017-11-09 22:54:34 -04:00
virtual void run ( ) override ;
2016-03-21 01:20:54 -03:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return true ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
2019-04-18 20:41:30 -03:00
bool is_autopilot ( ) const override { return false ; }
2016-03-21 01:20:54 -03:00
protected :
const char * name ( ) const override { return " ACRO " ; }
const char * name4 ( ) const override { return " ACRO " ; }
void get_pilot_desired_angle_rates ( int16_t roll_in , int16_t pitch_in , int16_t yaw_in , float & roll_out , float & pitch_out , float & yaw_out ) ;
2019-09-07 20:33:56 -03:00
float throttle_hover ( ) const override ;
2019-03-06 02:36:32 -04:00
2016-03-21 01:20:54 -03:00
private :
} ;
2018-03-14 17:14:49 -03:00
# endif
2016-03-21 01:20:54 -03:00
# if FRAME_CONFIG == HELI_FRAME
2017-12-10 23:51:13 -04:00
class ModeAcro_Heli : public ModeAcro {
2016-03-21 01:20:54 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeAcro : : Mode ;
2016-03-21 01:20:54 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2019-03-18 13:08:47 -03:00
void virtual_flybar ( float & roll_out , float & pitch_out , float & yaw_out , float pitch_leak , float roll_leak ) ;
2016-03-21 01:20:54 -03:00
protected :
private :
} ;
# endif
2016-03-21 01:23:41 -03:00
2017-12-10 23:51:13 -04:00
class ModeAltHold : public Mode {
2016-03-21 01:23:41 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-21 01:23:41 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-03-21 01:23:41 -03:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override {
return ! must_navigate ;
}
2016-03-21 01:23:41 -03:00
protected :
const char * name ( ) const override { return " ALT_HOLD " ; }
const char * name4 ( ) const override { return " ALTH " ; }
private :
} ;
2017-01-14 01:23:33 -04:00
2017-12-10 23:51:13 -04:00
class ModeAuto : public Mode {
2016-03-21 00:45:50 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-21 00:45:50 -03:00
2018-02-08 18:50:59 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2016-03-21 00:45:50 -03:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
2019-04-18 20:41:30 -03:00
bool is_autopilot ( ) const override { return true ; }
2018-11-07 07:07:46 -04:00
bool in_guided_mode ( ) const override { return mode ( ) = = Auto_NavGuided ; }
2016-03-21 00:45:50 -03:00
// Auto
2017-12-05 21:28:32 -04:00
AutoMode mode ( ) const { return _mode ; }
2016-03-21 00:45:50 -03:00
bool loiter_start ( ) ;
void rtl_start ( ) ;
void takeoff_start ( const Location & dest_loc ) ;
2019-07-10 23:11:46 -03:00
void wp_start ( const Vector3f & destination , bool terrain_alt ) ;
2019-01-01 22:54:31 -04:00
void wp_start ( const Location & dest_loc ) ;
2016-03-21 00:45:50 -03:00
void land_start ( ) ;
void land_start ( const Vector3f & destination ) ;
2019-01-01 22:54:31 -04:00
void circle_movetoedge_start ( const Location & circle_center , float radius_m ) ;
2016-03-21 00:45:50 -03:00
void circle_start ( ) ;
void spline_start ( const Vector3f & destination , bool stopped_at_start , AC_WPNav : : spline_segment_end_type seg_end_type , const Vector3f & next_spline_destination ) ;
2019-01-01 22:54:31 -04:00
void spline_start ( const Location & destination , bool stopped_at_start , AC_WPNav : : spline_segment_end_type seg_end_type , const Location & next_destination ) ;
2016-03-21 00:45:50 -03:00
void nav_guided_start ( ) ;
2018-04-30 06:50:04 -03:00
bool is_landing ( ) const override ;
2017-12-06 07:18:34 -04:00
bool landing_gear_should_be_deployed ( ) const override ;
2016-03-21 00:45:50 -03:00
2018-04-30 06:50:04 -03:00
bool is_taking_off ( ) const override ;
2016-05-01 00:29:31 -03:00
// return true if this flight mode supports user takeoff
// must_nagivate is true if mode must also control horizontal position
2018-11-07 07:07:46 -04:00
virtual bool has_user_takeoff ( bool must_navigate ) const override { return false ; }
2016-05-01 00:29:31 -03:00
2016-03-21 00:45:50 -03:00
void payload_place_start ( ) ;
2017-12-10 22:50:49 -04:00
// for GCS_MAVLink to call:
bool do_guided ( const AP_Mission : : Mission_Command & cmd ) ;
2018-04-24 20:31:01 -03:00
AP_Mission mission {
2019-05-09 23:18:49 -03:00
FUNCTOR_BIND_MEMBER ( & ModeAuto : : start_command , bool , const AP_Mission : : Mission_Command & ) ,
FUNCTOR_BIND_MEMBER ( & ModeAuto : : verify_command , bool , const AP_Mission : : Mission_Command & ) ,
FUNCTOR_BIND_MEMBER ( & ModeAuto : : exit_mission , void ) } ;
2018-04-24 20:31:01 -03:00
2016-03-21 00:45:50 -03:00
protected :
const char * name ( ) const override { return " AUTO " ; }
const char * name4 ( ) const override { return " AUTO " ; }
2018-02-07 22:21:09 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2018-05-23 12:34:24 -03:00
float crosstrack_error ( ) const override { return wp_nav - > crosstrack_error ( ) ; }
2019-01-01 22:54:31 -04:00
bool get_wp ( Location & loc ) override ;
2018-02-07 22:21:09 -04:00
void run_autopilot ( ) override ;
2017-12-05 21:28:32 -04:00
2016-03-21 00:45:50 -03:00
private :
2018-04-24 20:31:01 -03:00
bool start_command ( const AP_Mission : : Mission_Command & cmd ) ;
2017-12-10 22:50:49 -04:00
bool verify_command ( const AP_Mission : : Mission_Command & cmd ) ;
2018-04-24 20:31:01 -03:00
void exit_mission ( ) ;
2017-12-10 22:50:49 -04:00
2016-03-21 00:45:50 -03:00
void takeoff_run ( ) ;
void wp_run ( ) ;
void spline_run ( ) ;
void land_run ( ) ;
void rtl_run ( ) ;
void circle_run ( ) ;
void nav_guided_run ( ) ;
void loiter_run ( ) ;
2018-07-25 00:39:43 -03:00
void loiter_to_alt_run ( ) ;
2016-03-21 00:45:50 -03:00
2019-01-01 22:54:31 -04:00
Location loc_from_cmd ( const AP_Mission : : Mission_Command & cmd ) const ;
2018-10-03 00:33:03 -03:00
2016-03-21 00:45:50 -03:00
void payload_place_start ( const Vector3f & destination ) ;
void payload_place_run ( ) ;
bool payload_place_run_should_run ( ) ;
void payload_place_run_loiter ( ) ;
void payload_place_run_descend ( ) ;
void payload_place_run_release ( ) ;
AutoMode _mode = Auto_TakeOff ; // controls which auto controller is run
2019-01-01 22:54:31 -04:00
Location terrain_adjusted_location ( const AP_Mission : : Mission_Command & cmd ) const ;
2017-12-10 22:50:49 -04:00
void do_takeoff ( const AP_Mission : : Mission_Command & cmd ) ;
void do_nav_wp ( const AP_Mission : : Mission_Command & cmd ) ;
void do_land ( const AP_Mission : : Mission_Command & cmd ) ;
void do_loiter_unlimited ( const AP_Mission : : Mission_Command & cmd ) ;
void do_circle ( const AP_Mission : : Mission_Command & cmd ) ;
void do_loiter_time ( const AP_Mission : : Mission_Command & cmd ) ;
2018-07-25 00:39:43 -03:00
void do_loiter_to_alt ( const AP_Mission : : Mission_Command & cmd ) ;
2017-12-10 22:50:49 -04:00
void do_spline_wp ( const AP_Mission : : Mission_Command & cmd ) ;
# if NAV_GUIDED == ENABLED
void do_nav_guided_enable ( const AP_Mission : : Mission_Command & cmd ) ;
void do_guided_limits ( const AP_Mission : : Mission_Command & cmd ) ;
# endif
void do_nav_delay ( const AP_Mission : : Mission_Command & cmd ) ;
void do_wait_delay ( const AP_Mission : : Mission_Command & cmd ) ;
void do_within_distance ( const AP_Mission : : Mission_Command & cmd ) ;
void do_yaw ( const AP_Mission : : Mission_Command & cmd ) ;
void do_change_speed ( const AP_Mission : : Mission_Command & cmd ) ;
void do_set_home ( const AP_Mission : : Mission_Command & cmd ) ;
void do_roi ( const AP_Mission : : Mission_Command & cmd ) ;
void do_mount_control ( const AP_Mission : : Mission_Command & cmd ) ;
# if PARACHUTE == ENABLED
void do_parachute ( const AP_Mission : : Mission_Command & cmd ) ;
# endif
2018-02-10 10:23:06 -04:00
# if WINCH_ENABLED == ENABLED
2017-12-10 22:50:49 -04:00
void do_winch ( const AP_Mission : : Mission_Command & cmd ) ;
2018-02-10 10:23:06 -04:00
# endif
2017-12-10 22:50:49 -04:00
void do_payload_place ( const AP_Mission : : Mission_Command & cmd ) ;
void do_RTL ( void ) ;
bool verify_takeoff ( ) ;
bool verify_land ( ) ;
bool verify_payload_place ( ) ;
bool verify_loiter_unlimited ( ) ;
2019-02-25 16:38:38 -04:00
bool verify_loiter_time ( const AP_Mission : : Mission_Command & cmd ) ;
2018-07-25 00:39:43 -03:00
bool verify_loiter_to_alt ( ) ;
2017-12-10 22:50:49 -04:00
bool verify_RTL ( ) ;
bool verify_wait_delay ( ) ;
bool verify_within_distance ( ) ;
bool verify_yaw ( ) ;
bool verify_nav_wp ( const AP_Mission : : Mission_Command & cmd ) ;
bool verify_circle ( const AP_Mission : : Mission_Command & cmd ) ;
bool verify_spline_wp ( const AP_Mission : : Mission_Command & cmd ) ;
# if NAV_GUIDED == ENABLED
bool verify_nav_guided_enable ( const AP_Mission : : Mission_Command & cmd ) ;
# endif
bool verify_nav_delay ( const AP_Mission : : Mission_Command & cmd ) ;
// Loiter control
uint16_t loiter_time_max ; // How long we should stay in Loiter Mode for mission scripting (time in seconds)
uint32_t loiter_time ; // How long have we been loitering - The start time in millis
2018-07-25 00:39:43 -03:00
struct {
bool reached_destination_xy : 1 ;
bool loiter_start_done : 1 ;
bool reached_alt : 1 ;
float alt_error_cm ;
int32_t alt ;
} loiter_to_alt ;
2017-12-10 22:50:49 -04:00
// Delay the next navigation command
2019-08-08 11:10:20 -03:00
uint32_t nav_delay_time_max_ms ; // used for delaying the navigation commands (eg land,takeoff etc.)
uint32_t nav_delay_time_start_ms ;
2017-12-10 22:50:49 -04:00
// Delay Mission Scripting Command
int32_t condition_value ; // used in condition commands (eg delay, change alt, etc.)
uint32_t condition_start ;
LandStateType land_state = LandStateType_FlyToLocation ; // records state of land (flying to location, descending)
struct {
PayloadPlaceStateType state = PayloadPlaceStateType_Calibrating_Hover_Start ; // records state of place (descending, releasing, released, ...)
uint32_t hover_start_timestamp ; // milliseconds
float hover_throttle_level ;
uint32_t descend_start_timestamp ; // milliseconds
uint32_t place_start_timestamp ; // milliseconds
float descend_throttle_level ;
float descend_start_altitude ;
float descend_max ; // centimetres
} nav_payload_place ;
2016-03-21 00:45:50 -03:00
} ;
2016-03-21 07:41:37 -03:00
2017-12-10 23:10:48 -04:00
# if AUTOTUNE_ENABLED == ENABLED
2018-12-12 23:53:56 -04:00
/*
wrapper class for AC_AutoTune
*/
class AutoTune : public AC_AutoTune
{
public :
bool init ( ) override ;
void run ( ) override ;
protected :
bool start ( void ) override ;
bool position_ok ( ) override ;
float get_pilot_desired_climb_rate_cms ( void ) const override ;
2019-02-28 07:10:05 -04:00
void get_pilot_desired_rp_yrate_cd ( float & roll_cd , float & pitch_cd , float & yaw_rate_cds ) override ;
2018-12-12 23:53:56 -04:00
void init_z_limits ( ) override ;
void Log_Write_Event ( enum at_event id ) override ;
2018-12-21 22:26:45 -04:00
void log_pids ( ) override ;
2018-12-12 23:53:56 -04:00
} ;
2017-12-10 23:51:13 -04:00
class ModeAutoTune : public Mode {
2016-03-21 07:41:37 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-21 07:41:37 -03:00
bool init ( bool ignore_checks ) override ;
2018-12-12 23:53:56 -04:00
void run ( ) override ;
2019-04-18 20:41:30 -03:00
2017-12-10 23:10:48 -04:00
bool requires_GPS ( ) const override { return false ; }
2016-03-21 07:41:37 -03:00
bool has_manual_throttle ( ) const override { return false ; }
2017-11-10 00:50:34 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool is_autopilot ( ) const override { return false ; }
2019-04-18 20:41:30 -03:00
2017-12-10 23:10:48 -04:00
void save_tuning_gains ( ) ;
void stop ( ) ;
2019-05-01 09:27:40 -03:00
void reset ( ) ;
2016-03-21 07:41:37 -03:00
2017-12-10 23:10:48 -04:00
protected :
const char * name ( ) const override { return " AUTOTUNE " ; }
const char * name4 ( ) const override { return " ATUN " ; }
} ;
# endif
2017-12-10 23:51:13 -04:00
class ModeBrake : public Mode {
2016-03-21 21:42:21 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-21 21:42:21 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-03-21 21:42:21 -03:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
2016-03-21 21:42:21 -03:00
bool is_autopilot ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
void timeout_to_loiter_ms ( uint32_t timeout_ms ) ;
2016-03-21 21:42:21 -03:00
protected :
2017-12-10 23:10:48 -04:00
const char * name ( ) const override { return " BRAKE " ; }
const char * name4 ( ) const override { return " BRAK " ; }
2016-03-21 21:42:21 -03:00
private :
2019-06-12 03:42:55 -03:00
void init_target ( ) ;
2017-12-10 23:10:48 -04:00
uint32_t _timeout_start ;
uint32_t _timeout_ms ;
2016-03-21 21:42:21 -03:00
} ;
2016-03-21 23:13:34 -03:00
2017-12-10 23:51:13 -04:00
class ModeCircle : public Mode {
2016-03-21 23:13:34 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-21 23:13:34 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-03-21 23:13:34 -03:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
2016-03-21 23:13:34 -03:00
bool is_autopilot ( ) const override { return true ; }
2017-12-10 23:10:48 -04:00
protected :
2016-03-21 23:13:34 -03:00
2017-12-10 23:10:48 -04:00
const char * name ( ) const override { return " CIRCLE " ; }
const char * name4 ( ) const override { return " CIRC " ; }
2018-02-07 22:21:09 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2017-12-10 23:10:48 -04:00
private :
// Circle
bool pilot_yaw_override = false ; // true if pilot is overriding yaw
} ;
2017-12-10 23:51:13 -04:00
class ModeDrift : public Mode {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2017-12-10 23:10:48 -04:00
2018-02-08 18:50:59 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2017-12-10 23:10:48 -04:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
protected :
const char * name ( ) const override { return " DRIFT " ; }
const char * name4 ( ) const override { return " DRIF " ; }
private :
float get_throttle_assist ( float velz , float pilot_throttle_scaled ) ;
} ;
2017-12-10 23:51:13 -04:00
class ModeFlip : public Mode {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2017-12-10 23:10:48 -04:00
2018-02-08 18:50:59 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2017-12-10 23:10:48 -04:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
bool is_autopilot ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
protected :
const char * name ( ) const override { return " FLIP " ; }
const char * name4 ( ) const override { return " FLIP " ; }
private :
// Flip
2019-02-02 00:19:03 -04:00
Vector3f orig_attitude ; // original vehicle attitude before flip
2019-04-08 00:20:47 -03:00
enum class FlipState : uint8_t {
Start ,
Roll ,
Pitch_A ,
Pitch_B ,
Recover ,
Abandon
2019-02-02 00:19:03 -04:00
} ;
FlipState _state ; // current state of flip
2019-09-07 20:33:56 -03:00
Mode : : Number orig_control_mode ; // flight mode when flip was initated
2019-02-02 00:19:03 -04:00
uint32_t start_time_ms ; // time since flip began
int8_t roll_dir ; // roll direction (-1 = roll left, 1 = roll right)
int8_t pitch_dir ; // pitch direction (-1 = pitch forward, 1 = pitch back)
2017-12-10 23:10:48 -04:00
} ;
2018-02-11 23:26:09 -04:00
# if !HAL_MINIMIZE_FEATURES && OPTFLOW == ENABLED
2018-02-08 08:21:10 -04:00
/*
class to support FLOWHOLD mode , which is a position hold mode using
optical flow directly , avoiding the need for a rangefinder
*/
class ModeFlowHold : public Mode {
public :
// need a constructor for parameters
ModeFlowHold ( void ) ;
bool init ( bool ignore_checks ) override ;
void run ( void ) override ;
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override {
return ! must_navigate ;
}
2018-02-08 08:21:10 -04:00
static const struct AP_Param : : GroupInfo var_info [ ] ;
protected :
const char * name ( ) const override { return " FLOWHOLD " ; }
const char * name4 ( ) const override { return " FHLD " ; }
private :
// FlowHold states
enum FlowHoldModeState {
FlowHold_MotorStopped ,
FlowHold_Takeoff ,
FlowHold_Flying ,
FlowHold_Landed
} ;
// calculate attitude from flow data
void flow_to_angle ( Vector2f & bf_angle ) ;
LowPassFilterVector2f flow_filter ;
bool flowhold_init ( bool ignore_checks ) ;
void flowhold_run ( ) ;
void flowhold_flow_to_angle ( Vector2f & angle , bool stick_input ) ;
void update_height_estimate ( void ) ;
// minimum assumed height
2019-04-04 02:41:10 -03:00
const float height_min = 0.1f ;
2018-02-08 08:21:10 -04:00
// maximum scaling height
2019-04-04 02:41:10 -03:00
const float height_max = 3.0f ;
2018-02-08 08:21:10 -04:00
AP_Float flow_max ;
2019-04-04 02:41:10 -03:00
AC_PI_2D flow_pi_xy { 0.2f , 0.3f , 3000 , 5 , 0.0025f } ;
2018-02-08 08:21:10 -04:00
AP_Float flow_filter_hz ;
AP_Int8 flow_min_quality ;
AP_Int8 brake_rate_dps ;
float quality_filtered ;
uint8_t log_counter ;
bool limited ;
Vector2f xy_I ;
// accumulated INS delta velocity in north-east form since last flow update
Vector2f delta_velocity_ne ;
// last flow rate in radians/sec in north-east axis
Vector2f last_flow_rate_rps ;
// timestamp of last flow data
uint32_t last_flow_ms ;
float last_ins_height ;
float height_offset ;
// are we braking after pilot input?
bool braking ;
// last time there was significant stick input
uint32_t last_stick_input_ms ;
} ;
# endif // OPTFLOW
2017-12-10 23:51:13 -04:00
class ModeGuided : public Mode {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2017-12-10 23:10:48 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2017-11-10 00:50:34 -04:00
bool allows_arming ( bool from_gcs ) const override { return from_gcs ; }
2017-12-10 23:10:48 -04:00
bool is_autopilot ( ) const override { return true ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override { return true ; }
2019-04-18 20:41:30 -03:00
bool in_guided_mode ( ) const override { return true ; }
2017-12-10 23:10:48 -04:00
void set_angle ( const Quaternion & q , float climb_rate_cms , bool use_yaw_rate , float yaw_rate_rads ) ;
bool 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 ) ;
2019-01-01 22:54:31 -04:00
bool 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 ) ;
bool get_wp ( Location & loc ) override ;
2018-02-06 02:16:09 -04:00
void 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 ) ;
2017-12-10 23:10:48 -04:00
bool 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 ) ;
void limit_clear ( ) ;
void limit_init_time_and_pos ( ) ;
2016-03-21 23:13:34 -03:00
void limit_set ( uint32_t timeout_ms , float alt_min_cm , float alt_max_cm , float horiz_max_cm ) ;
bool limit_check ( ) ;
2018-04-30 06:50:04 -03:00
bool is_taking_off ( ) const override ;
2017-12-12 06:09:48 -04:00
bool do_user_takeoff_start ( float final_alt_above_home ) override ;
2016-03-21 23:13:34 -03:00
2017-12-05 21:28:32 -04:00
GuidedMode mode ( ) const { return guided_mode ; }
2016-03-21 23:13:34 -03:00
void angle_control_start ( ) ;
void angle_control_run ( ) ;
protected :
const char * name ( ) const override { return " GUIDED " ; }
const char * name4 ( ) const override { return " GUID " ; }
2017-12-05 21:28:32 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2018-05-23 12:34:24 -03:00
float crosstrack_error ( ) const override ;
2017-12-05 21:28:32 -04:00
2016-03-21 23:13:34 -03:00
private :
void pos_control_start ( ) ;
void vel_control_start ( ) ;
void posvel_control_start ( ) ;
void takeoff_run ( ) ;
void pos_control_run ( ) ;
void vel_control_run ( ) ;
void posvel_control_run ( ) ;
void set_desired_velocity_with_accel_and_fence_limits ( const Vector3f & vel_des ) ;
void set_yaw_state ( bool use_yaw , float yaw_cd , bool use_yaw_rate , float yaw_rate_cds , bool relative_angle ) ;
// controls which controller is run (pos or vel):
GuidedMode guided_mode = Guided_TakeOff ;
} ;
2016-03-22 00:24:56 -03:00
2017-12-10 23:51:13 -04:00
class ModeGuidedNoGPS : public ModeGuided {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeGuided : : Mode ;
2017-12-10 23:10:48 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2019-02-05 21:33:36 -04:00
bool requires_GPS ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool has_manual_throttle ( ) const override { return false ; }
2017-11-10 00:50:34 -04:00
bool allows_arming ( bool from_gcs ) const override { return from_gcs ; }
2017-12-10 23:10:48 -04:00
bool is_autopilot ( ) const override { return true ; }
protected :
const char * name ( ) const override { return " GUIDED_NOGPS " ; }
const char * name4 ( ) const override { return " GNGP " ; }
private :
} ;
2016-03-22 00:24:56 -03:00
2017-12-10 23:51:13 -04:00
class ModeLand : public Mode {
2016-03-22 00:24:56 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-22 00:24:56 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-03-22 00:24:56 -03:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
bool is_autopilot ( ) const override { return true ; }
2019-04-18 20:41:30 -03:00
2018-04-30 06:50:04 -03:00
bool is_landing ( ) const override { return true ; } ;
2017-12-06 07:18:34 -04:00
bool landing_gear_should_be_deployed ( ) const override { return true ; } ;
2016-03-22 00:24:56 -03:00
void do_not_use_GPS ( ) ;
protected :
const char * name ( ) const override { return " LAND " ; }
const char * name4 ( ) const override { return " LAND " ; }
private :
void gps_run ( ) ;
void nogps_run ( ) ;
} ;
2016-03-22 03:42:17 -03:00
2017-12-10 23:51:13 -04:00
class ModeLoiter : public Mode {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2017-12-10 23:10:48 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override { return true ; }
2017-12-10 23:10:48 -04:00
# if PRECISION_LANDING == ENABLED
void set_precision_loiter_enabled ( bool value ) { _precision_loiter_enabled = value ; }
# endif
protected :
const char * name ( ) const override { return " LOITER " ; }
const char * name4 ( ) const override { return " LOIT " ; }
2018-02-07 22:21:09 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2017-12-10 23:10:48 -04:00
# if PRECISION_LANDING == ENABLED
bool do_precision_loiter ( ) ;
void precision_loiter_xy ( ) ;
# endif
private :
# if PRECISION_LANDING == ENABLED
bool _precision_loiter_enabled ;
# endif
} ;
2017-12-10 23:51:13 -04:00
class ModePosHold : public Mode {
2017-12-10 23:10:48 -04:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2017-12-10 23:10:48 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override { return true ; }
2017-12-10 23:10:48 -04:00
protected :
const char * name ( ) const override { return " POSHOLD " ; }
const char * name4 ( ) const override { return " PHLD " ; }
private :
2019-04-22 22:54:48 -03:00
void update_pilot_lean_angle ( float & lean_angle_filtered , float & lean_angle_raw ) ;
2019-07-07 10:13:43 -03:00
float mix_controls ( float mix_ratio , float first_control , float second_control ) ;
void update_brake_angle_from_velocity ( float & brake_angle , float velocity ) ;
2019-04-22 22:54:48 -03:00
void update_wind_comp_estimate ( ) ;
2019-07-07 10:13:43 -03:00
void get_wind_comp_lean_angles ( float & roll_angle , float & pitch_angle ) ;
2019-04-22 22:54:48 -03:00
void roll_controller_to_pilot_override ( ) ;
void pitch_controller_to_pilot_override ( ) ;
2017-12-10 23:10:48 -04:00
2019-04-22 23:14:35 -03:00
enum class RPMode {
PILOT_OVERRIDE = 0 , // pilot is controlling this axis (i.e. roll or pitch)
BRAKE , // this axis is braking towards zero
BRAKE_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)
BRAKE_TO_LOITER , // both vehicle's axis (roll and pitch) are transitioning from braking to loiter mode (braking and loiter controls are mixed)
LOITER , // both vehicle axis are holding position
CONTROLLER_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)
2019-04-22 22:48:41 -03:00
} ;
2019-04-22 23:14:35 -03:00
RPMode roll_mode ;
RPMode pitch_mode ;
2019-04-22 22:48:41 -03:00
uint8_t braking_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 braking
uint8_t braking_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 braking
// pilot input related variables
float pilot_roll ; // pilot requested roll angle (filtered to slow returns to zero)
float pilot_pitch ; // pilot requested roll angle (filtered to slow returns to zero)
// braking related variables
float brake_gain ; // gain used during conversion of vehicle's velocity to lean angle during braking (calculated from brake_rate)
2019-07-07 10:13:43 -03:00
float brake_roll ; // target roll angle during braking periods
float brake_pitch ; // target pitch angle during braking periods
2019-04-22 22:48:41 -03:00
int16_t brake_timeout_roll ; // number of cycles allowed for the braking to complete, this timeout will be updated at half-braking
int16_t brake_timeout_pitch ; // number of cycles allowed for the braking to complete, this timeout will be updated at half-braking
2019-07-07 10:13:43 -03:00
float brake_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 time
float brake_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 time
2019-04-22 22:48:41 -03:00
int16_t brake_to_loiter_timer ; // cycles to mix brake and loiter controls in POSHOLD_BRAKE_TO_LOITER
// loiter related variables
int16_t controller_to_pilot_timer_roll ; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT
int16_t controller_to_pilot_timer_pitch ; // cycles to mix controller and pilot controls in POSHOLD_CONTROLLER_TO_PILOT
2019-07-07 10:13:43 -03:00
float controller_final_roll ; // final roll angle from controller as we exit brake or loiter mode (used for mixing with pilot input)
float controller_final_pitch ; // final pitch angle from controller as we exit brake or loiter mode (used for mixing with pilot input)
2019-04-22 22:48:41 -03:00
// wind compensation related variables
Vector2f wind_comp_ef ; // wind compensation in earth frame, filtered lean angles from position controller
2019-07-07 10:13:43 -03:00
float wind_comp_roll ; // roll angle to compensate for wind
float wind_comp_pitch ; // pitch angle to compensate for wind
2019-04-22 22:48:41 -03:00
uint16_t wind_comp_start_timer ; // counter to delay start of wind compensation for a short time after loiter is engaged
int8_t wind_comp_timer ; // counter to reduce wind comp roll/pitch lean angle calcs to 10hz
// final output
2019-07-07 10:13:43 -03:00
float roll ; // final roll angle sent to attitude controller
float pitch ; // final pitch angle sent to attitude controller
2019-04-22 22:48:41 -03:00
2017-12-10 23:10:48 -04:00
} ;
2016-03-22 03:42:17 -03:00
2017-12-10 23:51:13 -04:00
class ModeRTL : public Mode {
2016-03-22 03:42:17 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-22 03:42:17 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override {
2016-03-22 03:42:17 -03:00
return run ( true ) ;
}
2017-11-09 22:54:34 -04:00
void run ( bool disarm_on_land ) ;
2016-03-22 03:42:17 -03:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2018-01-24 20:34:57 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; } ;
2016-03-22 03:42:17 -03:00
bool is_autopilot ( ) const override { return true ; }
2019-06-05 07:47:32 -03:00
// for reporting to GCS
bool get_wp ( Location & loc ) override ;
2016-03-22 03:42:17 -03:00
RTLState state ( ) { return _state ; }
// this should probably not be exposed
bool state_complete ( ) { return _state_complete ; }
2018-04-30 06:50:04 -03:00
bool is_landing ( ) const override ;
2017-12-06 07:18:34 -04:00
bool landing_gear_should_be_deployed ( ) const override ;
2016-03-22 03:42:17 -03:00
void restart_without_terrain ( ) ;
protected :
const char * name ( ) const override { return " RTL " ; }
const char * name4 ( ) const override { return " RTL " ; }
2019-06-05 07:47:32 -03:00
// for reporting to GCS
2018-02-07 22:21:09 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2018-05-23 12:34:24 -03:00
float crosstrack_error ( ) const override { return wp_nav - > crosstrack_error ( ) ; }
2017-12-05 21:28:32 -04:00
2017-09-10 20:46:51 -03:00
void descent_start ( ) ;
void descent_run ( ) ;
void land_start ( ) ;
void land_run ( bool disarm_on_land ) ;
void set_descent_target_alt ( uint32_t alt ) { rtl_path . descent_target . alt = alt ; }
2016-03-22 03:42:17 -03:00
private :
void climb_start ( ) ;
void return_start ( ) ;
void climb_return_run ( ) ;
void loiterathome_start ( ) ;
void loiterathome_run ( ) ;
2018-10-25 23:10:32 -03:00
void build_path ( ) ;
void compute_return_target ( ) ;
2016-03-22 03:42:17 -03:00
RTLState _state = RTL_InitialClimb ; // records state of rtl (initial climb, returning home, etc)
bool _state_complete = false ; // set to true if the current state is completed
struct {
// NEU w/ Z element alt-above-ekf-origin unless use_terrain is true in which case Z element is alt-above-terrain
2019-01-01 22:54:31 -04:00
Location origin_point ;
Location climb_target ;
Location return_target ;
Location descent_target ;
2016-03-22 03:42:17 -03:00
bool land ;
bool terrain_used ;
} rtl_path ;
// Loiter timer - Records how long we have been in loiter
2018-10-25 22:28:03 -03:00
uint32_t _loiter_start_time ;
2018-10-25 23:10:32 -03:00
bool terrain_following_allowed ;
2016-03-22 03:42:17 -03:00
} ;
2016-03-22 03:56:08 -03:00
2017-12-10 23:51:13 -04:00
class ModeSmartRTL : public ModeRTL {
2016-03-22 03:56:08 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeRTL : : Mode ;
2016-03-22 03:56:08 -03:00
2017-12-10 23:10:48 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2016-03-22 03:56:08 -03:00
2017-12-10 23:10:48 -04:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2017-11-10 00:50:34 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool is_autopilot ( ) const override { return true ; }
void save_position ( ) ;
void exit ( ) ;
2016-03-22 03:56:08 -03:00
protected :
2017-12-10 23:10:48 -04:00
const char * name ( ) const override { return " SMARTRTL " ; }
const char * name4 ( ) const override { return " SRTL " ; }
2019-06-05 07:47:32 -03:00
// for reporting to GCS
bool get_wp ( Location & loc ) override ;
2018-02-07 22:21:09 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2018-05-23 12:34:24 -03:00
float crosstrack_error ( ) const override { return wp_nav - > crosstrack_error ( ) ; }
2016-03-22 03:56:08 -03:00
private :
2017-12-10 23:10:48 -04:00
void wait_cleanup_run ( ) ;
void path_follow_run ( ) ;
void pre_land_position_run ( ) ;
void land ( ) ;
SmartRTLState smart_rtl_state = SmartRTL_PathFollow ;
2016-03-22 03:56:08 -03:00
} ;
2016-03-22 05:07:23 -03:00
2017-12-10 23:51:13 -04:00
class ModeSport : public Mode {
2016-03-22 05:07:23 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-22 05:07:23 -03:00
2018-02-08 18:50:59 -04:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
2016-03-22 05:07:23 -03:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-05-01 00:29:31 -03:00
bool has_user_takeoff ( bool must_navigate ) const override {
return ! must_navigate ;
}
2016-03-22 05:07:23 -03:00
protected :
const char * name ( ) const override { return " SPORT " ; }
const char * name4 ( ) const override { return " SPRT " ; }
private :
} ;
2016-03-22 07:41:38 -03:00
2017-12-10 23:51:13 -04:00
class ModeStabilize : public Mode {
2016-03-22 07:41:38 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-03-22 07:41:38 -03:00
2017-11-09 22:54:34 -04:00
virtual void run ( ) override ;
2016-03-22 07:41:38 -03:00
2018-02-08 18:50:59 -04:00
bool requires_GPS ( ) const override { return false ; }
bool has_manual_throttle ( ) const override { return true ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2016-03-22 07:41:38 -03:00
protected :
2017-12-10 23:10:48 -04:00
const char * name ( ) const override { return " STABILIZE " ; }
const char * name4 ( ) const override { return " STAB " ; }
2016-03-22 20:36:52 -03:00
private :
} ;
2016-03-22 21:51:39 -03:00
2017-12-10 23:10:48 -04:00
# if FRAME_CONFIG == HELI_FRAME
2017-12-10 23:51:13 -04:00
class ModeStabilize_Heli : public ModeStabilize {
2016-03-22 21:51:39 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeStabilize : : Mode ;
2016-03-22 21:51:39 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-03-22 21:51:39 -03:00
protected :
private :
} ;
# endif
2016-03-22 22:00:19 -03:00
2019-07-29 04:55:40 -03:00
class ModeSystemId : public Mode {
public :
ModeSystemId ( void ) ;
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
bool stop_attitude_logging ( ) const override { return true ; }
void set_magnitude ( float input ) { waveform_magnitude = input ; }
static const struct AP_Param : : GroupInfo var_info [ ] ;
protected :
const char * name ( ) const override { return " SYSTEMID " ; }
const char * name4 ( ) const override { return " SYSI " ; }
private :
void log_data ( ) ;
float waveform ( float time ) ;
enum AxisType {
NONE = 0 , // none
INPUT_ROLL = 1 , // angle input roll axis is being excited
INPUT_PITCH = 2 , // angle pitch axis is being excited
INPUT_YAW = 3 , // angle yaw axis is being excited
RECOVER_ROLL = 4 , // angle roll axis is being excited
RECOVER_PITCH = 5 , // angle pitch axis is being excited
RECOVER_YAW = 6 , // angle yaw axis is being excited
RATE_ROLL = 7 , // rate roll axis is being excited
RATE_PITCH = 8 , // rate pitch axis is being excited
RATE_YAW = 9 , // rate yaw axis is being excited
MIX_ROLL = 10 , // mixer roll axis is being excited
MIX_PITCH = 11 , // mixer pitch axis is being excited
MIX_YAW = 12 , // mixer pitch axis is being excited
MIX_THROTTLE = 13 , // mixer throttle axis is being excited
} ;
AP_Int8 systemID_axis ; // Controls which axis are being excited
AP_Float waveform_magnitude ; // Magnitude of chirp waveform
AP_Float frequency_start ; // Frequency at the start of the chirp
AP_Float frequency_stop ; // Frequency at the end of the chirp
AP_Float time_fade_in ; // Time to reach maximum amplitude of chirp
AP_Float time_record ; // Time taken to complete the chirp waveform
AP_Float time_fade_out ; // Time to reach zero amplitude after chirp finishes
bool att_bf_feedforward ; // Setting of attitude_control->get_bf_feedforward
float waveform_time ; // Time reference for waveform
float waveform_sample ; // Current waveform sample
float waveform_freq_rads ; // Instantaneous waveform frequency
float time_const_freq ; // Time at constant frequency before chirp starts
int8_t log_subsample ; // Subsample multiple for logging.
// System ID states
enum SystemIDModeState {
SystemID_Stopped ,
SystemID_Testing
} ;
SystemIDModeState systemIDState ;
} ;
2016-03-22 22:00:19 -03:00
2017-12-10 23:51:13 -04:00
class ModeThrow : public Mode {
2016-08-02 23:30:27 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2016-08-02 23:30:27 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2016-08-02 23:30:27 -03:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return true ; } ;
bool is_autopilot ( ) const override { return false ; }
2017-12-13 05:57:38 -04:00
// Throw types
enum ThrowModeType {
ThrowType_Upward = 0 ,
ThrowType_Drop = 1
} ;
2016-08-02 23:30:27 -03:00
protected :
const char * name ( ) const override { return " THROW " ; }
const char * name4 ( ) const override { return " THRW " ; }
private :
bool throw_detected ( ) ;
bool throw_position_good ( ) ;
bool throw_height_good ( ) ;
bool throw_attitude_good ( ) ;
2017-12-13 05:57:38 -04:00
// Throw stages
enum ThrowModeStage {
Throw_Disarmed ,
Throw_Detecting ,
Throw_Uprighting ,
Throw_HgtStabilise ,
Throw_PosHold
} ;
2016-08-02 23:30:27 -03:00
ThrowModeStage stage = Throw_Disarmed ;
ThrowModeStage prev_stage = Throw_Disarmed ;
uint32_t last_log_ms ;
bool nextmode_attempted ;
uint32_t free_fall_start_ms ; // system time free fall was detected
float free_fall_start_velz ; // vertical velocity when free fall was detected
} ;
2016-08-02 23:41:10 -03:00
2018-02-05 22:44:05 -04:00
// modes below rely on Guided mode so must be declared at the end (instead of in alphabetical order)
2016-08-02 23:41:10 -03:00
2017-12-10 23:51:13 -04:00
class ModeAvoidADSB : public ModeGuided {
2017-09-10 20:46:51 -03:00
public :
2018-02-07 22:21:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeGuided : : Mode ;
2017-09-10 20:46:51 -03:00
bool init ( bool ignore_checks ) override ;
2017-11-09 22:54:34 -04:00
void run ( ) override ;
2017-09-10 20:46:51 -03:00
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
2017-12-10 23:10:48 -04:00
bool allows_arming ( bool from_gcs ) const override { return false ; }
2017-09-10 20:46:51 -03:00
bool is_autopilot ( ) const override { return true ; }
2017-12-10 23:10:48 -04:00
bool set_velocity ( const Vector3f & velocity_neu ) ;
2017-09-10 20:46:51 -03:00
protected :
2017-12-10 23:10:48 -04:00
const char * name ( ) const override { return " AVOID_ADSB " ; }
const char * name4 ( ) const override { return " AVOI " ; }
2017-12-05 21:28:32 -04:00
2017-09-10 20:46:51 -03:00
private :
} ;
2017-12-26 19:09:11 -04:00
2018-02-05 22:44:05 -04:00
class ModeFollow : public ModeGuided {
2017-12-26 19:09:11 -04:00
public :
2018-02-06 02:16:09 -04:00
// inherit constructor
2019-05-09 23:18:49 -03:00
using ModeGuided : : Mode ;
2017-12-26 19:09:11 -04:00
bool init ( bool ignore_checks ) override ;
2019-10-03 22:24:51 -03:00
void exit ( ) ;
2017-12-26 19:09:11 -04:00
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return false ; }
bool is_autopilot ( ) const override { return true ; }
protected :
2018-02-05 22:44:05 -04:00
const char * name ( ) const override { return " FOLLOW " ; }
const char * name4 ( ) const override { return " FOLL " ; }
2019-06-05 07:47:32 -03:00
// for reporting to GCS
bool get_wp ( Location & loc ) override ;
2018-12-11 05:37:30 -04:00
uint32_t wp_distance ( ) const override ;
int32_t wp_bearing ( ) const override ;
2018-02-06 02:16:09 -04:00
uint32_t last_log_ms ; // system time of last time desired velocity was logging
2017-12-26 19:09:11 -04:00
} ;
2018-09-07 01:23:33 -03:00
class ModeZigZag : public Mode {
public :
// inherit constructor
2019-05-09 23:18:49 -03:00
using Mode : : Mode ;
2018-09-07 01:23:33 -03:00
bool init ( bool ignore_checks ) override ;
void run ( ) override ;
bool requires_GPS ( ) const override { return true ; }
bool has_manual_throttle ( ) const override { return false ; }
bool allows_arming ( bool from_gcs ) const override { return false ; }
bool is_autopilot ( ) const override { return true ; }
2018-09-29 06:25:31 -03:00
// save current position as A (dest_num = 0) or B (dest_num = 1). If both A and B have been saved move to the one specified
void save_or_move_to_destination ( uint8_t dest_num ) ;
// return manual control to the pilot
2019-04-11 01:34:30 -03:00
void return_to_manual_control ( bool maintain_target ) ;
2018-09-07 01:23:33 -03:00
protected :
const char * name ( ) const override { return " ZIGZAG " ; }
const char * name4 ( ) const override { return " ZIGZ " ; }
private :
void auto_control ( ) ;
void manual_control ( ) ;
2018-09-29 06:25:31 -03:00
bool reached_destination ( ) ;
2019-04-11 01:34:30 -03:00
bool calculate_next_dest ( uint8_t position_num , bool use_wpnav_alt , Vector3f & next_dest , bool & terrain_alt ) const ;
2018-09-07 01:23:33 -03:00
2018-09-29 06:25:31 -03:00
Vector2f dest_A ; // in NEU frame in cm relative to ekf origin
Vector2f dest_B ; // in NEU frame in cm relative to ekf origin
2018-09-07 01:23:33 -03:00
enum zigzag_state {
2018-09-29 06:25:31 -03:00
STORING_POINTS , // storing points A and B, pilot has manual control
AUTO , // after A and B defined, pilot toggle the switch from one side to the other, vehicle flies autonomously
MANUAL_REGAIN // pilot toggle the switch to middle position, has manual control
} stage ;
2018-09-07 01:23:33 -03:00
2018-09-29 06:25:31 -03:00
uint32_t reach_wp_time_ms = 0 ; // time since vehicle reached destination (or zero if not yet reached)
2018-09-07 01:23:33 -03:00
} ;