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/libraries/AC_WPNav/AC_WPNav.h
Views: 1798
1
#pragma once
2
3
#include <AP_Common/AP_Common.h>
4
#include <AP_Param/AP_Param.h>
5
#include <AP_Math/AP_Math.h>
6
#include <AP_Math/SCurve.h>
7
#include <AP_Math/SplineCurve.h>
8
#include <AP_Common/Location.h>
9
#include <AP_InertialNav/AP_InertialNav.h> // Inertial Navigation library
10
#include <AC_AttitudeControl/AC_PosControl.h> // Position control library
11
#include <AC_AttitudeControl/AC_AttitudeControl.h> // Attitude control library
12
#include <AP_Terrain/AP_Terrain.h>
13
#include <AC_Avoidance/AC_Avoid.h> // Stop at fence library
14
15
// maximum velocities and accelerations
16
#define WPNAV_ACCELERATION 250.0f // maximum horizontal acceleration in cm/s/s that wp navigation will request
17
18
class AC_WPNav
19
{
20
public:
21
22
/// Constructor
23
AC_WPNav(const AP_InertialNav& inav, const AP_AHRS_View& ahrs, AC_PosControl& pos_control, const AC_AttitudeControl& attitude_control);
24
25
/// provide rangefinder based terrain offset
26
/// terrain offset is the terrain's height above the EKF origin
27
void set_rangefinder_terrain_offset(bool use, bool healthy, float terrain_offset_cm) { _rangefinder_available = use; _rangefinder_healthy = healthy; _rangefinder_terrain_offset_cm = terrain_offset_cm;}
28
29
// return true if range finder may be used for terrain following
30
bool rangefinder_used() const { return _rangefinder_use; }
31
bool rangefinder_used_and_healthy() const { return _rangefinder_use && _rangefinder_healthy; }
32
33
// get expected source of terrain data if alt-above-terrain command is executed (used by Copter's ModeRTL)
34
enum class TerrainSource {
35
TERRAIN_UNAVAILABLE,
36
TERRAIN_FROM_RANGEFINDER,
37
TERRAIN_FROM_TERRAINDATABASE,
38
};
39
AC_WPNav::TerrainSource get_terrain_source() const;
40
41
// get terrain's altitude (in cm above the ekf origin) at the current position (+ve means terrain below vehicle is above ekf origin's altitude)
42
bool get_terrain_offset(float& offset_cm);
43
44
// return terrain following altitude margin. vehicle will stop if distance from target altitude is larger than this margin
45
float get_terrain_margin() const { return MAX(_terrain_margin, 0.1); }
46
47
// convert location to vector from ekf origin. terrain_alt is set to true if resulting vector's z-axis should be treated as alt-above-terrain
48
// returns false if conversion failed (likely because terrain data was not available)
49
bool get_vector_NEU(const Location &loc, Vector3f &vec, bool &terrain_alt);
50
51
///
52
/// waypoint controller
53
///
54
55
/// wp_and_spline_init - initialise straight line and spline waypoint controllers
56
/// speed_cms is the desired max speed to travel between waypoints. should be a positive value or omitted to use the default speed
57
/// updates target roll, pitch targets and I terms based on vehicle lean angles
58
/// should be called once before the waypoint controller is used but does not need to be called before subsequent updates to destination
59
void wp_and_spline_init(float speed_cms = 0.0f, Vector3f stopping_point = Vector3f{});
60
61
/// set current target horizontal speed during wp navigation
62
void set_speed_xy(float speed_cms);
63
64
/// set pause or resume during wp navigation
65
void set_pause() { _paused = true; }
66
void set_resume() { _paused = false; }
67
68
/// get paused status
69
bool paused() { return _paused; }
70
71
/// set current target climb or descent rate during wp navigation
72
void set_speed_up(float speed_up_cms);
73
void set_speed_down(float speed_down_cms);
74
75
/// get default target horizontal velocity during wp navigation
76
float get_default_speed_xy() const { return _wp_speed_cms; }
77
78
/// get default target climb speed in cm/s during missions
79
float get_default_speed_up() const { return _wp_speed_up_cms; }
80
81
/// get default target descent rate in cm/s during missions. Note: always positive
82
float get_default_speed_down() const { return fabsf(_wp_speed_down_cms); }
83
84
/// get_speed_z - returns target descent speed in cm/s during missions. Note: always positive
85
float get_accel_z() const { return _wp_accel_z_cmss; }
86
87
/// get_wp_acceleration - returns acceleration in cm/s/s during missions
88
float get_wp_acceleration() const { return (is_positive(_wp_accel_cmss)) ? _wp_accel_cmss : WPNAV_ACCELERATION; }
89
90
/// get_corner_acceleration - returns maximum acceleration in cm/s/s used during cornering in missions
91
float get_corner_acceleration() const { return (is_positive(_wp_accel_c_cmss)) ? _wp_accel_c_cmss : 2.0 * get_wp_acceleration(); }
92
93
/// get_wp_destination waypoint using position vector
94
/// x,y are distance from ekf origin in cm
95
/// z may be cm above ekf origin or terrain (see origin_and_destination_are_terrain_alt method)
96
const Vector3f &get_wp_destination() const { return _destination; }
97
98
/// get origin using position vector (distance from ekf origin in cm)
99
const Vector3f &get_wp_origin() const { return _origin; }
100
101
/// true if origin.z and destination.z are alt-above-terrain, false if alt-above-ekf-origin
102
bool origin_and_destination_are_terrain_alt() const { return _terrain_alt; }
103
104
/// set_wp_destination waypoint using location class
105
/// provide the next_destination if known
106
/// returns false if conversion from location to vector from ekf origin cannot be calculated
107
bool set_wp_destination_loc(const Location& destination);
108
bool set_wp_destination_next_loc(const Location& destination);
109
110
// get destination as a location. Altitude frame will be absolute (AMSL) or above terrain
111
// returns false if unable to return a destination (for example if origin has not yet been set)
112
bool get_wp_destination_loc(Location& destination) const;
113
114
// returns object avoidance adjusted destination which is always the same as get_wp_destination
115
// having this function unifies the AC_WPNav_OA and AC_WPNav interfaces making vehicle code simpler
116
virtual bool get_oa_wp_destination(Location& destination) const { return get_wp_destination_loc(destination); }
117
118
/// set_wp_destination waypoint using position vector (distance from ekf origin in cm)
119
/// terrain_alt should be true if destination.z is a desired altitude above terrain
120
virtual bool set_wp_destination(const Vector3f& destination, bool terrain_alt = false);
121
bool set_wp_destination_next(const Vector3f& destination, bool terrain_alt = false);
122
123
/// set waypoint destination using NED position vector from ekf origin in meters
124
/// provide next_destination_NED if known
125
bool set_wp_destination_NED(const Vector3f& destination_NED);
126
bool set_wp_destination_next_NED(const Vector3f& destination_NED);
127
128
/// shifts the origin and destination horizontally to the current position
129
/// used to reset the track when taking off without horizontal position control
130
/// relies on set_wp_destination or set_wp_origin_and_destination having been called first
131
void shift_wp_origin_and_destination_to_current_pos_xy();
132
133
/// shifts the origin and destination horizontally to the achievable stopping point
134
/// used to reset the track when horizontal navigation is enabled after having been disabled (see Copter's wp_navalt_min)
135
/// relies on set_wp_destination or set_wp_origin_and_destination having been called first
136
void shift_wp_origin_and_destination_to_stopping_point_xy();
137
138
/// get_wp_stopping_point_xy - calculates stopping point based on current position, velocity, waypoint acceleration
139
/// results placed in stopping_position vector
140
void get_wp_stopping_point_xy(Vector2f& stopping_point) const;
141
void get_wp_stopping_point(Vector3f& stopping_point) const;
142
143
/// get_wp_distance_to_destination - get horizontal distance to destination in cm
144
virtual float get_wp_distance_to_destination() const;
145
146
/// get_bearing_to_destination - get bearing to next waypoint in centi-degrees
147
virtual int32_t get_wp_bearing_to_destination() const;
148
149
/// reached_destination - true when we have come within RADIUS cm of the waypoint
150
virtual bool reached_wp_destination() const { return _flags.reached_destination; }
151
152
// reached_wp_destination_xy - true if within RADIUS_CM of waypoint in x/y
153
bool reached_wp_destination_xy() const {
154
return get_wp_distance_to_destination() < _wp_radius_cm;
155
}
156
157
// get wp_radius parameter value in cm
158
float get_wp_radius_cm() const { return _wp_radius_cm; }
159
160
/// update_wpnav - run the wp controller - should be called at 100hz or higher
161
virtual bool update_wpnav();
162
163
// returns true if update_wpnav has been run very recently
164
bool is_active() const;
165
166
// force stopping at next waypoint. Used by Dijkstra's object avoidance when path from destination to next destination is not clear
167
// only affects regular (e.g. non-spline) waypoints
168
// returns true if this had any affect on the path
169
bool force_stop_at_next_wp();
170
171
///
172
/// spline methods
173
///
174
175
/// set_spline_destination waypoint using location class
176
/// returns false if conversion from location to vector from ekf origin cannot be calculated
177
/// next_destination should be the next segment's destination
178
/// next_is_spline should be true if next_destination is a spline segment
179
bool set_spline_destination_loc(const Location& destination, const Location& next_destination, bool next_is_spline);
180
181
/// set next destination (e.g. the one after the current destination) as a spline segment specified as a location
182
/// returns false if conversion from location to vector from ekf origin cannot be calculated
183
/// next_next_destination should be the next segment's destination
184
/// next_next_is_spline should be true if next_next_destination is a spline segment
185
bool set_spline_destination_next_loc(const Location& next_destination, const Location& next_next_destination, bool next_next_is_spline);
186
187
/// set_spline_destination waypoint using position vector (distance from ekf origin in cm)
188
/// terrain_alt should be true if destination.z is a desired altitude above terrain (false if its desired altitudes above ekf origin)
189
/// next_destination is the next segment's destination
190
/// next_terrain_alt should be true if next_destination.z is a desired altitude above terrain (false if its desired altitudes above ekf origin)
191
/// next_destination.z must be in the same "frame" as destination.z (i.e. if destination is a alt-above-terrain, next_destination must be too)
192
/// next_is_spline should be true if next_destination is a spline segment
193
bool set_spline_destination(const Vector3f& destination, bool terrain_alt, const Vector3f& next_destination, bool next_terrain_alt, bool next_is_spline);
194
195
/// set next destination (e.g. the one after the current destination) as an offset (in cm, NEU frame) from the EKF origin
196
/// next_terrain_alt should be true if next_destination.z is a desired altitude above terrain (false if its desired altitudes above ekf origin)
197
/// next_next_destination is the next segment's destination
198
/// next_next_terrain_alt should be true if next_next_destination.z is a desired altitude above terrain (false if it is desired altitude above ekf origin)
199
/// next_next_destination.z must be in the same "frame" as destination.z (i.e. if next_destination is a alt-above-terrain, next_next_destination must be too)
200
/// next_next_is_spline should be true if next_next_destination is a spline segment
201
bool set_spline_destination_next(const Vector3f& next_destination, bool next_terrain_alt, const Vector3f& next_next_destination, bool next_next_terrain_alt, bool next_next_is_spline);
202
203
///
204
/// shared methods
205
///
206
207
/// get desired roll, pitch which should be fed into stabilize controllers
208
float get_roll() const { return _pos_control.get_roll_cd(); }
209
float get_pitch() const { return _pos_control.get_pitch_cd(); }
210
Vector3f get_thrust_vector() const { return _pos_control.get_thrust_vector(); }
211
212
// get target yaw in centi-degrees
213
float get_yaw() const { return _pos_control.get_yaw_cd(); }
214
/// advance_wp_target_along_track - move target location along track from origin to destination
215
bool advance_wp_target_along_track(float dt);
216
217
/// recalculate path with update speed and/or acceleration limits
218
void update_track_with_speed_accel_limits();
219
220
/// return the crosstrack_error - horizontal error of the actual position vs the desired position
221
float crosstrack_error() const { return _pos_control.crosstrack_error();}
222
223
static const struct AP_Param::GroupInfo var_info[];
224
225
protected:
226
227
// flags structure
228
struct wpnav_flags {
229
uint8_t reached_destination : 1; // true if we have reached the destination
230
uint8_t fast_waypoint : 1; // true if we should ignore the waypoint radius and consider the waypoint complete once the intermediate target has reached the waypoint
231
uint8_t wp_yaw_set : 1; // true if yaw target has been set
232
} _flags;
233
234
// helper function to calculate scurve jerk and jerk_time values
235
// updates _scurve_jerk and _scurve_snap
236
void calc_scurve_jerk_and_snap();
237
238
// references and pointers to external libraries
239
const AP_InertialNav& _inav;
240
const AP_AHRS_View& _ahrs;
241
AC_PosControl& _pos_control;
242
const AC_AttitudeControl& _attitude_control;
243
244
// parameters
245
AP_Float _wp_speed_cms; // default maximum horizontal speed in cm/s during missions
246
AP_Float _wp_speed_up_cms; // default maximum climb rate in cm/s
247
AP_Float _wp_speed_down_cms; // default maximum descent rate in cm/s
248
AP_Float _wp_radius_cm; // distance from a waypoint in cm that, when crossed, indicates the wp has been reached
249
AP_Float _wp_accel_cmss; // horizontal acceleration in cm/s/s during missions
250
AP_Float _wp_accel_c_cmss; // cornering acceleration in cm/s/s during missions
251
AP_Float _wp_accel_z_cmss; // vertical acceleration in cm/s/s during missions
252
AP_Float _wp_jerk; // maximum jerk used to generate scurve trajectories in m/s/s/s
253
AP_Float _terrain_margin; // terrain following altitude margin. vehicle will stop if distance from target altitude is larger than this margin
254
255
// WPNAV_SPEED param change checker
256
bool _check_wp_speed_change; // if true WPNAV_SPEED param should be checked for changes in-flight
257
float _last_wp_speed_cms; // last recorded WPNAV_SPEED, used for changing speed in-flight
258
float _last_wp_speed_up_cms; // last recorded WPNAV_SPEED_UP, used for changing speed in-flight
259
float _last_wp_speed_down_cms; // last recorded WPNAV_SPEED_DN, used for changing speed in-flight
260
261
// scurve
262
SCurve _scurve_prev_leg; // previous scurve trajectory used to blend with current scurve trajectory
263
SCurve _scurve_this_leg; // current scurve trajectory
264
SCurve _scurve_next_leg; // next scurve trajectory used to blend with current scurve trajectory
265
float _scurve_jerk; // scurve jerk max in m/s/s/s
266
float _scurve_snap; // scurve snap in m/s/s/s/s
267
268
// spline curves
269
SplineCurve _spline_this_leg; // spline curve for current segment
270
SplineCurve _spline_next_leg; // spline curve for next segment
271
272
// the type of this leg
273
bool _this_leg_is_spline; // true if this leg is a spline
274
bool _next_leg_is_spline; // true if the next leg is a spline
275
276
// waypoint controller internal variables
277
uint32_t _wp_last_update; // time of last update_wpnav call
278
float _wp_desired_speed_xy_cms; // desired wp speed in cm/sec
279
Vector3f _origin; // starting point of trip to next waypoint in cm from ekf origin
280
Vector3f _destination; // target destination in cm from ekf origin
281
Vector3f _next_destination; // next target destination in cm from ekf origin
282
float _track_scalar_dt; // time compression multiplier to slow the progress along the track
283
float _offset_vel; // horizontal velocity reference used to slow the aircraft for pause and to ensure the aircraft can maintain height above terrain
284
float _offset_accel; // horizontal acceleration reference used to slow the aircraft for pause and to ensure the aircraft can maintain height above terrain
285
bool _paused; // flag for pausing waypoint controller
286
287
// terrain following variables
288
bool _terrain_alt; // true if origin and destination.z are alt-above-terrain, false if alt-above-ekf-origin
289
bool _rangefinder_available; // true if rangefinder is enabled (user switch can turn this true/false)
290
AP_Int8 _rangefinder_use; // parameter that specifies if the range finder should be used for terrain following commands
291
bool _rangefinder_healthy; // true if rangefinder distance is healthy (i.e. between min and maximum)
292
float _rangefinder_terrain_offset_cm; // latest rangefinder based terrain offset (e.g. terrain's height above EKF origin)
293
};
294
295