CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

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