Line data Source code
1 : #pragma once
2 :
3 : #include "Copter.h"
4 : #include <AP_Math/chirp.h>
5 : #include <AP_ExternalControl/AP_ExternalControl_config.h> // TODO why is this needed if Copter.h includes this
6 : #include <AP_HAL/Semaphores.h>
7 :
8 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
9 : #include "afs_copter.h"
10 : #endif
11 :
12 : class Parameters;
13 : class ParametersG2;
14 :
15 : class GCS_Copter;
16 :
17 : // object shared by both Guided and Auto for takeoff.
18 : // position controller controls vehicle but the user can control the yaw.
19 : class _AutoTakeoff {
20 : public:
21 : void run();
22 : void start_m(float complete_alt_m, bool is_terrain_alt);
23 : bool get_completion_pos_ned_m(Vector3p& pos_ned_m);
24 :
25 : bool complete; // true when takeoff is complete
26 :
27 : private:
28 : // altitude above-ekf-origin below which auto takeoff does not control horizontal position
29 : bool no_nav_active;
30 : float no_nav_alt_m;
31 :
32 : // auto takeoff variables
33 : float complete_alt_m; // completion altitude expressed in m above ekf origin or above terrain (depending upon auto_takeoff_terrain_alt)
34 : bool is_terrain_alt; // true if altitudes are above terrain
35 : Vector3p complete_pos_ned_m; // target takeoff position as offset from ekf origin in m
36 : };
37 :
38 : #if AC_PAYLOAD_PLACE_ENABLED
39 : class PayloadPlace {
40 : public:
41 : void run();
42 : void start_descent();
43 : bool verify();
44 :
45 : enum class State : uint8_t {
46 : FlyToLocation,
47 : Descent_Start,
48 : Descent,
49 : Release,
50 : Releasing,
51 : Delay,
52 : Ascent_Start,
53 : Ascent,
54 : Done,
55 : };
56 :
57 : // these are set by the Mission code:
58 : State state = State::Descent_Start; // records state of payload place
59 : float descent_max_m;
60 :
61 : private:
62 :
63 : uint32_t descent_established_time_ms; // milliseconds
64 : uint32_t place_start_time_ms; // milliseconds
65 : float descent_thrust_level;
66 : float descent_start_altitude_m;
67 : float descent_speed_ms;
68 : };
69 : #endif
70 :
71 : class Mode {
72 : friend class PayloadPlace;
73 :
74 : public:
75 :
76 : // Auto Pilot Modes enumeration
77 : enum class Number : uint8_t {
78 : STABILIZE = 0, // manual airframe angle with manual throttle
79 : ACRO = 1, // manual body-frame angular rate with manual throttle
80 : ALT_HOLD = 2, // manual airframe angle with automatic throttle
81 : AUTO = 3, // fully automatic waypoint control using mission commands
82 : GUIDED = 4, // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands
83 : LOITER = 5, // automatic horizontal acceleration with automatic throttle
84 : RTL = 6, // automatic return to launching point
85 : CIRCLE = 7, // automatic circular flight with automatic throttle
86 : LAND = 9, // automatic landing with horizontal position control
87 : DRIFT = 11, // semi-autonomous position, yaw and throttle control
88 : SPORT = 13, // manual earth-frame angular rate control with manual throttle
89 : FLIP = 14, // automatically flip the vehicle on the roll axis
90 : AUTOTUNE = 15, // automatically tune the vehicle's roll and pitch gains
91 : POSHOLD = 16, // automatic position hold with manual override, with automatic throttle
92 : BRAKE = 17, // full-brake using inertial/GPS system, no pilot input
93 : THROW = 18, // throw to launch mode using inertial/GPS system, no pilot input
94 : AVOID_ADSB = 19, // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft
95 : GUIDED_NOGPS = 20, // guided mode but only accepts attitude and altitude
96 : SMART_RTL = 21, // SMART_RTL returns to home by retracing its steps
97 : FLOWHOLD = 22, // FLOWHOLD holds position with optical flow without rangefinder
98 : FOLLOW = 23, // follow attempts to follow another vehicle or ground station
99 : ZIGZAG = 24, // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B
100 : SYSTEMID = 25, // System ID mode produces automated system identification signals in the controllers
101 : AUTOROTATE = 26, // Autonomous autorotation
102 : AUTO_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 sequence
103 : TURTLE = 28, // Flip over after crash
104 :
105 : // Mode number 30 reserved for "offboard" for external/lua control.
106 :
107 : // Mode number 127 reserved for the "drone show mode" in the Skybrush
108 : // fork at https://github.com/skybrush-io/ardupilot
109 : };
110 :
111 : // constructor
112 : Mode(void);
113 :
114 : // do not allow copying
115 : CLASS_NO_COPY(Mode);
116 :
117 : friend class _AutoTakeoff;
118 :
119 : // returns a unique number specific to this mode
120 : virtual Number mode_number() const = 0;
121 :
122 : // child classes should override these methods
123 147 : virtual bool init(bool ignore_checks) {
124 147 : return true;
125 : }
126 1142 : virtual void exit() {};
127 : virtual void run() = 0;
128 : virtual bool requires_position() const = 0;
129 : virtual bool has_manual_throttle() const = 0;
130 : virtual bool allows_arming(AP_Arming::Method method) const = 0;
131 : virtual bool is_autopilot() const = 0;
132 1866449 : virtual bool has_user_takeoff(bool must_navigate) const { return false; }
133 2258 : virtual bool in_guided_mode() const { return false; }
134 2004728 : virtual bool logs_attitude() const { return false; }
135 0 : virtual bool allows_save_trim() const { return false; }
136 2 : virtual bool allows_auto_trim() const { return false; }
137 32 : virtual bool allows_autotune() const { return false; }
138 32 : virtual bool allows_flip() const { return false; }
139 18409822 : virtual bool crash_check_enabled() const { return true; }
140 21945806 : virtual bool move_vehicle_on_ekf_reset() const { return false; }
141 :
142 : // "no pilot input" here means eg. in RC failsafe
143 21 : virtual bool allows_entry_in_rc_failsafe() const { return true; }
144 :
145 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
146 : // Return the type of this mode for use by advanced failsafe
147 : virtual AP_AdvancedFailsafe_Copter::control_mode afs_mode() const { return AP_AdvancedFailsafe_Copter::control_mode::AFS_STABILIZED; }
148 : #endif
149 :
150 : // Return true if the throttle high arming check can be skipped when arming from GCS or Scripting
151 336 : virtual bool allows_GCS_or_SCR_arming_with_throttle_high() const { return false; }
152 :
153 : #if FRAME_CONFIG == HELI_FRAME
154 44 : virtual bool allows_inverted() const { return false; };
155 : #endif
156 :
157 : // return a string for this flightmode
158 : virtual const char *name() const = 0;
159 : virtual const char *name4() const = 0;
160 :
161 : bool do_user_takeoff_U_m(float takeoff_alt_m, bool must_navigate);
162 : virtual bool is_taking_off() const;
163 1267 : static void takeoff_stop() { takeoff.stop(); }
164 :
165 5520890 : virtual bool is_landing() const { return false; }
166 :
167 : // mode requires terrain to be present to be functional
168 0 : virtual bool requires_terrain_failsafe() const { return false; }
169 :
170 : // functions for reporting to GCS
171 217974 : virtual bool get_wp(Location &loc) const { return false; };
172 203827 : virtual float wp_bearing_deg() const { return 0; }
173 203827 : virtual float wp_distance_m() const { return 0.0f; }
174 205551 : virtual float crosstrack_error_m() const { return 0.0f;}
175 :
176 : // functions to support MAV_CMD_DO_CHANGE_SPEED
177 55 : virtual bool set_speed_NE_ms(float speed_ne_ms) {return false;}
178 0 : virtual bool set_speed_up_ms(float speed_up_ms) {return false;}
179 0 : virtual bool set_speed_down_ms(float speed_down_ms) {return false;}
180 :
181 : virtual float get_alt_above_ground_m(void) const;
182 :
183 : // pilot input processing
184 : void get_pilot_desired_lean_angles_rad(float &roll_out_rad, float &pitch_out_rad, float angle_max_rad, float angle_limit_rad) const;
185 : float get_pilot_desired_yaw_rate_rads() const;
186 : Vector2f get_pilot_desired_velocity(float vel_max) const;
187 : float get_pilot_desired_throttle() const;
188 :
189 : // returns climb target_rate reduced to avoid obstacles and
190 : // altitude fence
191 : float get_avoidance_adjusted_climbrate_ms(float target_rate_ms);
192 :
193 : // send output to the motors, can be overridden by subclasses
194 : virtual void output_to_motors();
195 :
196 : // returns true if pilot's yaw input should be used to adjust vehicle's heading
197 109882 : virtual bool use_pilot_yaw() const {return true; }
198 :
199 : // pause and resume a mode
200 0 : virtual bool pause() { return false; };
201 0 : virtual bool resume() { return false; };
202 :
203 : // handle situations where the vehicle is on the ground waiting for takeoff
204 : void make_safe_ground_handling(bool force_throttle_unlimited = false);
205 :
206 : // true if weathervaning is allowed in the current mode
207 : #if WEATHERVANE_ENABLED
208 5536646 : virtual bool allows_weathervaning() const { return false; }
209 : #endif
210 :
211 : // Return true if this mode is enabled, used by MAVLink available modes
212 : // For example flow hold mode requires optical flow to be enabled
213 1437296 : virtual bool enabled() const { return true; }
214 :
215 : protected:
216 :
217 : // helper functions
218 : bool is_disarmed_or_landed() const;
219 : void zero_throttle_and_relax_ac(bool spool_up = false);
220 : void zero_throttle_and_hold_attitude();
221 :
222 : // Return stopping point as a location with above origin alt frame
223 : Location get_stopping_point() const;
224 :
225 : // functions to control normal landing. pause_descent is true if vehicle should not descend
226 : void land_run_horizontal_control();
227 : void land_run_vertical_control(bool pause_descent = false);
228 4453760 : void land_run_horiz_and_vert_control(bool pause_descent = false) {
229 4453760 : land_run_horizontal_control();
230 4453760 : land_run_vertical_control(pause_descent);
231 4453760 : }
232 :
233 : #if AC_PAYLOAD_PLACE_ENABLED
234 : // payload place flight behaviour:
235 : static PayloadPlace payload_place;
236 : #endif
237 :
238 : // run normal or precision landing (if enabled)
239 : // pause_descent is true if vehicle should not descend
240 : void land_run_normal_or_precland(bool pause_descent = false);
241 :
242 : #if AC_PRECLAND_ENABLED
243 : // Go towards a position commanded by prec land state machine in order to retry landing
244 : // The passed in location is expected to be NED and in meters
245 : void precland_retry_position(const Vector3p &retry_pos);
246 :
247 : // Run precland statemachine. This function should be called from any mode that wants to do precision landing.
248 : // This handles everything from prec landing, to prec landing failures, to retries and failsafe measures
249 : void precland_run();
250 : #endif
251 :
252 : // return expected input throttle setting to hover:
253 : virtual float throttle_hover() const;
254 :
255 : // Alt_Hold based flight mode states used in Alt_Hold, Loiter, and Sport
256 : enum class AltHoldModeState {
257 : MotorStopped,
258 : Takeoff,
259 : Landed_Ground_Idle,
260 : Landed_Pre_Takeoff,
261 : Flying
262 : };
263 : AltHoldModeState get_alt_hold_state_D_ms(float target_climb_rate_ms);
264 :
265 : // convenience references to avoid code churn in conversion:
266 : Parameters &g;
267 : ParametersG2 &g2;
268 : AC_WPNav *&wp_nav;
269 : AC_Loiter *&loiter_nav;
270 : AC_PosControl *&pos_control;
271 : AP_AHRS &ahrs;
272 : AC_AttitudeControl *&attitude_control;
273 : MOTOR_CLASS *&motors;
274 : RC_Channel *&channel_roll;
275 : RC_Channel *&channel_pitch;
276 : RC_Channel *&channel_throttle;
277 : RC_Channel *&channel_yaw;
278 : float &G_Dt;
279 :
280 : // note that we support two entirely different automatic takeoffs:
281 :
282 : // "user-takeoff", which is available in modes such as ALT_HOLD
283 : // (see has_user_takeoff method). "user-takeoff" is a simple
284 : // reach-altitude-based-on-pilot-input-or-parameter routine.
285 :
286 : // "auto-takeoff" is used by both Guided and Auto, and is
287 : // basically waypoint navigation with pilot yaw permitted.
288 :
289 : // user-takeoff support; takeoff state is shared across all mode instances
290 : class _TakeOff {
291 : public:
292 : void start_m(float alt_m);
293 : void stop();
294 : void do_pilot_takeoff_ms(float pilot_climb_rate_ms);
295 : bool triggered_ms(float target_climb_rate_ms) const;
296 :
297 6015198 : bool running() const { return _running; }
298 : private:
299 : bool _running;
300 : float take_off_start_alt_m;
301 : float take_off_complete_alt_m;
302 : };
303 :
304 : static _TakeOff takeoff;
305 :
306 : virtual bool do_user_takeoff_start_m(float takeoff_alt_m);
307 :
308 : static _AutoTakeoff auto_takeoff;
309 :
310 : public:
311 : // Navigation Yaw control
312 : class AutoYaw {
313 :
314 : public:
315 :
316 : // Autopilot Yaw Mode enumeration
317 : enum class Mode {
318 : HOLD = 0, // hold zero yaw rate
319 : LOOK_AT_NEXT_WP = 1, // point towards next waypoint (no pilot input accepted)
320 : ROI = 2, // point towards a location held in roi_ned_m (no pilot input accepted)
321 : FIXED = 3, // point towards a particular angle (no pilot input accepted)
322 : LOOK_AHEAD = 4, // point in the direction the copter is moving
323 : RESET_TO_ARMED_YAW = 5, // point towards heading at time motors were armed
324 : ANGLE_RATE = 6, // turn at a specified rate from a starting angle
325 : RATE = 7, // turn at a specified rate (held in auto_yaw_rate)
326 : CIRCLE = 8, // use AC_Circle's provided yaw (used during Loiter-Turns commands)
327 : PILOT_RATE = 9, // target rate from pilot stick
328 : WEATHERVANE = 10, // yaw into wind
329 : };
330 :
331 : // mode(): current method of determining desired yaw:
332 25103452 : Mode mode() const { return _mode; }
333 : void set_mode_to_default(bool rtl);
334 : void set_mode(Mode new_mode);
335 : Mode default_mode(bool rtl) const;
336 :
337 : void set_rate_rad(float turn_rate_rads);
338 :
339 : // set_roi(...): set a "look at" location:
340 : void set_roi(const Location &roi_location);
341 :
342 : void set_fixed_yaw_rad(float angle_rad,
343 : float turn_rate_rads,
344 : int8_t direction,
345 : bool relative_angle);
346 :
347 : void set_yaw_angle_and_rate_rad(float yaw_angle_rad, float yaw_rate_rads);
348 :
349 : void set_yaw_angle_offset_deg(const float yaw_angle_offset_deg);
350 :
351 : bool reached_fixed_yaw_target();
352 :
353 : #if WEATHERVANE_ENABLED
354 : void update_weathervane(const float pilot_yaw_rads);
355 : #endif
356 :
357 : AC_AttitudeControl::HeadingCommand get_heading();
358 :
359 : private:
360 :
361 : // yaw_rad(): main product of AutoYaw; the heading:
362 : float yaw_rad();
363 :
364 : // rate_rads(): desired yaw rate in radians/second:
365 : float rate_rads();
366 :
367 : // Returns the yaw angle (in radians) representing the direction of horizontal motion.
368 : float look_ahead_yaw_rad();
369 :
370 : float roi_yaw_rad() const;
371 :
372 : // auto flight mode's yaw mode
373 : Mode _mode = Mode::LOOK_AT_NEXT_WP;
374 : Mode _last_mode;
375 :
376 : // Yaw will point at this location if mode is set to Mode::ROI
377 : Vector3f roi_ned_m;
378 :
379 : // yaw used for YAW_FIXED yaw_mode
380 : float _fixed_yaw_offset_rad;
381 :
382 : // Radians/s we should turn
383 : float _fixed_yaw_slewrate_rads;
384 :
385 : // time of the last yaw update
386 : uint32_t _last_update_ms;
387 :
388 : // heading when in yaw_look_ahead_yaw
389 : float _look_ahead_yaw_rad;
390 :
391 : // turn heading (rad) and rate (rads) when auto_yaw_mode is set to AUTO_YAW_RATE
392 : float _yaw_angle_rad;
393 : float _yaw_rate_rads;
394 : float _pilot_yaw_rate_rads;
395 : };
396 : static AutoYaw auto_yaw;
397 :
398 : // pass-through functions to reduce code churn on conversion;
399 : // these are candidates for moving into the Mode base
400 : // class.
401 :
402 : // Returns the pilot’s commanded climb rate in m/s.
403 : float get_pilot_desired_climb_rate_ms() const;
404 :
405 : // Returns the throttle level to maintain altitude (excluding takeoff boost).
406 : float get_non_takeoff_throttle() const;
407 :
408 : // Rotates roll/pitch pilot input if simple or super simple mode is active.
409 : void apply_simple_mode(float &roll, float &pitch) const;
410 :
411 : // Requests a mode change with the specified reason; returns true if accepted.
412 : bool set_mode(Mode::Number mode, ModeReason reason);
413 :
414 : // Sets the “land complete” state flag.
415 : void set_land_complete(bool b);
416 :
417 : // Returns a reference to the GCS interface for Copter.
418 : GCS_Copter &gcs() const;
419 :
420 : // Returns the pilot’s maximum upward speed in m/s.
421 : float get_pilot_speed_up_ms() const;
422 :
423 : // Returns the pilot’s maximum downward speed in m/s.
424 : float get_pilot_speed_dn_ms() const;
425 :
426 : // Returns the pilot’s vertical acceleration limit in m/s².
427 : float get_pilot_accel_D_mss() const;
428 : // end pass-through functions
429 : };
430 :
431 :
432 : #if MODE_ACRO_ENABLED
433 : class ModeAcro : public Mode {
434 :
435 : public:
436 : // inherit constructor
437 : using Mode::Mode;
438 83784 : Number mode_number() const override { return Number::ACRO; }
439 :
440 : enum class Trainer {
441 : OFF = 0,
442 : LEVELING = 1,
443 : LIMITED = 2,
444 : };
445 :
446 : enum class AcroOptions {
447 : AIR_MODE = 1 << 0,
448 : RATE_LOOP_ONLY = 1 << 1,
449 : };
450 :
451 : virtual void run() override;
452 :
453 866 : bool requires_position() const override { return false; }
454 4582 : bool has_manual_throttle() const override { return true; }
455 4 : bool allows_arming(AP_Arming::Method method) const override { return true; };
456 9 : bool is_autopilot() const override { return false; }
457 : bool init(bool ignore_checks) override;
458 : void exit() override;
459 : // Called when air mode is enabled via AUX switch; prevents automatic reset to default air_mode state
460 : void air_mode_aux_changed();
461 0 : bool allows_flip() const override { return true; }
462 0 : bool crash_check_enabled() const override { return false; }
463 0 : bool allows_entry_in_rc_failsafe() const override { return false; }
464 :
465 : protected:
466 :
467 1 : const char *name() const override { return "Acro"; }
468 9 : const char *name4() const override { return "ACRO"; }
469 :
470 : // get_pilot_desired_rates_rads - transform pilot's normalised roll pitch and yaw input into a desired lean angle rates
471 : // the function returns desired angle rates in radians-per-second
472 : void get_pilot_desired_rates_rads(float &roll_out_rads, float &pitch_out_rads, float &yaw_out_rads);
473 :
474 : float throttle_hover() const override;
475 :
476 : private:
477 : bool disable_air_mode_reset;
478 : };
479 : #endif
480 :
481 : #if FRAME_CONFIG == HELI_FRAME
482 : class ModeAcro_Heli : public ModeAcro {
483 :
484 : public:
485 : // inherit constructor
486 : using ModeAcro::Mode;
487 :
488 : bool init(bool ignore_checks) override;
489 : void run() override;
490 : void virtual_flybar( float &roll_out_rads, float &pitch_out_rads, float &yaw_out_rads, float pitch_leak, float roll_leak);
491 :
492 : protected:
493 : private:
494 : };
495 : #endif
496 :
497 :
498 : class ModeAltHold : public Mode {
499 :
500 : public:
501 : // inherit constructor
502 : using Mode::Mode;
503 1763328 : Number mode_number() const override { return Number::ALT_HOLD; }
504 :
505 : bool init(bool ignore_checks) override;
506 : void run() override;
507 :
508 214097 : bool requires_position() const override { return false; }
509 3616562 : bool has_manual_throttle() const override { return false; }
510 70 : bool allows_arming(AP_Arming::Method method) const override { return true; };
511 165 : bool is_autopilot() const override { return false; }
512 487342 : bool has_user_takeoff(bool must_navigate) const override {
513 487342 : return !must_navigate;
514 : }
515 7 : bool allows_autotune() const override { return true; }
516 15 : bool allows_flip() const override { return true; }
517 181 : bool allows_auto_trim() const override { return true; }
518 0 : bool allows_save_trim() const override { return true; }
519 : #if FRAME_CONFIG == HELI_FRAME
520 17 : bool allows_inverted() const override { return true; };
521 : #endif
522 : protected:
523 :
524 11 : const char *name() const override { return "Altitude Hold"; }
525 164 : const char *name4() const override { return "ALTH"; }
526 :
527 : private:
528 :
529 : };
530 :
531 : #if MODE_AUTO_ENABLED
532 : class ModeAuto : public Mode {
533 :
534 : public:
535 : friend class PayloadPlace; // in case wp_run is accidentally required
536 :
537 : // inherit constructor
538 : using Mode::Mode;
539 2966817 : Number mode_number() const override { return auto_RTL? Number::AUTO_RTL : Number::AUTO; }
540 :
541 : bool init(bool ignore_checks) override;
542 : void exit() override;
543 : void run() override;
544 :
545 : bool requires_position() const override;
546 5559461 : bool has_manual_throttle() const override { return false; }
547 : bool allows_arming(AP_Arming::Method method) const override;
548 98 : bool is_autopilot() const override { return true; }
549 2 : bool in_guided_mode() const override { return _mode == SubMode::NAVGUIDED || _mode == SubMode::NAV_SCRIPT_TIME; }
550 : #if FRAME_CONFIG == HELI_FRAME
551 7 : bool allows_inverted() const override { return true; };
552 : #endif
553 : bool move_vehicle_on_ekf_reset() const override;
554 :
555 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
556 : // Return the type of this mode for use by advanced failsafe
557 : AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }
558 : #endif
559 :
560 : // Return true if the throttle high arming check can be skipped when arming from GCS or Scripting
561 53 : bool allows_GCS_or_SCR_arming_with_throttle_high() const override { return true; }
562 :
563 : // Auto modes
564 : enum class SubMode : uint8_t {
565 : TAKEOFF,
566 : WP,
567 : LAND,
568 : RTL,
569 : CIRCLE_MOVE_TO_EDGE,
570 : CIRCLE,
571 : NAVGUIDED,
572 : LOITER,
573 : LOITER_TO_ALT,
574 : #if AP_MISSION_NAV_PAYLOAD_PLACE_ENABLED && AC_PAYLOAD_PLACE_ENABLED
575 : NAV_PAYLOAD_PLACE,
576 : #endif
577 : NAV_SCRIPT_TIME,
578 : NAV_ATTITUDE_TIME,
579 : };
580 :
581 : // set submode. returns true on success, false on failure
582 : void set_submode(SubMode new_submode);
583 :
584 : // pause continue in auto mode
585 : bool pause() override;
586 : bool resume() override;
587 : bool paused() const;
588 :
589 : bool loiter_start();
590 : void rtl_start();
591 : void takeoff_start(const Location& dest_loc);
592 : bool wp_start(const Location& dest_loc);
593 : void land_start();
594 : void circle_movetoedge_start(const Location &circle_center, float radius_m);
595 : void circle_start();
596 : void nav_guided_start();
597 :
598 : bool is_landing() const override;
599 :
600 : bool is_taking_off() const override;
601 : bool use_pilot_yaw() const override;
602 :
603 : bool set_speed_NE_ms(float speed_ne_ms) override;
604 : bool set_speed_up_ms(float speed_up_ms) override;
605 : bool set_speed_down_ms(float speed_down_ms) override;
606 :
607 0 : bool requires_terrain_failsafe() const override { return true; }
608 :
609 : void payload_place_start();
610 :
611 : // for GCS_MAVLink to call:
612 : bool do_guided(const AP_Mission::Mission_Command& cmd);
613 :
614 : // Go straight to landing sequence via DO_LAND_START, if succeeds pretend to be Auto RTL mode
615 : bool jump_to_landing_sequence_auto_RTL(ModeReason reason);
616 :
617 : // Join mission after DO_RETURN_PATH_START waypoint, if succeeds pretend to be Auto RTL mode
618 : bool return_path_start_auto_RTL(ModeReason reason);
619 :
620 : // Try join return path else do land start
621 : bool return_path_or_jump_to_landing_sequence_auto_RTL(ModeReason reason);
622 :
623 : // lua accessors for nav script time support
624 : bool nav_script_time(uint16_t &id, uint8_t &cmd, float &arg1, float &arg2, int16_t &arg3, int16_t &arg4);
625 : void nav_script_time_done(uint16_t id);
626 :
627 : AP_Mission mission{
628 : FUNCTOR_BIND_MEMBER(&ModeAuto::start_command, bool, const AP_Mission::Mission_Command &),
629 : FUNCTOR_BIND_MEMBER(&ModeAuto::verify_command, bool, const AP_Mission::Mission_Command &),
630 : FUNCTOR_BIND_MEMBER(&ModeAuto::exit_mission, void)};
631 :
632 : // Mission change detector
633 : AP_Mission_ChangeDetector mis_change_detector;
634 :
635 : // true if weathervaning is allowed in auto
636 : #if WEATHERVANE_ENABLED
637 : bool allows_weathervaning(void) const override;
638 : #endif
639 :
640 : // Get height above ground, uses landing height if available
641 : float get_alt_above_ground_m() const override;
642 :
643 : protected:
644 :
645 0 : const char *name() const override { return auto_RTL? "Auto RTL" : "Auto"; }
646 98 : const char *name4() const override { return auto_RTL? "ARTL" : "AUTO"; }
647 :
648 : float wp_distance_m() const override;
649 : float wp_bearing_deg() const override;
650 52149 : float crosstrack_error_m() const override { return wp_nav->crosstrack_error_m();}
651 : bool get_wp(Location &loc) const override;
652 :
653 : private:
654 :
655 : enum class Option : int32_t {
656 : AllowArming = (1 << 0U),
657 : AllowTakeOffWithoutRaisingThrottle = (1 << 1U),
658 : IgnorePilotYaw = (1 << 2U),
659 : AllowWeatherVaning = (1 << 7U),
660 : };
661 : bool option_is_enabled(Option option) const;
662 :
663 : // Enter auto rtl pseudo mode
664 : bool enter_auto_rtl(ModeReason reason);
665 :
666 : bool start_command(const AP_Mission::Mission_Command& cmd);
667 : bool verify_command(const AP_Mission::Mission_Command& cmd);
668 : void exit_mission();
669 :
670 : bool check_for_mission_change(); // detect external changes to mission
671 :
672 : void takeoff_run();
673 : void wp_run();
674 : void land_run();
675 : void rtl_run();
676 : void nav_guided_run();
677 : void loiter_run();
678 : void loiter_to_alt_run();
679 : void nav_attitude_time_run();
680 :
681 : // get 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 instead
682 : // returns false if the location cannot be determined which only happens if the terrain data is unavailable
683 : bool get_loc_from_cmd(const AP_Mission::Mission_Command& cmd, const Location& default_loc, Location& loc) const WARN_IF_UNUSED;
684 :
685 : SubMode _mode = SubMode::TAKEOFF; // controls which auto controller is run
686 :
687 : // subtract position controller offsets from target location
688 : // should be used when the location will be used as a target for the position controller
689 : void subtract_pos_offsets(Location& target_loc) const;
690 :
691 : void do_takeoff(const AP_Mission::Mission_Command& cmd);
692 : void do_nav_wp(const AP_Mission::Mission_Command& cmd);
693 : bool set_next_wp(const AP_Mission::Mission_Command& current_cmd, const Location &default_loc);
694 : void do_land(const AP_Mission::Mission_Command& cmd);
695 : bool do_loiter_unlimited(const AP_Mission::Mission_Command& cmd);
696 : void do_circle(const AP_Mission::Mission_Command& cmd);
697 : void do_loiter_time(const AP_Mission::Mission_Command& cmd);
698 : void do_loiter_to_alt(const AP_Mission::Mission_Command& cmd);
699 : void do_spline_wp(const AP_Mission::Mission_Command& cmd);
700 : bool 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);
701 : #if AC_NAV_GUIDED
702 : void do_nav_guided_enable(const AP_Mission::Mission_Command& cmd);
703 : void do_guided_limits(const AP_Mission::Mission_Command& cmd);
704 : #endif
705 : void do_nav_delay(const AP_Mission::Mission_Command& cmd);
706 : void do_wait_delay(const AP_Mission::Mission_Command& cmd);
707 : void do_within_distance(const AP_Mission::Mission_Command& cmd);
708 : void do_yaw(const AP_Mission::Mission_Command& cmd);
709 : void do_change_speed(const AP_Mission::Mission_Command& cmd);
710 : void do_set_home(const AP_Mission::Mission_Command& cmd);
711 : void do_roi(const AP_Mission::Mission_Command& cmd);
712 : void do_mount_control(const AP_Mission::Mission_Command& cmd);
713 : #if HAL_PARACHUTE_ENABLED
714 : void do_parachute(const AP_Mission::Mission_Command& cmd);
715 : #endif
716 : #if AP_WINCH_ENABLED
717 : void do_winch(const AP_Mission::Mission_Command& cmd);
718 : #endif
719 : void do_payload_place(const AP_Mission::Mission_Command& cmd);
720 : void do_RTL(void);
721 : #if AP_SCRIPTING_ENABLED
722 : void do_nav_script_time(const AP_Mission::Mission_Command& cmd);
723 : #endif
724 : void do_nav_attitude_time(const AP_Mission::Mission_Command& cmd);
725 :
726 : bool verify_takeoff();
727 : bool verify_land();
728 : bool verify_payload_place();
729 : bool verify_loiter_unlimited();
730 : bool verify_loiter_time(const AP_Mission::Mission_Command& cmd);
731 : bool verify_loiter_to_alt() const;
732 : bool verify_RTL();
733 : bool verify_wait_delay();
734 : bool verify_within_distance();
735 : bool verify_yaw();
736 : bool verify_nav_wp(const AP_Mission::Mission_Command& cmd);
737 : bool verify_circle(const AP_Mission::Mission_Command& cmd);
738 : bool verify_spline_wp(const AP_Mission::Mission_Command& cmd);
739 : #if AC_NAV_GUIDED
740 : bool verify_nav_guided_enable(const AP_Mission::Mission_Command& cmd);
741 : #endif
742 : bool verify_nav_delay(const AP_Mission::Mission_Command& cmd);
743 : #if AP_SCRIPTING_ENABLED
744 : bool verify_nav_script_time();
745 : #endif
746 : bool verify_nav_attitude_time(const AP_Mission::Mission_Command& cmd);
747 :
748 : // Loiter control
749 : uint16_t loiter_time_max; // How long we should stay in Loiter Mode for mission scripting (time in seconds)
750 : uint32_t loiter_time; // How long have we been loitering - The start time in millis
751 :
752 : struct {
753 : bool reached_destination_xy : 1;
754 : bool loiter_start_done : 1;
755 : bool reached_alt : 1;
756 : float alt_error_m;
757 : float alt_m;
758 : } loiter_to_alt;
759 :
760 : // Delay the next navigation command
761 : uint32_t nav_delay_time_max_ms; // used for delaying the navigation commands (eg land,takeoff etc.)
762 : uint32_t nav_delay_time_start_ms;
763 :
764 : // Delay Mission Scripting Command
765 : int32_t condition_value; // used in condition commands (eg delay, change alt, etc.)
766 : uint32_t condition_start;
767 :
768 : // Land within Auto state
769 : enum class State {
770 : FlyToLocation = 0,
771 : Descending = 1
772 : };
773 : State state = State::FlyToLocation;
774 :
775 : bool waiting_to_start; // true if waiting for vehicle to be armed or EKF origin before starting mission
776 :
777 : // True if we have entered AUTO to perform a DO_LAND_START landing sequence and we should report as AUTO RTL mode
778 : bool auto_RTL;
779 :
780 : #if AP_SCRIPTING_ENABLED
781 : // nav_script_time command variables
782 : struct {
783 : bool done; // true once lua script indicates it has completed
784 : uint16_t id; // unique id to avoid race conditions between commands and lua scripts
785 : uint32_t start_ms; // system time nav_script_time command was received (used for timeout)
786 : uint8_t command; // command number provided by mission command
787 : uint8_t timeout_s; // timeout (in seconds) provided by mission command
788 : float arg1; // 1st argument provided by mission command
789 : float arg2; // 2nd argument provided by mission command
790 : int16_t arg3; // 3rd argument provided by mission command
791 : int16_t arg4; // 4th argument provided by mission command
792 : } nav_scripting;
793 : #endif
794 :
795 : // nav attitude time command variables
796 : struct {
797 : int16_t roll_deg; // target roll angle in degrees. provided by mission command
798 : int8_t pitch_deg; // target pitch angle in degrees. provided by mission command
799 : int16_t yaw_deg; // target yaw angle in degrees. provided by mission command
800 : float climb_rate_ms; // climb rate in m/s. provided by mission command
801 : uint32_t start_ms; // system time that nav attitude time command was received (used for timeout)
802 : } nav_attitude_time;
803 :
804 : // desired speeds
805 : struct {
806 : float xy; // desired speed horizontally in m/s. 0 if unset
807 : float up; // desired speed upwards in m/s. 0 if unset
808 : float down; // desired speed downwards in m/s. 0 if unset
809 : } desired_speed_override_ms;
810 :
811 : // LOITER_TURNS state
812 : struct {
813 : float turns_signed; // signed number of turns for the active LOITER_TURNS orbit (sign selects direction)
814 : float radius_m; // commanded LOITER_TURNS radius (0 = panorama; circle_nav's get_radius_m() falls back to the parameter so cannot express zero)
815 : uint16_t turns_reported; // number of whole orbit turns already announced to the GCS
816 : uint32_t panorama_start_ms; // time the radius-0 panorama started
817 : float panorama_rate_rads; // yaw rate the radius-0 panorama was commanded at
818 : } circle;
819 : };
820 : #endif // MODE_AUTO_ENABLED
821 :
822 : #if AUTOTUNE_ENABLED
823 : /*
824 : wrapper class for AC_AutoTune
825 : */
826 :
827 : #if FRAME_CONFIG == HELI_FRAME
828 : class AutoTune : public AC_AutoTune_Heli
829 : #else
830 : class AutoTune : public AC_AutoTune_Multi
831 : #endif
832 : {
833 : public:
834 : bool init() override;
835 : void run() override;
836 :
837 : protected:
838 : bool position_ok() override;
839 : float get_desired_climb_rate_ms(void) const override;
840 : void get_pilot_desired_rp_yrate_rad(float &des_roll_rad, float &des_pitch_rad, float &des_yaw_rate_rads) override;
841 : void init_z_limits() override;
842 : #if HAL_LOGGING_ENABLED
843 : void log_pids() override;
844 : #endif
845 : };
846 :
847 : class ModeAutoTune : public Mode {
848 :
849 : // ParametersG2 sets a pointer within our autotune object:
850 : friend class ParametersG2;
851 :
852 : public:
853 : // inherit constructor
854 : using Mode::Mode;
855 2643328 : Number mode_number() const override { return Number::AUTOTUNE; }
856 :
857 : bool init(bool ignore_checks) override;
858 : void exit() override;
859 : void run() override;
860 :
861 84734 : bool requires_position() const override { return false; }
862 3598004 : bool has_manual_throttle() const override { return false; }
863 0 : bool allows_arming(AP_Arming::Method method) const override { return false; }
864 12 : bool is_autopilot() const override { return false; }
865 :
866 : AutoTune autotune;
867 :
868 : protected:
869 :
870 33 : const char *name() const override { return "Autotune"; }
871 12 : const char *name4() const override { return "ATUN"; }
872 : };
873 : #endif
874 :
875 :
876 : class ModeBrake : public Mode {
877 :
878 : public:
879 : // inherit constructor
880 : using Mode::Mode;
881 83015 : Number mode_number() const override { return Number::BRAKE; }
882 :
883 : bool init(bool ignore_checks) override;
884 : void run() override;
885 :
886 818 : bool requires_position() const override { return true; }
887 22514 : bool has_manual_throttle() const override { return false; }
888 1 : bool allows_arming(AP_Arming::Method method) const override { return false; };
889 8 : bool is_autopilot() const override { return true; }
890 :
891 : void timeout_to_loiter_ms(uint32_t timeout_ms);
892 :
893 : protected:
894 :
895 2 : const char *name() const override { return "Brake"; }
896 8 : const char *name4() const override { return "BRAK"; }
897 :
898 : private:
899 :
900 : uint32_t _timeout_start;
901 : uint32_t _timeout_ms;
902 :
903 : };
904 :
905 :
906 : class ModeCircle : public Mode {
907 :
908 : public:
909 : // inherit constructor
910 : using Mode::Mode;
911 136026 : Number mode_number() const override { return Number::CIRCLE; }
912 :
913 : bool init(bool ignore_checks) override;
914 : void run() override;
915 :
916 5814 : bool requires_position() const override { return true; }
917 182421 : bool has_manual_throttle() const override { return false; }
918 2 : bool allows_arming(AP_Arming::Method method) const override { return false; };
919 22 : bool is_autopilot() const override { return true; }
920 :
921 : protected:
922 :
923 2 : const char *name() const override { return "Circle"; }
924 22 : const char *name4() const override { return "CIRC"; }
925 :
926 : float wp_distance_m() const override;
927 : float wp_bearing_deg() const override;
928 :
929 : private:
930 :
931 : // Circle
932 : bool speed_changing = false; // true when the roll stick is being held to facilitate stopping at 0 rate
933 : };
934 :
935 :
936 : class ModeDrift : public Mode {
937 :
938 : public:
939 : // inherit constructor
940 : using Mode::Mode;
941 88532 : Number mode_number() const override { return Number::DRIFT; }
942 :
943 : bool init(bool ignore_checks) override;
944 : void run() override;
945 :
946 2060 : bool requires_position() const override { return true; }
947 27290 : bool has_manual_throttle() const override { return false; }
948 2 : bool allows_arming(AP_Arming::Method method) const override { return true; };
949 2 : bool is_autopilot() const override { return false; }
950 0 : bool allows_entry_in_rc_failsafe() const override { return false; }
951 :
952 : protected:
953 :
954 1 : const char *name() const override { return "Drift"; }
955 2 : const char *name4() const override { return "DRIF"; }
956 :
957 : private:
958 :
959 : float get_throttle_assist(float vel_d_ms, float pilot_throttle_scaled);
960 :
961 : };
962 :
963 :
964 : class ModeFlip : public Mode {
965 :
966 : public:
967 : // need a constructor
968 : ModeFlip(void);
969 78533 : Number mode_number() const override { return Number::FLIP; }
970 :
971 : bool init(bool ignore_checks) override;
972 : void run() override;
973 :
974 237 : bool requires_position() const override { return false; }
975 7869 : bool has_manual_throttle() const override { return false; }
976 0 : bool allows_arming(AP_Arming::Method method) const override { return false; };
977 15 : bool is_autopilot() const override { return false; }
978 4308 : bool crash_check_enabled() const override { return false; }
979 :
980 : void abandon_flip();
981 :
982 : static const struct AP_Param::GroupInfo var_info[];
983 :
984 : protected:
985 :
986 32 : const char *name() const override { return "Flip"; }
987 15 : const char *name4() const override { return "FLIP"; }
988 :
989 : private:
990 :
991 : Vector3f orig_attitude_euler_rad; // original vehicle attitude before flip
992 :
993 : enum class FlipState : uint8_t {
994 : Start,
995 : Roll,
996 : Pitch_A,
997 : Pitch_B,
998 : Recover,
999 : Abandon
1000 : };
1001 : bool abandon_requested;
1002 : FlipState _state; // current state of flip
1003 : Mode::Number orig_control_mode; // flight mode when flip was initiated
1004 : uint32_t start_time_ms;
1005 : int8_t roll_dir; // roll direction (-1 = roll left, 1 = roll right)
1006 : int8_t pitch_dir; // pitch direction (-1 = pitch forward, 1 = pitch back)
1007 : AP_Float flip_rate_dps; // rotational rate during flip
1008 :
1009 : bool input_is_high_magnitude(RC_Channel &input) const;
1010 : };
1011 :
1012 :
1013 : #if MODE_FLOWHOLD_ENABLED
1014 : /*
1015 : class to support FLOWHOLD mode, which is a position hold mode using
1016 : optical flow directly, avoiding the need for a rangefinder
1017 : */
1018 :
1019 : class ModeFlowHold : public Mode {
1020 : public:
1021 : // need a constructor for parameters
1022 : ModeFlowHold(void);
1023 30479 : Number mode_number() const override { return Number::FLOWHOLD; }
1024 :
1025 : bool init(bool ignore_checks) override;
1026 : void run(void) override;
1027 :
1028 2526 : bool requires_position() const override { return false; }
1029 79989 : bool has_manual_throttle() const override { return false; }
1030 1 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1031 1 : bool is_autopilot() const override { return false; }
1032 7675 : bool has_user_takeoff(bool must_navigate) const override {
1033 7675 : return !must_navigate;
1034 : }
1035 0 : bool allows_flip() const override { return true; }
1036 :
1037 : // Return true if this mode is enabled, used by MAVLink available modes
1038 : bool enabled() const override;
1039 :
1040 : static const struct AP_Param::GroupInfo var_info[];
1041 :
1042 : protected:
1043 0 : const char *name() const override { return "Flow Hold"; }
1044 1 : const char *name4() const override { return "FHLD"; }
1045 :
1046 : private:
1047 :
1048 : // FlowHold states
1049 : enum FlowHoldModeState {
1050 : FlowHold_MotorStopped,
1051 : FlowHold_Takeoff,
1052 : FlowHold_Flying,
1053 : FlowHold_Landed
1054 : };
1055 :
1056 : // calculate attitude from flow data
1057 : void flow_to_angle(Vector2f &bf_angle);
1058 :
1059 : LowPassFilterConstDtVector2f flow_filter;
1060 :
1061 : bool flowhold_init(bool ignore_checks);
1062 : void flowhold_run();
1063 : void flowhold_flow_to_angle(Vector2f &bf_angles_rad, bool stick_input);
1064 : void update_height_estimate(void);
1065 :
1066 : // minimum assumed height
1067 : const float height_min_m = 0.1f;
1068 :
1069 : // maximum scaling height
1070 : const float height_max = 3.0f;
1071 :
1072 : AP_Float flow_max;
1073 : AC_PI_2D flow_pi_xy{0.2f, 0.3f, 3000, 5, 0.0025f};
1074 : AP_Float flow_filter_hz;
1075 : AP_Int8 flow_min_quality;
1076 : AP_Int8 brake_rate_dps;
1077 :
1078 : float quality_filtered;
1079 :
1080 : uint8_t log_counter;
1081 : bool limited;
1082 : Vector2f xy_I;
1083 :
1084 : // accumulated INS delta velocity in north-east form since last flow update
1085 : Vector2f delta_velocity_ne_ms;
1086 :
1087 : // last flow rate in radians/sec in north-east axis
1088 : Vector2f last_flow_rate_rads;
1089 :
1090 : // timestamp of last flow data
1091 : uint32_t last_flow_ms;
1092 :
1093 : float last_ins_height_m;
1094 : float height_offset_m;
1095 :
1096 : // are we braking after pilot input?
1097 : bool braking;
1098 :
1099 : // last time there was significant stick input
1100 : uint32_t last_stick_input_ms;
1101 : };
1102 : #endif // MODE_FLOWHOLD_ENABLED
1103 :
1104 :
1105 : class ModeGuided : public Mode {
1106 :
1107 : public:
1108 : #if AP_EXTERNAL_CONTROL_ENABLED
1109 : friend class AP_ExternalControl_Copter;
1110 : #endif
1111 :
1112 : // inherit constructor
1113 : using Mode::Mode;
1114 2445227 : Number mode_number() const override { return Number::GUIDED; }
1115 :
1116 : bool init(bool ignore_checks) override;
1117 : void run() override;
1118 :
1119 252741 : bool requires_position() const override { return true; }
1120 5974411 : bool has_manual_throttle() const override { return false; }
1121 : bool allows_arming(AP_Arming::Method method) const override;
1122 161 : bool is_autopilot() const override { return true; }
1123 145 : bool has_user_takeoff(bool must_navigate) const override { return true; }
1124 6286 : bool in_guided_mode() const override { return true; }
1125 : bool move_vehicle_on_ekf_reset() const override;
1126 :
1127 0 : bool requires_terrain_failsafe() const override { return true; }
1128 :
1129 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
1130 : // Return the type of this mode for use by advanced failsafe
1131 : AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }
1132 : #endif
1133 :
1134 : // Return true if the throttle high arming check can be skipped when arming from GCS or Scripting
1135 145 : bool allows_GCS_or_SCR_arming_with_throttle_high() const override { return true; }
1136 : void set_angle(const Quaternion &attitude_quat, const Vector3f &ang_vel, float climb_rate_ms_or_thrust, bool use_thrust);
1137 :
1138 : void hold_position();
1139 : bool set_pos_NED_m(const Vector3p& pos_ned_m, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false, bool is_terrain_alt = false);
1140 : bool set_destination(const Location& dest_loc, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false);
1141 : bool get_wp(Location &loc) const override;
1142 : void set_accel_NED_mss(const Vector3f& accel_ned_mss, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false, bool log_request = true);
1143 : void set_vel_NED_ms(const Vector3f& vel_ned_ms, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false, bool log_request = true);
1144 : void set_vel_accel_NED_m(const Vector3f& vel_ned_ms, const Vector3f& accel_ned_mss, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false, bool log_request = true);
1145 : bool set_pos_vel_NED_m(const Vector3p& pos_ned_m, const Vector3f& vel_ned_ms, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false);
1146 : bool set_pos_vel_accel_NED_m(const Vector3p& pos_ned_m, const Vector3f& vel_ned_ms, const Vector3f& accel_ned_mss, bool use_yaw = false, float yaw_rad = 0.0, bool use_yaw_rate = false, float yaw_rate_rads = 0.0, bool yaw_relative = false);
1147 :
1148 : // get position, velocity and acceleration targets
1149 : const Vector3p& get_target_pos_NED_m() const;
1150 : const Vector3f& get_target_vel_NED_ms() const;
1151 : const Vector3f& get_target_accel_NED_mss() const;
1152 :
1153 : // returns true if GUIDED_OPTIONS param suggests SET_ATTITUDE_TARGET's "thrust" field should be interpreted as thrust instead of climb rate
1154 : bool set_attitude_target_provides_thrust() const;
1155 : bool stabilizing_pos_NE() const;
1156 : bool stabilizing_vel_NE() const;
1157 : bool use_wpnav_for_position_control() const;
1158 :
1159 : void limit_clear();
1160 : void limit_init_time_and_pos();
1161 : void limit_set(uint32_t timeout_ms, float alt_min_m, float alt_max_m, float horiz_max_m);
1162 : bool limit_check();
1163 :
1164 : bool is_taking_off() const override;
1165 :
1166 : bool set_speed_NE_ms(float speed_ne_ms) override;
1167 : bool set_speed_up_ms(float speed_up_ms) override;
1168 : bool set_speed_down_ms(float speed_down_ms) override;
1169 :
1170 : // initialises position controller to implement take-off
1171 : // takeoff_alt_m is interpreted as alt-above-home (in m) or alt-above-terrain if a rangefinder is available
1172 : bool do_user_takeoff_start_m(float takeoff_alt_m) override;
1173 :
1174 : enum class SubMode {
1175 : TakeOff,
1176 : WP,
1177 : Pos,
1178 : PosVelAccel,
1179 : VelAccel,
1180 : Accel,
1181 : Angle,
1182 : };
1183 :
1184 2536 : SubMode submode() const { return guided_mode; }
1185 :
1186 : void angle_control_start();
1187 : void angle_control_run();
1188 :
1189 : // return guided mode timeout in milliseconds. Only used for velocity, acceleration, angle control, and angular rate control
1190 : uint32_t get_timeout_ms() const;
1191 :
1192 : bool use_pilot_yaw() const override;
1193 :
1194 : // pause continue in guided mode
1195 : bool pause() override;
1196 : bool resume() override;
1197 :
1198 : // true if weathervaning is allowed in guided
1199 : #if WEATHERVANE_ENABLED
1200 : bool allows_weathervaning(void) const override;
1201 : #endif
1202 :
1203 : protected:
1204 :
1205 0 : const char *name() const override { return "Guided"; }
1206 160 : const char *name4() const override { return "GUID"; }
1207 :
1208 : float wp_distance_m() const override;
1209 : float wp_bearing_deg() const override;
1210 : float crosstrack_error_m() const override;
1211 :
1212 : private:
1213 :
1214 : // enum for GUID_OPTIONS parameter
1215 : enum class Option : uint32_t {
1216 : AllowArmingFromTX = (1U << 0),
1217 : // this bit is still available, pilot yaw was mapped to bit 2 for symmetry with auto
1218 : IgnorePilotYaw = (1U << 2),
1219 : SetAttitudeTarget_ThrustAsThrust = (1U << 3),
1220 : DoNotStabilizePositionXY = (1U << 4),
1221 : DoNotStabilizeVelocityXY = (1U << 5),
1222 : WPNavUsedForPosControl = (1U << 6),
1223 : AllowWeatherVaning = (1U << 7)
1224 : };
1225 :
1226 : // returns true if the Guided-mode-option is set (see GUID_OPTIONS)
1227 : bool option_is_enabled(Option option) const;
1228 :
1229 : // wp controller
1230 : void wp_control_start();
1231 : void wp_control_run();
1232 :
1233 : void pva_control_start();
1234 : void pos_control_start();
1235 : void accel_control_start();
1236 : void velaccel_control_start();
1237 : void posvelaccel_control_start();
1238 : void takeoff_run();
1239 : void pos_control_run();
1240 : void accel_control_run();
1241 : void velaccel_control_run();
1242 : void pause_control_run();
1243 : void posvelaccel_control_run();
1244 : void set_yaw_state_rad(bool use_yaw, float yaw_rad, bool use_yaw_rate, float yaw_rate_rads, bool relative_angle);
1245 :
1246 : // controls which controller is run (pos or vel):
1247 : SubMode guided_mode = SubMode::TakeOff;
1248 : // used to send one time notification to ground station:
1249 : bool send_notification;
1250 : static bool takeoff_complete; // true once takeoff has completed (used to trigger retracting of landing gear)
1251 :
1252 : // guided mode is paused or not
1253 : bool _paused;
1254 : };
1255 :
1256 : #if AP_SCRIPTING_ENABLED
1257 : // Mode which behaves as guided with custom mode number and name
1258 : class ModeGuidedCustom : public ModeGuided {
1259 : public:
1260 : // constructor registers custom number and names
1261 : ModeGuidedCustom(const Number _number, const char* _full_name, const char* _short_name);
1262 :
1263 : bool init(bool ignore_checks) override;
1264 :
1265 810 : Number mode_number() const override { return number; }
1266 :
1267 11 : const char *name() const override { return full_name; }
1268 1 : const char *name4() const override { return short_name; }
1269 :
1270 : // State object which can be edited by scripting
1271 : AP_Vehicle::custom_mode_state state;
1272 :
1273 : private:
1274 : const Number number;
1275 : const char* full_name;
1276 : const char* short_name;
1277 : };
1278 : #endif
1279 :
1280 : class ModeGuidedNoGPS : public ModeGuided {
1281 :
1282 : public:
1283 : // inherit constructor
1284 : using ModeGuided::Mode;
1285 76241 : Number mode_number() const override { return Number::GUIDED_NOGPS; }
1286 :
1287 : bool init(bool ignore_checks) override;
1288 : void run() override;
1289 :
1290 82 : bool requires_position() const override { return false; }
1291 1066 : bool has_manual_throttle() const override { return false; }
1292 2 : bool is_autopilot() const override { return true; }
1293 :
1294 : protected:
1295 :
1296 0 : const char *name() const override { return "Guided No GPS"; }
1297 2 : const char *name4() const override { return "GNGP"; }
1298 :
1299 : private:
1300 :
1301 : };
1302 :
1303 :
1304 : class ModeLand : public Mode {
1305 :
1306 : public:
1307 : // need a constructor for parameters
1308 : ModeLand(void);
1309 738612 : Number mode_number() const override { return Number::LAND; }
1310 :
1311 : bool init(bool ignore_checks) override;
1312 : void run() override;
1313 :
1314 55669 : bool requires_position() const override { return false; }
1315 1659704 : bool has_manual_throttle() const override { return false; }
1316 2 : bool allows_arming(AP_Arming::Method method) const override { return false; };
1317 102 : bool is_autopilot() const override { return true; }
1318 345649 : bool is_landing() const override { return true; };
1319 :
1320 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
1321 : // Return the type of this mode for use by advanced failsafe
1322 : AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }
1323 : #endif
1324 :
1325 : void do_not_use_GPS();
1326 :
1327 : // returns true if LAND mode is trying to control X/Y position
1328 55028 : bool controlling_position() const { return control_position; }
1329 :
1330 17 : void set_land_pause(bool new_value) { land_pause = new_value; }
1331 : bool use_pilot_yaw() const override;
1332 :
1333 : // parameter accessors
1334 4514393 : float get_land_speed_ms() const { return land_speed_ms.get(); }
1335 4514392 : float get_land_speed_high_ms() const { return land_speed_high_ms.get(); }
1336 4514392 : float get_land_alt_low_m() const { return land_alt_low_m.get(); }
1337 :
1338 : // convert parameters
1339 : void convert_params();
1340 :
1341 : // mode specific parameter variable table
1342 : static const struct AP_Param::GroupInfo var_info[];
1343 :
1344 : protected:
1345 :
1346 7 : const char *name() const override { return "Land"; }
1347 102 : const char *name4() const override { return "LAND"; }
1348 :
1349 : private:
1350 :
1351 : void gps_run();
1352 : void nogps_run();
1353 :
1354 : bool control_position; // true if we are using an external reference to control position
1355 :
1356 : // parameters
1357 : AP_Float land_speed_ms;
1358 : AP_Float land_speed_high_ms;
1359 : AP_Float land_alt_low_m;
1360 :
1361 : uint32_t land_start_time;
1362 : bool land_pause;
1363 : };
1364 :
1365 :
1366 : class ModeLoiter : public Mode {
1367 :
1368 : public:
1369 : // inherit constructor
1370 : using Mode::Mode;
1371 1681668 : Number mode_number() const override { return Number::LOITER; }
1372 :
1373 : bool init(bool ignore_checks) override;
1374 : void run() override;
1375 :
1376 177705 : bool requires_position() const override { return true; }
1377 3911646 : bool has_manual_throttle() const override { return false; }
1378 119 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1379 194 : bool is_autopilot() const override { return false; }
1380 514099 : bool has_user_takeoff(bool must_navigate) const override { return true; }
1381 2 : bool allows_autotune() const override { return true; }
1382 1 : bool allows_auto_trim() const override { return true; }
1383 :
1384 : #if FRAME_CONFIG == HELI_FRAME
1385 6 : bool allows_inverted() const override { return true; };
1386 : #endif
1387 :
1388 : #if AC_PRECLAND_ENABLED
1389 4 : void set_precision_loiter_enabled(bool value) { _precision_loiter_enabled = value; }
1390 : #endif
1391 :
1392 : protected:
1393 :
1394 21 : const char *name() const override { return "Loiter"; }
1395 194 : const char *name4() const override { return "LOIT"; }
1396 :
1397 : float wp_distance_m() const override;
1398 : float wp_bearing_deg() const override;
1399 51926 : float crosstrack_error_m() const override { return pos_control->crosstrack_error_m();}
1400 :
1401 : #if AC_PRECLAND_ENABLED
1402 : bool do_precision_loiter();
1403 : void precision_loiter_xy();
1404 : #endif
1405 :
1406 : private:
1407 :
1408 : #if AC_PRECLAND_ENABLED
1409 : bool _precision_loiter_enabled;
1410 : bool _precision_loiter_active; // true if user has switched on prec loiter
1411 : #endif
1412 :
1413 : };
1414 :
1415 :
1416 : class ModePosHold : public Mode {
1417 :
1418 : public:
1419 : // need a constructor for parameters
1420 : ModePosHold(void);
1421 363499 : Number mode_number() const override { return Number::POSHOLD; }
1422 :
1423 : bool init(bool ignore_checks) override;
1424 : void run() override;
1425 :
1426 11001 : bool requires_position() const override { return true; }
1427 386573 : bool has_manual_throttle() const override { return false; }
1428 11 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1429 12 : bool is_autopilot() const override { return false; }
1430 104316 : bool has_user_takeoff(bool must_navigate) const override { return true; }
1431 0 : bool allows_autotune() const override { return true; }
1432 0 : bool allows_auto_trim() const override { return true; }
1433 :
1434 : // convert parameters
1435 : void convert_params();
1436 :
1437 : // mode specific parameter variable table
1438 : static const struct AP_Param::GroupInfo var_info[];
1439 :
1440 : protected:
1441 :
1442 0 : const char *name() const override { return "Position Hold"; }
1443 12 : const char *name4() const override { return "PHLD"; }
1444 :
1445 : private:
1446 :
1447 : // parameters
1448 : AP_Float brake_angle_max_deg; // max lean angle (in degrees) during braking
1449 :
1450 : void update_pilot_lean_angle_rad(float &lean_angle_filtered_rad, float &lean_angle_raw_rad);
1451 : float mix_controls(float mix_ratio, float first_control, float second_control);
1452 : void update_brake_angle_from_velocity(float &brake_angle_rad, float velocity_ms);
1453 : void init_wind_comp_estimate();
1454 : void update_wind_comp_estimate();
1455 : void get_wind_comp_lean_angles_rad(float &roll_angle_rad, float &pitch_angle_rad);
1456 : void roll_controller_to_pilot_override();
1457 : void pitch_controller_to_pilot_override();
1458 :
1459 : enum class RPMode {
1460 : PILOT_OVERRIDE=0, // pilot is controlling this axis (i.e. roll or pitch)
1461 : BRAKE, // this axis is braking towards zero
1462 : 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)
1463 : BRAKE_TO_LOITER, // both vehicle's axis (roll and pitch) are transitioning from braking to loiter mode (braking and loiter controls are mixed)
1464 : LOITER, // both vehicle axis are holding position
1465 : 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)
1466 : };
1467 :
1468 : RPMode roll_mode;
1469 : RPMode pitch_mode;
1470 :
1471 : // pilot input related variables
1472 : float pilot_roll_rad; // filtered roll lean angle commanded by the pilot. Slowly returns to zero when stick is released
1473 : float pilot_pitch_rad; // filtered pitch lean angle commanded by the pilot. Slowly returns to zero when stick is released
1474 :
1475 :
1476 : // braking related variables
1477 : struct {
1478 : bool time_updated_roll; // true if braking timeout (roll) has been re-estimated
1479 : bool time_updated_pitch; // true if braking timeout (pitch) has been re-estimated
1480 : float gain; // braking gain converting velocity (m/s) -> lean angle (rad)
1481 : float roll_rad; // braking roll angle (rad)
1482 : float pitch_rad; // braking pitch angle (rad)
1483 : uint32_t start_time_roll_ms; // time (ms) when braking on roll axis begins
1484 : uint32_t start_time_pitch_ms; // time (ms) when braking on pitch axis begins
1485 : float angle_max_roll_rad; // peak roll angle (rad) during braking, used to detect vehicle flattening
1486 : float angle_max_pitch_rad; // peak pitch angle (rad) during braking, used to detect vehicle flattening
1487 : uint32_t loiter_transition_start_time_ms; // time (ms) when transition from brake to loiter started
1488 : } brake;
1489 :
1490 : // loiter transition timing (ms)
1491 : uint32_t controller_to_pilot_start_time_roll_ms; // time (ms) when transition from controller to pilot roll input began
1492 : uint32_t controller_to_pilot_start_time_pitch_ms; // time (ms) when transition from controller to pilot pitch input began
1493 :
1494 : // cached controller outputs for mix during transition (radians)
1495 : float controller_final_roll_rad; // final roll output (rad) from controller before transition to pilot input
1496 : float controller_final_pitch_rad; // final pitch output (rad) from controller before transition to pilot input
1497 :
1498 : // wind compensation related variables
1499 : Vector2f wind_comp_ne_mss; // earth-frame accel estimate (N,E), m/s^2, low-pass filtered
1500 : float wind_comp_roll_rad; // roll angle (rad) to counter wind
1501 : float wind_comp_pitch_rad; // pitch angle (rad) to counter wind
1502 : uint32_t wind_comp_start_time_ms; // time (ms) when wind compensation updates are started
1503 :
1504 : // final outputs (radians)
1505 : float roll_rad; // final roll angle sent to attitude controller
1506 : float pitch_rad; // final pitch angle sent to attitude controller
1507 : };
1508 :
1509 :
1510 : class ModeRTL : public Mode {
1511 :
1512 : public:
1513 : // need a constructor for parameters
1514 : ModeRTL(void);
1515 2840552 : Number mode_number() const override { return Number::RTL; }
1516 :
1517 : bool init(bool ignore_checks) override;
1518 4798856 : void run() override {
1519 4798856 : return run(true);
1520 : }
1521 : void run(bool disarm_on_land);
1522 :
1523 338661 : bool requires_position() const override { return true; }
1524 7359735 : bool has_manual_throttle() const override { return false; }
1525 2 : bool allows_arming(AP_Arming::Method method) const override { return false; };
1526 269 : bool is_autopilot() const override { return true; }
1527 :
1528 0 : bool requires_terrain_failsafe() const override { return true; }
1529 :
1530 : #if AP_COPTER_ADVANCED_FAILSAFE_ENABLED
1531 : // Return the type of this mode for use by advanced failsafe
1532 : AP_AdvancedFailsafe_Copter::control_mode afs_mode() const override { return AP_AdvancedFailsafe_Copter::control_mode::AFS_AUTO; }
1533 : #endif
1534 :
1535 : // for reporting to GCS
1536 : bool get_wp(Location &loc) const override;
1537 :
1538 : bool use_pilot_yaw() const override;
1539 :
1540 : bool set_speed_NE_ms(float speed_ne_ms) override;
1541 : bool set_speed_up_ms(float speed_up_ms) override;
1542 : bool set_speed_down_ms(float speed_down_ms) override;
1543 :
1544 : // RTL states
1545 : enum class SubMode : uint8_t {
1546 : STARTING,
1547 : INITIAL_CLIMB,
1548 : RETURN_HOME,
1549 : LOITER_AT_HOME,
1550 : FINAL_DESCENT,
1551 : LAND
1552 : };
1553 17412 : SubMode state() { return _state; }
1554 :
1555 : // this should probably not be exposed
1556 950728 : bool state_complete() const { return _state_complete; }
1557 :
1558 : virtual bool is_landing() const override;
1559 :
1560 : void restart_without_terrain();
1561 :
1562 : // enum for RTL_ALT_TYPE parameter
1563 : enum class RTLAltType : int8_t {
1564 : RELATIVE = 0,
1565 : TERRAIN = 1
1566 : };
1567 : ModeRTL::RTLAltType get_alt_type() const;
1568 :
1569 : // parameter accessors
1570 444 : float get_altitude_m() const { return altitude_m.get(); }
1571 : float get_speed_ms() const { return speed_ms.get(); }
1572 8 : float get_alt_final_m() const { return alt_final_m.get(); }
1573 : float get_climb_min_m() const { return climb_min_m.get(); }
1574 :
1575 : // convert parameters
1576 : void convert_params();
1577 :
1578 : // mode specific parameter variable table
1579 : static const struct AP_Param::GroupInfo var_info[];
1580 :
1581 : protected:
1582 :
1583 4 : const char *name() const override { return "RTL"; }
1584 269 : const char *name4() const override { return "RTL "; }
1585 :
1586 : // for reporting to GCS
1587 : float wp_distance_m() const override;
1588 : float wp_bearing_deg() const override;
1589 71706 : float crosstrack_error_m() const override { return wp_nav->crosstrack_error_m();}
1590 :
1591 : void descent_start();
1592 : void descent_run();
1593 : void land_start();
1594 : void land_run(bool disarm_on_land);
1595 :
1596 0 : void set_descent_target_alt(uint32_t alt) { rtl_path.descent_target.alt = alt; }
1597 :
1598 : private:
1599 :
1600 : void climb_start();
1601 : void return_start();
1602 : void climb_return_run();
1603 : void loiterathome_start();
1604 : void loiterathome_run();
1605 : void build_path();
1606 : void compute_return_target();
1607 :
1608 : // RTL parameters
1609 : AP_Float altitude_m;
1610 : AP_Float speed_ms;
1611 : AP_Float alt_final_m;
1612 : AP_Float climb_min_m;
1613 :
1614 : SubMode _state = SubMode::INITIAL_CLIMB; // records state of rtl (initial climb, returning home, etc)
1615 : bool _state_complete = false; // set to true if the current state is completed
1616 :
1617 : struct {
1618 : Location origin_point;
1619 : Location climb_target;
1620 : Location return_target;
1621 : Location descent_target;
1622 : bool land;
1623 : } rtl_path;
1624 :
1625 : // return target alt type
1626 : enum class ReturnTargetAltType {
1627 : RELATIVE = 0,
1628 : RANGEFINDER = 1,
1629 : TERRAINDATABASE = 2
1630 : };
1631 :
1632 : // Loiter timer - Records how long we have been in loiter
1633 : uint32_t _loiter_start_time;
1634 :
1635 : bool terrain_following_allowed;
1636 :
1637 : // enum for RTL_OPTIONS parameter
1638 : enum class Option : int32_t {
1639 : // First pair of bits are still available, pilot yaw was mapped to bit 2 for symmetry with auto
1640 : IgnorePilotYaw = (1U << 2),
1641 : };
1642 : bool option_is_enabled(Option option) const;
1643 :
1644 : };
1645 :
1646 :
1647 : class ModeSmartRTL : public ModeRTL {
1648 :
1649 : public:
1650 : // inherit constructor
1651 : using ModeRTL::Mode;
1652 178299 : Number mode_number() const override { return Number::SMART_RTL; }
1653 :
1654 : bool init(bool ignore_checks) override;
1655 : void run() override;
1656 :
1657 9944 : bool requires_position() const override { return true; }
1658 311744 : bool has_manual_throttle() const override { return false; }
1659 2 : bool allows_arming(AP_Arming::Method method) const override { return false; }
1660 14 : bool is_autopilot() const override { return true; }
1661 :
1662 : void save_position();
1663 : void exit() override;
1664 :
1665 : bool is_landing() const override;
1666 : bool use_pilot_yaw() const override;
1667 :
1668 : // Return true if this mode is enabled, used by MAVLink available modes
1669 : bool enabled() const override;
1670 :
1671 : // Safe RTL states
1672 : enum class SubMode : uint8_t {
1673 : WAIT_FOR_PATH_CLEANUP,
1674 : PATH_FOLLOW,
1675 : PRELAND_POSITION,
1676 : DESCEND,
1677 : LAND
1678 : };
1679 :
1680 : protected:
1681 :
1682 4 : const char *name() const override { return "Smart RTL"; }
1683 14 : const char *name4() const override { return "SRTL"; }
1684 :
1685 : // for reporting to GCS
1686 : bool get_wp(Location &loc) const override;
1687 : float wp_distance_m() const override;
1688 : float wp_bearing_deg() const override;
1689 2956 : float crosstrack_error_m() const override { return wp_nav->crosstrack_error_m();}
1690 :
1691 : private:
1692 :
1693 : void wait_cleanup_run();
1694 : void path_follow_run();
1695 : void pre_land_position_run();
1696 : void land();
1697 : SubMode smart_rtl_state = SubMode::PATH_FOLLOW;
1698 :
1699 : // keep track of how long we have failed to get another return
1700 : // point while following our path home. If we take too long we
1701 : // may choose to land the vehicle.
1702 : uint32_t path_follow_last_pop_fail_ms;
1703 :
1704 : // backup last popped point so that it can be restored to the path
1705 : // if vehicle exits SmartRTL mode before reaching home. invalid if zero
1706 : Vector3p dest_NED_backup;
1707 : };
1708 :
1709 :
1710 : class ModeSport : public Mode {
1711 :
1712 : public:
1713 : // inherit constructor
1714 : using Mode::Mode;
1715 75223 : Number mode_number() const override { return Number::SPORT; }
1716 :
1717 : bool init(bool ignore_checks) override;
1718 : void run() override;
1719 :
1720 0 : bool requires_position() const override { return false; }
1721 0 : bool has_manual_throttle() const override { return false; }
1722 0 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1723 0 : bool is_autopilot() const override { return false; }
1724 0 : bool has_user_takeoff(bool must_navigate) const override {
1725 0 : return !must_navigate;
1726 : }
1727 :
1728 : protected:
1729 :
1730 0 : const char *name() const override { return "Sport"; }
1731 0 : const char *name4() const override { return "SPRT"; }
1732 :
1733 : private:
1734 :
1735 : };
1736 :
1737 :
1738 : class ModeStabilize : public Mode {
1739 :
1740 : public:
1741 : // inherit constructor
1742 : using Mode::Mode;
1743 2764059 : Number mode_number() const override { return Number::STABILIZE; }
1744 :
1745 : virtual void run() override;
1746 :
1747 525432 : bool requires_position() const override { return false; }
1748 3067697 : bool has_manual_throttle() const override { return true; }
1749 142 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1750 1163 : bool is_autopilot() const override { return false; }
1751 0 : bool allows_save_trim() const override { return true; }
1752 191 : bool allows_auto_trim() const override { return true; }
1753 4 : bool allows_autotune() const override { return true; }
1754 0 : bool allows_flip() const override { return true; }
1755 1 : bool allows_entry_in_rc_failsafe() const override { return false; }
1756 :
1757 : protected:
1758 :
1759 2 : const char *name() const override { return "Stabilize"; }
1760 1163 : const char *name4() const override { return "STAB"; }
1761 :
1762 : private:
1763 :
1764 : };
1765 :
1766 : #if FRAME_CONFIG == HELI_FRAME
1767 : class ModeStabilize_Heli : public ModeStabilize {
1768 :
1769 : public:
1770 : // inherit constructor
1771 : using ModeStabilize::Mode;
1772 :
1773 : bool init(bool ignore_checks) override;
1774 : void run() override;
1775 :
1776 15 : bool allows_inverted() const override { return true; };
1777 :
1778 : protected:
1779 :
1780 : private:
1781 :
1782 : };
1783 : #endif
1784 :
1785 : class ModeSystemId : public Mode {
1786 :
1787 : public:
1788 : ModeSystemId(void);
1789 0 : Number mode_number() const override { return Number::SYSTEMID; }
1790 :
1791 : bool init(bool ignore_checks) override;
1792 : void run() override;
1793 : void exit() override;
1794 :
1795 0 : bool requires_position() const override { return false; }
1796 0 : bool has_manual_throttle() const override { return true; }
1797 0 : bool allows_arming(AP_Arming::Method method) const override { return false; };
1798 0 : bool is_autopilot() const override { return false; }
1799 0 : bool logs_attitude() const override { return true; }
1800 :
1801 : // Return true if this mode is enabled, used by MAVLink available modes
1802 : bool enabled() const override;
1803 :
1804 0 : void set_magnitude(float input) { waveform_magnitude.set(input); }
1805 :
1806 : static const struct AP_Param::GroupInfo var_info[];
1807 :
1808 : Chirp chirp_input;
1809 :
1810 : protected:
1811 :
1812 0 : const char *name() const override { return "SystemID"; }
1813 0 : const char *name4() const override { return "SYSI"; }
1814 :
1815 : private:
1816 :
1817 : void log_data() const;
1818 : bool is_poscontrol_axis_type() const;
1819 :
1820 : enum class AxisType {
1821 : NONE = 0, // none
1822 : INPUT_ROLL = 1, // angle input roll axis is being excited
1823 : INPUT_PITCH = 2, // angle pitch axis is being excited
1824 : INPUT_YAW = 3, // angle yaw axis is being excited
1825 : RECOVER_ROLL = 4, // angle roll axis is being excited
1826 : RECOVER_PITCH = 5, // angle pitch axis is being excited
1827 : RECOVER_YAW = 6, // angle yaw axis is being excited
1828 : RATE_ROLL = 7, // rate roll axis is being excited
1829 : RATE_PITCH = 8, // rate pitch axis is being excited
1830 : RATE_YAW = 9, // rate yaw axis is being excited
1831 : MIX_ROLL = 10, // mixer roll axis is being excited
1832 : MIX_PITCH = 11, // mixer pitch axis is being excited
1833 : MIX_YAW = 12, // mixer pitch axis is being excited
1834 : MIX_THROTTLE = 13, // mixer throttle axis is being excited
1835 : DISTURB_POS_LAT = 14, // lateral body axis measured position is being excited
1836 : DISTURB_POS_LONG = 15, // longitudinal body axis measured position is being excited
1837 : DISTURB_VEL_LAT = 16, // lateral body axis measured velocity is being excited
1838 : DISTURB_VEL_LONG = 17, // longitudinal body axis measured velocity is being excited
1839 : INPUT_VEL_LAT = 18, // lateral body axis commanded velocity is being excited
1840 : INPUT_VEL_LONG = 19, // longitudinal body axis commanded velocity is being excited
1841 : };
1842 :
1843 : AP_Int8 axis; // Controls which axis are being excited. Set to non-zero to display other parameters
1844 : AP_Float waveform_magnitude;// Magnitude of chirp waveform
1845 : AP_Float frequency_start; // Frequency at the start of the chirp
1846 : AP_Float frequency_stop; // Frequency at the end of the chirp
1847 : AP_Float time_fade_in; // Time to reach maximum amplitude of chirp
1848 : AP_Float time_record; // Time taken to complete the chirp waveform
1849 : AP_Float time_fade_out; // Time to reach zero amplitude after chirp finishes
1850 :
1851 : bool att_bf_feedforward; // Setting of attitude_control->get_bf_feedforward
1852 : float waveform_time; // Time reference for waveform
1853 : float waveform_sample; // Current waveform sample
1854 : float waveform_freq_rads; // Instantaneous waveform frequency
1855 : float time_const_freq; // Time at constant frequency before chirp starts
1856 : int8_t log_subsample; // Subsample multiple for logging.
1857 : Vector2f target_vel_ne_ms; // target velocity for position controller modes
1858 : Vector2p target_pos_ne_m; // target position
1859 : Vector2f input_vel_last_ne_ms; // last cycle input velocity
1860 : // System ID states
1861 : enum class SystemIDModeState {
1862 : SYSTEMID_STATE_STOPPED,
1863 : SYSTEMID_STATE_TESTING
1864 : } systemid_state;
1865 : };
1866 :
1867 : class ModeThrow : public Mode {
1868 :
1869 : public:
1870 : // inherit constructor
1871 : using Mode::Mode;
1872 91742 : Number mode_number() const override { return Number::THROW; }
1873 :
1874 : bool init(bool ignore_checks) override;
1875 : void run() override;
1876 :
1877 2918 : bool requires_position() const override { return true; }
1878 19209 : bool has_manual_throttle() const override { return false; }
1879 6 : bool allows_arming(AP_Arming::Method method) const override { return true; };
1880 6 : bool is_autopilot() const override { return false; }
1881 :
1882 : // Throw types
1883 : enum class ThrowType {
1884 : Upward = 0,
1885 : Drop = 1
1886 : };
1887 :
1888 : enum class PreThrowMotorState {
1889 : STOPPED = 0,
1890 : RUNNING = 1,
1891 : };
1892 :
1893 : protected:
1894 :
1895 0 : const char *name() const override { return "Throw"; }
1896 6 : const char *name4() const override { return "THRW"; }
1897 :
1898 : private:
1899 :
1900 : bool throw_detected();
1901 : bool throw_position_good() const;
1902 : bool throw_height_good() const;
1903 : bool throw_attitude_good() const;
1904 :
1905 : // Throw stages
1906 : enum ThrowModeStage {
1907 : Throw_Disarmed,
1908 : Throw_Detecting,
1909 : Throw_Wait_Throttle_Unlimited,
1910 : Throw_Uprighting,
1911 : Throw_HgtStabilise,
1912 : Throw_PosHold
1913 : };
1914 :
1915 : ThrowModeStage stage = Throw_Disarmed;
1916 : ThrowModeStage prev_stage = Throw_Disarmed;
1917 : uint32_t last_log_ms;
1918 : bool nextmode_attempted;
1919 : uint32_t free_fall_start_ms; // system time free fall was detected
1920 : float free_fall_start_vel_u_ms; // vertical velocity when free fall was detected
1921 : };
1922 :
1923 : #if MODE_TURTLE_ENABLED
1924 : class ModeTurtle : public Mode {
1925 :
1926 : public:
1927 : // inherit constructors
1928 : using Mode::Mode;
1929 0 : Number mode_number() const override { return Number::TURTLE; }
1930 :
1931 : bool init(bool ignore_checks) override;
1932 : void run() override;
1933 : void exit() override;
1934 :
1935 0 : bool requires_position() const override { return false; }
1936 0 : bool has_manual_throttle() const override { return true; }
1937 : bool allows_arming(AP_Arming::Method method) const override;
1938 0 : bool is_autopilot() const override { return false; }
1939 : void change_motor_direction(bool reverse);
1940 : void output_to_motors() override;
1941 0 : bool allows_entry_in_rc_failsafe() const override { return false; }
1942 :
1943 : // Return true if this mode is enabled, used by MAVLink available modes
1944 : bool enabled() const override;
1945 :
1946 : protected:
1947 0 : const char *name() const override { return "Turtle"; }
1948 0 : const char *name4() const override { return "TRTL"; }
1949 :
1950 : private:
1951 : void arm_motors();
1952 : void disarm_motors();
1953 :
1954 : float motors_output;
1955 : Vector2f motors_input;
1956 : uint32_t last_throttle_warning_output_ms;
1957 :
1958 : // Semaphore to protect the motors from the arming state
1959 : HAL_Semaphore msem;
1960 : bool shutdown;
1961 : };
1962 : #endif
1963 :
1964 : // modes below rely on Guided mode so must be declared at the end (instead of in alphabetical order)
1965 :
1966 : #if AP_ADSB_AVOIDANCE_ENABLED
1967 : class ModeAvoidADSB : public ModeGuided {
1968 :
1969 : public:
1970 : // inherit constructor
1971 : using ModeGuided::Mode;
1972 75505 : Number mode_number() const override { return Number::AVOID_ADSB; }
1973 :
1974 : bool init(bool ignore_checks) override;
1975 : void run() override;
1976 :
1977 50 : bool requires_position() const override { return true; }
1978 589 : bool has_manual_throttle() const override { return false; }
1979 2 : bool allows_arming(AP_Arming::Method method) const override { return false; }
1980 2 : bool is_autopilot() const override { return true; }
1981 :
1982 : bool set_velocity_NEU_ms(const Vector3f& velocity_neu_cms);
1983 :
1984 : protected:
1985 :
1986 2 : const char *name() const override { return "Avoid ADSB"; }
1987 2 : const char *name4() const override { return "AVOI"; }
1988 :
1989 : private:
1990 :
1991 : };
1992 : #endif // AP_ADSB_AVOIDANCE_ENABLED
1993 :
1994 : #if MODE_FOLLOW_ENABLED
1995 : class ModeFollow : public ModeGuided {
1996 :
1997 : public:
1998 :
1999 : // inherit constructor
2000 : using ModeGuided::Mode;
2001 9209 : Number mode_number() const override { return Number::FOLLOW; }
2002 :
2003 : bool init(bool ignore_checks) override;
2004 : void exit() override;
2005 : void run() override;
2006 :
2007 817 : bool requires_position() const override { return true; }
2008 25950 : bool has_manual_throttle() const override { return false; }
2009 2 : bool allows_arming(AP_Arming::Method method) const override { return false; }
2010 7 : bool is_autopilot() const override { return true; }
2011 :
2012 : // Return true if this mode is enabled, used by MAVLink available modes
2013 : bool enabled() const override;
2014 :
2015 : protected:
2016 :
2017 2 : const char *name() const override { return "Follow"; }
2018 7 : const char *name4() const override { return "FOLL"; }
2019 :
2020 : // for reporting to GCS
2021 : bool get_wp(Location &loc) const override;
2022 : float wp_distance_m() const override;
2023 : float wp_bearing_deg() const override;
2024 :
2025 : uint32_t last_log_ms; // system time of last time desired velocity was logging
2026 : };
2027 : #endif
2028 :
2029 : class ModeZigZag : public Mode {
2030 :
2031 : public:
2032 : ModeZigZag(void);
2033 :
2034 : // Inherit constructor
2035 : using Mode::Mode;
2036 148221 : Number mode_number() const override { return Number::ZIGZAG; }
2037 :
2038 : enum class Destination : uint8_t {
2039 : A, // Destination A
2040 : B, // Destination B
2041 : };
2042 :
2043 : enum class Direction : uint8_t {
2044 : FORWARD, // moving forward from the yaw direction
2045 : RIGHT, // moving right from the yaw direction
2046 : BACKWARD, // moving backward from the yaw direction
2047 : LEFT, // moving left from the yaw direction
2048 : } zigzag_direction;
2049 :
2050 : bool init(bool ignore_checks) override;
2051 : void exit() override;
2052 : void run() override;
2053 :
2054 : // auto control methods. copter flies grid pattern
2055 : void run_auto();
2056 : void suspend_auto();
2057 : void init_auto();
2058 :
2059 6824 : bool requires_position() const override { return true; }
2060 225070 : bool has_manual_throttle() const override { return false; }
2061 0 : bool allows_arming(AP_Arming::Method method) const override { return true; }
2062 4 : bool is_autopilot() const override { return true; }
2063 17050 : bool has_user_takeoff(bool must_navigate) const override { return true; }
2064 :
2065 : // save current position as A or B. If both A and B have been saved move to the one specified
2066 : void save_or_move_to_destination(Destination ab_dest);
2067 :
2068 : // return manual control to the pilot
2069 : void return_to_manual_control(bool maintain_target);
2070 :
2071 : static const struct AP_Param::GroupInfo var_info[];
2072 :
2073 : protected:
2074 :
2075 44 : const char *name() const override { return "ZigZag"; }
2076 4 : const char *name4() const override { return "ZIGZ"; }
2077 : float wp_distance_m() const override;
2078 : float wp_bearing_deg() const override;
2079 : float crosstrack_error_m() const override;
2080 :
2081 : private:
2082 :
2083 : void auto_control();
2084 : void manual_control();
2085 : bool reached_destination();
2086 : bool calculate_next_dest_m(Destination ab_dest, bool use_wpnav_alt, Vector3p& next_dest, bool& is_terrain_alt) const;
2087 : void spray(bool b);
2088 : bool calculate_side_dest_m(Vector3p& next_dest_ned_m, bool& is_terrain_alt) const;
2089 : void move_to_side();
2090 :
2091 : Vector2p dest_A_ne_m; // in NE frame in m relative to ekf origin
2092 : Vector2p dest_B_ne_m; // in NE frame in m relative to ekf origin
2093 : Vector3p current_dest_ned_m; // current target destination (use for resume after suspending)
2094 : bool current_is_terr_alt;
2095 :
2096 : // parameters
2097 : AP_Int8 _auto_enabled; // top level enable/disable control
2098 : #if HAL_SPRAYER_ENABLED
2099 : AP_Int8 _spray_enabled; // auto spray enable/disable
2100 : #endif
2101 : AP_Int8 _wp_delay_s; // delay for zigzag waypoint
2102 : AP_Float _side_dist_m; // sideways distance
2103 : AP_Int8 _direction; // sideways direction
2104 : AP_Int16 _line_num; // total number of lines
2105 :
2106 : enum ZigZagState {
2107 : STORING_POINTS, // storing points A and B, pilot has manual control
2108 : AUTO, // after A and B defined, pilot toggle the switch from one side to the other, vehicle flies autonomously
2109 : MANUAL_REGAIN // pilot toggle the switch to middle position, has manual control
2110 : } stage;
2111 :
2112 : enum AutoState {
2113 : MANUAL, // not in ZigZag Auto
2114 : AB_MOVING, // moving from A to B or from B to A
2115 : SIDEWAYS, // moving to sideways
2116 : } auto_stage;
2117 :
2118 : uint32_t reach_wp_time_ms = 0; // time since vehicle reached destination (or zero if not yet reached)
2119 : Destination ab_dest_stored; // store the current destination
2120 : bool is_auto; // enable zigzag auto feature which is automate both AB and sideways
2121 : uint16_t line_count = 0; // current line number
2122 : int16_t line_num = 0; // target line number
2123 : bool is_suspended; // true if zigzag auto is suspended
2124 : };
2125 :
2126 : #if MODE_AUTOROTATE_ENABLED
2127 : class ModeAutorotate : public Mode {
2128 :
2129 : public:
2130 :
2131 : // inherit constructor
2132 : using Mode::Mode;
2133 30660 : Number mode_number() const override { return Number::AUTOROTATE; }
2134 :
2135 : bool init(bool ignore_checks) override;
2136 : void run() override;
2137 :
2138 1 : bool is_autopilot() const override { return true; }
2139 729 : bool requires_position() const override { return false; }
2140 34953 : bool has_manual_throttle() const override { return false; }
2141 0 : bool allows_arming(AP_Arming::Method method) const override { return false; };
2142 :
2143 : static const struct AP_Param::GroupInfo var_info[];
2144 :
2145 : protected:
2146 :
2147 0 : const char *name() const override { return "Autorotate"; }
2148 1 : const char *name4() const override { return "AROT"; }
2149 :
2150 : private:
2151 :
2152 : uint32_t _entry_time_start_ms; // time remaining until entry phase moves on to glide phase
2153 : uint32_t _last_logged_ms; // used for timing slow rate autorotation log
2154 :
2155 : enum class Phase {
2156 : ENTRY_INIT,
2157 : ENTRY,
2158 : GLIDE_INIT,
2159 : GLIDE,
2160 : FLARE_INIT,
2161 : FLARE,
2162 : TOUCH_DOWN_INIT,
2163 : TOUCH_DOWN,
2164 : LANDED_INIT,
2165 : LANDED,
2166 : } current_phase;
2167 :
2168 : };
2169 : #endif
|