Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AC_WPNav/AC_WPNav.h
9842 views
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 <AC_AttitudeControl/AC_PosControl.h> // Position control library
10
#include <AC_AttitudeControl/AC_AttitudeControl.h> // Attitude control library
11
#include <AP_Terrain/AP_Terrain.h>
12
#include <AC_Avoidance/AC_Avoid.h> // Stop at fence library
13
14
// maximum velocities and accelerations
15
#define WPNAV_ACCELERATION_MS 2.5 // default horizontal acceleration limit for waypoint navigation (m/s²)
16
17
class AC_WPNav
18
{
19
public:
20
21
/// Constructor
22
AC_WPNav(const AP_AHRS_View& ahrs, AC_PosControl& pos_control, const AC_AttitudeControl& attitude_control);
23
24
// Sets terrain offset in cm from EKF origin using rangefinder.
25
// See set_rangefinder_terrain_U_m() for full details.
26
void set_rangefinder_terrain_U_cm(bool use, bool healthy, float terrain_u_cm) { _rangefinder_available = use; _rangefinder_healthy = healthy; _rangefinder_terrain_u_m = terrain_u_cm * 0.01;}
27
28
// Sets terrain offset in meters from EKF origin using rangefinder data.
29
// This value is used to determine alt-above-terrain for terrain following.
30
void set_rangefinder_terrain_U_m(bool use, bool healthy, float terrain_u_m) { _rangefinder_available = use; _rangefinder_healthy = healthy; _rangefinder_terrain_u_m = terrain_u_m;}
31
32
// Returns true if rangefinder is enabled and may be used for terrain following.
33
bool rangefinder_used() const { return _rangefinder_use; }
34
35
// Returns true if rangefinder is enabled and currently healthy.
36
bool rangefinder_used_and_healthy() const { return _rangefinder_use && _rangefinder_healthy; }
37
38
// Returns the expected source of terrain data when using alt-above-terrain commands.
39
// Used by systems like ModeRTL to determine which terrain provider is active.
40
enum class TerrainSource {
41
TERRAIN_UNAVAILABLE,
42
TERRAIN_FROM_RANGEFINDER,
43
TERRAIN_FROM_TERRAINDATABASE,
44
};
45
AC_WPNav::TerrainSource get_terrain_source() const;
46
47
// Returns terrain offset in meters above the EKF origin at the current position.
48
// Positive values mean terrain lies above the EKF origin altitude.
49
// Source may be rangefinder or terrain database depending on availability.
50
bool get_terrain_U_m(float& terrain_u_m);
51
bool get_terrain_D_m(float& terrain_d_m);
52
53
// Returns the terrain following altitude margin in meters.
54
// Vehicle will stop if distance from target altitude exceeds this margin.
55
float get_terrain_margin_m() const { return MAX(_terrain_margin_m, 0.1); }
56
57
// Converts a Location to a NED position vector in meters from the EKF origin.
58
// Sets `is_terrain_alt` to true if the resulting Z position is relative to terrain.
59
// Returns false if terrain data is unavailable or conversion fails.
60
bool get_vector_NED_m(const Location &loc, Vector3p &pos_from_origin_ned_m, bool &is_terrain_alt);
61
62
///
63
/// waypoint controller
64
///
65
66
// Initializes waypoint and spline navigation using inputs in meters.
67
// Sets speed and acceleration limits, calculates jerk constraints,
68
// and initializes spline or S-curve leg with a defined starting point.
69
void wp_and_spline_init_m(float speed_ms = 0.0f, Vector3p stopping_point_ned_m = Vector3p{});
70
71
// Sets the target horizontal speed in cm/s during waypoint navigation.
72
// See set_speed_NE_ms() for full details.
73
void set_speed_NE_cms(float speed_cms);
74
75
// Sets the target horizontal speed in m/s during waypoint navigation.
76
// Also updates internal velocity offsets and path shaping limits.
77
void set_speed_NE_ms(float speed_ms);
78
79
// Pauses progression along the waypoint track.
80
void set_pause() { _paused = true; }
81
82
// Resumes waypoint navigation after a pause. Track advancement continues from the current position.
83
void set_resume() { _paused = false; }
84
85
// Returns true if waypoint navigation is currently paused via set_pause().
86
bool paused() { return _paused; }
87
88
// Sets the climb speed for waypoint navigation in m/s.
89
// Updates the vertical controller with the new ascent rate limit.
90
void set_speed_up_ms(float speed_up_ms);
91
92
// Sets the descent speed for waypoint navigation in m/s.
93
// Updates the vertical controller with the new descent rate limit.
94
void set_speed_down_ms(float speed_down_ms);
95
96
// Returns the default horizontal speed in cm/s used during waypoint navigation.
97
// See get_default_speed_NE_ms() for full details.
98
float get_default_speed_NE_cms() const { return get_default_speed_NE_ms() * 100.0; }
99
100
// Returns the default horizontal speed in m/s used during waypoint navigation.
101
// Derived from the WPNAV_SPEED parameter.
102
float get_default_speed_NE_ms() const { return _wp_speed_cms * 0.01; }
103
104
// Returns the default climb speed in cm/s used during waypoint navigation.
105
// See get_default_speed_up_ms() for full details.
106
float get_default_speed_up_cms() const { return get_default_speed_up_ms() * 100.0; }
107
108
// Returns the default climb speed in m/s used during waypoint navigation.
109
// Derived from the WPNAV_SPEED_UP parameter.
110
float get_default_speed_up_ms() const { return _wp_speed_up_cms * 0.01; }
111
112
// Returns the default descent rate in cm/s used during waypoint navigation.
113
// Always positive. See get_default_speed_down_ms() for full details.
114
float get_default_speed_down_cms() const { return get_default_speed_down_ms() * 100.0; }
115
116
// Returns the default descent rate in m/s used during waypoint navigation.
117
// Derived from the WPNAV_SPEED_DN parameter. Always positive.
118
float get_default_speed_down_ms() const { return fabsf(_wp_speed_down_cms * 0.01); }
119
120
// Returns the vertical acceleration in cm/s² used during waypoint navigation.
121
// Always positive. See get_accel_D_mss() for full details.
122
float get_accel_D_cmss() const { return get_accel_D_mss() * 100.0; }
123
124
// Returns the vertical acceleration in m/s² used during waypoint navigation.
125
// Derived from the WPNAV_ACCEL_Z parameter. Always positive.
126
float get_accel_D_mss() const { return _wp_accel_z_cmss * 0.01; }
127
128
// Returns the horizontal acceleration in cm/s² used during waypoint navigation.
129
// See get_wp_acceleration_mss() for full details.
130
float get_wp_acceleration_cmss() const { return get_wp_acceleration_mss() * 100.0; }
131
132
// Returns the horizontal acceleration in m/s² used during waypoint navigation.
133
// Derived from the WPNAV_ACCEL parameter. Falls back to a default if unset.
134
float get_wp_acceleration_mss() const { return (is_positive(_wp_accel_cmss)) ? _wp_accel_cmss * 0.01 : WPNAV_ACCELERATION_MS; }
135
136
// Returns the maximum lateral acceleration in m/s² used during waypoint cornering.
137
// Derived from WPNAV_ACCEL_C or defaults to 2x WPNAV_ACCEL if unset.
138
float get_corner_acceleration_mss() const { return (is_positive(_wp_accel_c_cmss)) ? _wp_accel_c_cmss * 0.01 : 2.0 * get_wp_acceleration_mss(); }
139
140
// Returns the destination waypoint vector in NEU frame, in centimeters from EKF origin.
141
// See get_wp_destination_NED_m() for full details.
142
const Vector3f get_wp_destination_NEU_cm() const { return Vector3f(_destination_ned_m.x, _destination_ned_m.y, -_destination_ned_m.z) * 100.0; }
143
144
// Returns the destination waypoint vector in NED frame, in meters from EKF origin.
145
// Z is relative to terrain or EKF origin, depending on _is_terrain_alt.
146
const Vector3p &get_wp_destination_NED_m() const { return _destination_ned_m; }
147
148
// Returns the origin waypoint vector in NED frame, in centimeters from EKF origin.
149
// See get_wp_origin_NED_m() for full details.
150
const Vector3f get_wp_origin_NEU_cm() const { return Vector3f(_origin_ned_m.x, _origin_ned_m.y, -_origin_ned_m.z) * 100.0; }
151
152
// Returns the origin waypoint vector in NED frame, in meters from EKF origin.
153
// This marks the start of the current waypoint leg.
154
const Vector3p &get_wp_origin_NED_m() const { return _origin_ned_m; }
155
156
// Returns true if origin.z and destination.z are specified as altitudes above terrain.
157
// Returns false if altitudes are relative to the EKF origin.
158
bool origin_and_destination_are_terrain_alt() const { return _is_terrain_alt; }
159
160
// Sets the current waypoint destination using a Location object.
161
// Converts global coordinates to NED position and sets destination.
162
// arc_rad specifies the signed arc angle in radians for an ARC_WAYPOINT segment (0 for straight path)
163
// Returns false if conversion fails (e.g. missing terrain data).
164
bool set_wp_destination_loc(const Location& destination, float arc_rad = 0.0);
165
166
// Sets the next waypoint destination using a Location object.
167
// Converts global coordinates to NED position and preloads the trajectory.
168
// arc_rad specifies the signed arc angle in radians for an ARC_WAYPOINT segment (0 for straight path)
169
// Returns false if conversion fails or terrain data is unavailable.
170
bool set_wp_destination_next_loc(const Location& destination, float arc_rad = 0.0);
171
172
// Gets the current waypoint destination as a Location object.
173
// Altitude frame will be ABOVE_TERRAIN or ABOVE_ORIGIN depending on path configuration.
174
// Returns false if origin is not set or coordinate conversion fails.
175
bool get_wp_destination_loc(Location& destination) const;
176
177
// Returns the waypoint destination adjusted for object avoidance.
178
// In the base class this is identical to get_wp_destination_loc().
179
// Used to unify the AC_WPNav and AC_WPNav_OA interfaces.
180
virtual bool get_oa_wp_destination(Location& destination) const { return get_wp_destination_loc(destination); }
181
182
// Sets waypoint destination using NED position vector in centimeters from EKF origin.
183
// See set_wp_destination_NED_m() for full details.
184
virtual bool set_wp_destination_NEU_cm(const Vector3f& destination_neu_cm, bool is_terrain_alt = false);
185
186
// Sets waypoint destination using NED position vector in meters from EKF origin.
187
// If `is_terrain_alt` is true, altitude is interpreted as height above terrain.
188
// Reinitializes the current leg if interrupted, updates origin, and computes trajectory.
189
// arc_rad specifies the signed arc angle in radians for an ARC_WAYPOINT segment (0 for straight path)
190
// Returns false if terrain offset cannot be determined when required.
191
virtual bool set_wp_destination_NED_m(const Vector3p& destination_ned_m, bool is_terrain_alt = false, float arc_rad = 0.0);
192
193
// Sets the next waypoint destination using a NED position vector in meters.
194
// Only updates if terrain frame matches current leg.
195
// Calculates trajectory preview for smoother transition into next segment.
196
// Updates velocity handoff if previous leg is a spline.
197
// arc_rad specifies the signed arc angle in radians for an ARC_WAYPOINT segment (0 for straight path)
198
bool set_wp_destination_next_NED_m(const Vector3p& destination_ned_m, bool is_terrain_alt = false, float arc_rad = 0.0);
199
200
// Computes the horizontal stopping point in NE frame, returned in centimeters.
201
// See get_wp_stopping_point_NE_m() for full details.
202
void get_wp_stopping_point_NE_cm(Vector2f& stopping_point_ne_cm) const;
203
204
// Computes the horizontal stopping point in NE frame, in meters, based on current velocity and configured acceleration.
205
// This is the point where the vehicle would come to a stop if decelerated using the configured limits.
206
void get_wp_stopping_point_NE_m(Vector2p& stopping_point_ne_m) const;
207
208
// Computes the full 3D NED stopping point vector in centimeters based on current kinematics.
209
// See get_wp_stopping_point_NED_m() for full details.
210
void get_wp_stopping_point_NEU_cm(Vector3f& stopping_point_neu_cm) const;
211
212
// Computes the full 3D NED stopping point in meters based on current velocity and configured acceleration in all axes.
213
// Represents where the vehicle will stop if decelerated from current velocity using configured limits.
214
void get_wp_stopping_point_NED_m(Vector3p& stopping_point_ned_m) const;
215
216
// Returns the horizontal distance to the destination waypoint in centimeters.
217
// See get_wp_distance_to_destination_m() for full details.
218
virtual float get_wp_distance_to_destination_cm() const;
219
220
// Returns the horizontal distance in meters between the current position and the destination waypoint.
221
virtual float get_wp_distance_to_destination_m() const;
222
223
// Returns the bearing to the current waypoint destination in centidegrees.
224
// See get_wp_bearing_to_destination_rad() for full details.
225
virtual int32_t get_wp_bearing_to_destination_cd() const;
226
227
// Returns the bearing to the current waypoint destination in radians.
228
// The bearing is measured clockwise from North, with 0 = North.
229
virtual float get_wp_bearing_to_destination_rad() const;
230
231
// Returns true if the vehicle has reached the waypoint destination.
232
// A waypoint is considered reached when the vehicle comes within the defined radius threshold.
233
virtual bool reached_wp_destination() const { return _flags.reached_destination; }
234
235
// Returns true if the vehicle's horizontal (NE) distance to the waypoint is less than the waypoint radius.
236
// Uses the waypoint radius in meters for comparison.
237
bool reached_wp_destination_NE() const {
238
return get_wp_distance_to_destination_m() < _wp_radius_cm * 0.01;
239
}
240
241
// Returns the waypoint acceptance radius in meters.
242
// This radius defines the distance from the target waypoint within which the vehicle is considered to have arrived.
243
float get_wp_radius_m() const { return _wp_radius_cm * 0.01; }
244
245
// Runs the waypoint navigation controller.
246
// Advances the target position and updates the position controller.
247
// Should be called at 100 Hz or higher for accurate tracking.
248
virtual bool update_wpnav();
249
250
// Returns true if update_wpnav() has been called within the last 200 ms.
251
// Used to check if waypoint navigation is currently active.
252
bool is_active() const;
253
254
// Forces a stop at the next waypoint instead of continuing to the subsequent one.
255
// Used by Dijkstra’s object avoidance when the future path is obstructed.
256
// Only affects regular (non-spline) waypoints.
257
// Returns true if the stop behavior was newly enforced.
258
bool force_stop_at_next_wp();
259
260
///
261
/// spline methods
262
///
263
264
// Sets the current spline waypoint using global coordinates.
265
// Converts `destination` and `next_destination` to NED position vectors and sets up a spline between them.
266
// Returns false if conversion from location to vector fails.
267
bool set_spline_destination_loc(const Location& destination, const Location& next_destination, bool next_is_spline);
268
269
// Sets the next spline segment using global coordinates.
270
// Converts the next and next-next destinations to NED position vectors and initializes the spline transition.
271
// Returns false if any conversion from location to vector fails.
272
bool set_spline_destination_next_loc(const Location& next_destination, const Location& next_next_destination, bool next_next_is_spline);
273
274
// Sets the current spline waypoint using NED position vectors in meters.
275
// Initializes a spline path from `destination_ned_m` to `next_destination_ned_m`, respecting terrain altitude framing.
276
// Both waypoints must use the same altitude frame (either above terrain or above origin).
277
// Returns false if terrain altitude cannot be determined when required.
278
bool set_spline_destination_NED_m(const Vector3p& destination_ned_m, bool is_terrain_alt, const Vector3p& next_destination_ned_m, bool next_terrain_alt, bool next_is_spline);
279
280
// Sets the next spline segment using NED position vectors in meters.
281
// Creates a spline path from the current destination to `next_destination_ned_m`, and prepares transition toward `next_next_destination_ned_m`.
282
// All waypoints must use the same altitude frame (above terrain or origin).
283
// Returns false if terrain data is missing and required.
284
bool set_spline_destination_next_NED_m(const Vector3p& next_destination_ned_m, bool next_is_terrain_alt, const Vector3p& next_next_destination_ned_m, bool next_next_is_terrain_alt, bool next_next_is_spline);
285
286
///
287
/// shared methods
288
///
289
290
// Returns the desired roll angle in radians from the position controller.
291
// This value is passed to the attitude controller to achieve lateral motion.
292
float get_roll_rad() const { return _pos_control.get_roll_rad(); }
293
294
// Returns the desired pitch angle in radians from the position controller.
295
// This angle controls forward or backward acceleration.
296
float get_pitch_rad() const { return _pos_control.get_pitch_rad(); }
297
298
// Returns the desired yaw angle in radians from the position controller.
299
// Used to align the vehicle heading with track direction or command input.
300
float get_yaw_rad() const { return _pos_control.get_yaw_rad(); }
301
302
// Returns the desired 3D unit vector representing the commanded thrust direction.
303
// Used to calculate tilt angles for the attitude controller.
304
Vector3f get_thrust_vector() const { return _pos_control.get_thrust_vector(); }
305
306
// Returns the desired roll angle in centidegrees from the position controller.
307
// See get_roll_rad() for full details.
308
float get_roll() const { return rad_to_cd(get_roll_rad()); }
309
310
// Returns the desired pitch angle in centidegrees from the position controller.
311
// See get_pitch_rad() for full details.
312
float get_pitch() const { return rad_to_cd(get_pitch_rad()); }
313
314
// Returns the desired yaw angle in centidegrees from the position controller.
315
// See get_yaw_rad() for full details.
316
float get_yaw() const { return rad_to_cd(get_yaw_rad()); }
317
318
// Advances the target location along the current path segment.
319
// Updates target position, velocity, and acceleration based on jerk-limited profile (or spline).
320
// Returns true if the update succeeded (e.g., terrain data was available).
321
bool advance_wp_target_along_track(float dt);
322
323
// Updates the current and next path segment to reflect new speed and acceleration limits.
324
// Should be called after modifying NE/U controller limits or vehicle configuration.
325
void update_track_with_speed_accel_limits();
326
327
// Returns lateral (cross-track) position error in meters.
328
// Computed as the perpendicular distance between current position and the planned path.
329
// Used to assess horizontal deviation from the trajectory.
330
float crosstrack_error_m() const { return _pos_control.crosstrack_error_m();}
331
332
static const struct AP_Param::GroupInfo var_info[];
333
334
protected:
335
336
// flags structure
337
struct wpnav_flags {
338
uint8_t reached_destination : 1; // true if we have reached the destination
339
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
340
uint8_t wp_yaw_set : 1; // true if yaw target has been set
341
} _flags;
342
343
// Calculates s-curve jerk and snap limits based on attitude controller capabilities.
344
// Updates _scurve_jerk_max_msss and _scurve_snap_max_mssss with constrained values.
345
void calc_scurve_jerk_and_snap();
346
347
// References to shared sensor fusion, position, and attitude control subsystems.
348
const AP_AHRS_View& _ahrs;
349
AC_PosControl& _pos_control;
350
const AC_AttitudeControl& _attitude_control;
351
352
// parameters
353
AP_Float _wp_speed_cms; // default horizontal speed in cm/s for waypoint navigation
354
AP_Float _wp_speed_up_cms; // default climb rate in cm/s for waypoint navigation
355
AP_Float _wp_speed_down_cms; // default descent rate in cm/s for waypoint navigation
356
AP_Float _wp_radius_cm; // waypoint radius in cm; waypoint is considered reached when within this distance
357
AP_Float _wp_accel_cmss; // maximum horizontal acceleration in cm/s² used during waypoint tracking
358
AP_Float _wp_accel_c_cmss; // maximum acceleration in cm/s² for turns; defaults to 2x horizontal accel if unset
359
AP_Float _wp_accel_z_cmss; // maximum vertical acceleration in cm/s² used during climb or descent
360
AP_Float _wp_jerk_msss; // maximum jerk in m/s³ used for s-curve trajectory shaping
361
AP_Float _terrain_margin_m; // minimum altitude margin in meters when terrain following is active
362
363
// WPNAV_SPEED param change checker
364
bool _check_wp_speed_change; // true if WPNAV_SPEED should be monitored for changes during flight
365
float _last_wp_speed_cms; // last recorded WPNAV_SPEED value (cm/s) for change detection
366
float _last_wp_speed_up_cms; // last recorded WPNAV_SPEED_UP value (cm/s)
367
float _last_wp_speed_down_cms; // last recorded WPNAV_SPEED_DN value (cm/s)
368
369
// s-curve trajectory objects
370
SCurve _scurve_prev_leg; // s-curve for the previous waypoint leg, used for smoothing transitions
371
SCurve _scurve_this_leg; // s-curve for the current active waypoint leg
372
SCurve _scurve_next_leg; // s-curve for the next waypoint leg, used for lookahead blending
373
float _scurve_jerk_max_msss; // computed maximum jerk in m/s³ used for trajectory shaping
374
float _scurve_snap_max_mssss; // computed maximum snap in m/s⁴ derived from controller responsiveness
375
376
// spline curves
377
SplineCurve _spline_this_leg; // spline curve for the current segment
378
SplineCurve _spline_next_leg; // spline curve for the next segment
379
380
// path type flags
381
bool _this_leg_is_spline; // true if the current leg uses spline trajectory
382
bool _next_leg_is_spline; // true if the next leg will use spline trajectory
383
384
// waypoint navigation state
385
uint32_t _wp_last_update_ms; // timestamp of the last update_wpnav() call (milliseconds)
386
float _wp_desired_speed_ne_ms; // desired horizontal speed in m/s for the current segment
387
Vector3p _origin_ned_m; // origin of the current leg in meters (NED frame)
388
Vector3p _destination_ned_m; // destination of the current leg in meters (NED frame)
389
Vector3p _next_destination_ned_m; // destination of the next leg in meters (NED frame)
390
float _track_dt_scalar; // scalar to reduce or increase the advancement along the track (0.0–1.0)
391
float _offset_vel_ms; // filtered horizontal speed target (used for terrain following or pause handling)
392
float _offset_accel_mss; // filtered horizontal acceleration target (used for terrain following or pause handling)
393
bool _paused; // true if waypoint controller is paused
394
395
// terrain following state
396
bool _is_terrain_alt; // true if altitude values are relative to terrain height, false if relative to EKF origin
397
bool _rangefinder_available; // true if a rangefinder is enabled and available for use
398
AP_Int8 _rangefinder_use; // parameter specifying whether rangefinder should be used for terrain tracking
399
bool _rangefinder_healthy; // true if the rangefinder reading is valid and within operational range
400
float _rangefinder_terrain_u_m; // rangefinder-derived terrain offset (meters above EKF origin)
401
};
402
403