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