AC_WPNav.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. #pragma once
  2. #include <AP_Common/AP_Common.h>
  3. #include <AP_Param/AP_Param.h>
  4. #include <AP_Math/AP_Math.h>
  5. #include <AP_Common/Location.h>
  6. #include <AP_InertialNav/AP_InertialNav.h> // Inertial Navigation library
  7. #include <AC_AttitudeControl/AC_PosControl.h> // Position control library
  8. #include <AC_AttitudeControl/AC_AttitudeControl.h> // Attitude control library
  9. #include <AP_Terrain/AP_Terrain.h>
  10. #include <AC_Avoidance/AC_Avoid.h> // Stop at fence library
  11. // maximum velocities and accelerations
  12. #define WPNAV_ACCELERATION 100.0f // defines the default velocity vs distant curve. maximum acceleration in cm/s/s that position controller asks for from acceleration controller
  13. #define WPNAV_ACCELERATION_MIN 50.0f // minimum acceleration in cm/s/s - used for sanity checking _wp_accel parameter
  14. #define WPNAV_WP_SPEED 500.0f // default horizontal speed between waypoints in cm/s
  15. #define WPNAV_WP_SPEED_MIN 20.0f // minimum horizontal speed between waypoints in cm/s
  16. #define WPNAV_WP_TRACK_SPEED_MIN 50.0f // minimum speed along track of the target point the vehicle is chasing in cm/s (used as target slows down before reaching destination)
  17. #define WPNAV_WP_RADIUS 200.0f // default waypoint radius in cm
  18. #define WPNAV_WP_RADIUS_MIN 5.0f // minimum waypoint radius in cm
  19. #define WPNAV_WP_SPEED_UP 250.0f // default maximum climb velocity
  20. #define WPNAV_WP_SPEED_DOWN 150.0f // default maximum descent velocity
  21. #define WPNAV_WP_ACCEL_Z_DEFAULT 100.0f // default vertical acceleration between waypoints in cm/s/s
  22. #define WPNAV_LEASH_LENGTH_MIN 100.0f // minimum leash lengths in cm
  23. #define WPNAV_WP_FAST_OVERSHOOT_MAX 200.0f // 2m overshoot is allowed during fast waypoints to allow for smooth transitions to next waypoint
  24. #define WPNAV_YAW_DIST_MIN 200 // minimum track length which will lead to target yaw being updated to point at next waypoint. Under this distance the yaw target will be frozen at the current heading
  25. #define WPNAV_YAW_LEASH_PCT_MIN 0.134f // target point must be at least this distance from the vehicle (expressed as a percentage of the maximum distance it can be from the vehicle - i.e. the leash length)
  26. #define WPNAV_RANGEFINDER_FILT_Z 0.25f // range finder distance filtered at 0.25hz
  27. class AC_WPNav
  28. {
  29. public:
  30. // spline segment end types enum
  31. enum spline_segment_end_type {
  32. SEGMENT_END_STOP = 0,
  33. SEGMENT_END_STRAIGHT,
  34. SEGMENT_END_SPLINE
  35. };
  36. /// Constructor
  37. AC_WPNav(const AP_InertialNav& inav, const AP_AHRS_View& ahrs, AC_PosControl& pos_control, const AC_AttitudeControl& attitude_control);
  38. /// provide pointer to terrain database
  39. void set_terrain(AP_Terrain* terrain_ptr) { _terrain = terrain_ptr; }
  40. /// provide rangefinder altitude
  41. void set_rangefinder_alt(bool use, bool healthy, float alt_cm) { _rangefinder_available = use; _rangefinder_healthy = healthy; _rangefinder_alt_cm = alt_cm; }
  42. // return true if range finder may be used for terrain following
  43. bool rangefinder_used() const { return _rangefinder_use && _rangefinder_healthy; }
  44. ///
  45. /// waypoint controller
  46. ///
  47. /// wp_and_spline_init - initialise straight line and spline waypoint controllers
  48. /// updates target roll, pitch targets and I terms based on vehicle lean angles
  49. /// should be called once before the waypoint controller is used but does not need to be called before subsequent updates to destination
  50. void wp_and_spline_init();
  51. /// set current target horizontal speed during wp navigation
  52. void set_speed_xy(float speed_cms);
  53. /// set current target climb or descent rate during wp navigation
  54. void set_speed_up(float speed_up_cms);
  55. void set_speed_down(float speed_down_cms);
  56. /// get default target horizontal velocity during wp navigation
  57. float get_default_speed_xy() const { return _wp_speed_cms; }
  58. /// get default target climb speed in cm/s during missions
  59. float get_default_speed_up() const { return _wp_speed_up_cms; }
  60. /// get default target descent rate in cm/s during missions. Note: always positive
  61. float get_default_speed_down() const { return _wp_speed_down_cms; }
  62. /// get_speed_z - returns target descent speed in cm/s during missions. Note: always positive
  63. float get_accel_z() const { return _wp_accel_z_cmss; }
  64. /// get_wp_acceleration - returns acceleration in cm/s/s during missions
  65. float get_wp_acceleration() const { return _wp_accel_cmss.get(); }
  66. /// get_wp_destination waypoint using position vector (distance from ekf origin in cm)
  67. const Vector3f &get_wp_destination() const { return _destination; }
  68. /// get origin using position vector (distance from ekf origin in cm)
  69. const Vector3f &get_wp_origin() const { return _origin; }
  70. /// true if origin.z and destination.z are alt-above-terrain, false if alt-above-ekf-origin
  71. bool origin_and_destination_are_terrain_alt() const { return _terrain_alt; }
  72. /// set_wp_destination waypoint using location class
  73. /// returns false if conversion from location to vector from ekf origin cannot be calculated
  74. bool set_wp_destination(const Location& destination);
  75. // returns wp location using location class.
  76. // returns false if unable to convert from target vector to global
  77. // coordinates
  78. bool get_wp_destination(Location& destination) const;
  79. // returns object avoidance adjusted destination which is always the same as get_wp_destination
  80. // having this function unifies the AC_WPNav_OA and AC_WPNav interfaces making vehicle code simpler
  81. virtual bool get_oa_wp_destination(Location& destination) const { return get_wp_destination(destination); }
  82. /// set_wp_destination waypoint using position vector (distance from ekf origin in cm)
  83. /// terrain_alt should be true if destination.z is a desired altitude above terrain
  84. bool set_wp_destination(const Vector3f& destination, bool terrain_alt = false);
  85. /// set waypoint destination using NED position vector from ekf origin in meters
  86. bool set_wp_destination_NED(const Vector3f& destination_NED);
  87. /// set_wp_origin_and_destination - set origin and destination waypoints using position vectors (distance from ekf origin in cm)
  88. /// terrain_alt should be true if origin.z and destination.z are desired altitudes above terrain (false if these are alt-above-ekf-origin)
  89. /// returns false on failure (likely caused by missing terrain data)
  90. virtual bool set_wp_origin_and_destination(const Vector3f& origin, const Vector3f& destination, bool terrain_alt = false);
  91. /// shift_wp_origin_to_current_pos - shifts the origin and destination so the origin starts at the current position
  92. /// used to reset the position just before takeoff
  93. /// relies on set_wp_destination or set_wp_origin_and_destination having been called first
  94. void shift_wp_origin_to_current_pos();
  95. /// get_wp_stopping_point_xy - calculates stopping point based on current position, velocity, waypoint acceleration
  96. /// results placed in stopping_position vector
  97. void get_wp_stopping_point_xy(Vector3f& stopping_point) const;
  98. void get_wp_stopping_point(Vector3f& stopping_point) const;
  99. /// get_wp_distance_to_destination - get horizontal distance to destination in cm
  100. virtual float get_wp_distance_to_destination() const;
  101. /// get_bearing_to_destination - get bearing to next waypoint in centi-degrees
  102. virtual int32_t get_wp_bearing_to_destination() const;
  103. /// reached_destination - true when we have come within RADIUS cm of the waypoint
  104. virtual bool reached_wp_destination() const { return _flags.reached_destination; }
  105. // reached_wp_destination_xy - true if within RADIUS_CM of waypoint in x/y
  106. bool reached_wp_destination_xy() const {
  107. return get_wp_distance_to_destination() < _wp_radius_cm;
  108. }
  109. /// set_fast_waypoint - set to true to ignore the waypoint radius and consider the waypoint 'reached' the moment the intermediate point reaches it
  110. void set_fast_waypoint(bool fast) { _flags.fast_waypoint = fast; }
  111. /// update_wpnav - run the wp controller - should be called at 100hz or higher
  112. virtual bool update_wpnav();
  113. // check_wp_leash_length - check recalc_wp_leash flag and calls calculate_wp_leash_length() if necessary
  114. // should be called after _pos_control.update_xy_controller which may have changed the position controller leash lengths
  115. void check_wp_leash_length();
  116. /// calculate_wp_leash_length - calculates track speed, acceleration and leash lengths for waypoint controller
  117. void calculate_wp_leash_length();
  118. ///
  119. /// spline methods
  120. ///
  121. // segment start types
  122. // stop - vehicle is not moving at origin
  123. // straight-fast - vehicle is moving, previous segment is straight. vehicle will fly straight through the waypoint before beginning it's spline path to the next wp
  124. // _flag.segment_type holds whether prev segment is straight vs spline but we don't know if it has a delay
  125. // spline-fast - vehicle is moving, previous segment is splined, vehicle will fly through waypoint but previous segment should have it flying in the correct direction (i.e. exactly parallel to position difference vector from previous segment's origin to this segment's destination)
  126. // segment end types
  127. // stop - vehicle is not moving at destination
  128. // straight-fast - next segment is straight, vehicle's destination velocity should be directly along track from this segment's destination to next segment's destination
  129. // spline-fast - next segment is spline, vehicle's destination velocity should be parallel to position difference vector from previous segment's origin to this segment's destination
  130. // get target yaw in centi-degrees (used for wp and spline navigation)
  131. float get_yaw() const;
  132. /// set_spline_destination waypoint using location class
  133. /// returns false if conversion from location to vector from ekf origin cannot be calculated
  134. /// terrain_alt should be true if destination.z is a desired altitude above terrain (false if its desired altitude above ekf origin)
  135. /// stopped_at_start should be set to true if vehicle is stopped at the origin
  136. /// seg_end_type should be set to stopped, straight or spline depending upon the next segment's type
  137. /// next_destination should be set to the next segment's destination if the seg_end_type is SEGMENT_END_STRAIGHT or SEGMENT_END_SPLINE
  138. bool set_spline_destination(const Location& destination, bool stopped_at_start, spline_segment_end_type seg_end_type, Location next_destination);
  139. /// set_spline_destination waypoint using position vector (distance from ekf origin in cm)
  140. /// returns false if conversion from location to vector from ekf origin cannot be calculated
  141. /// terrain_alt should be true if destination.z is a desired altitudes above terrain (false if its desired altitudes above ekf origin)
  142. /// stopped_at_start should be set to true if vehicle is stopped at the origin
  143. /// seg_end_type should be set to stopped, straight or spline depending upon the next segment's type
  144. /// next_destination should be set to the next segment's destination if the seg_end_type is SEGMENT_END_STRAIGHT or SEGMENT_END_SPLINE
  145. /// next_destination.z must be in the same "frame" as destination.z (i.e. if destination is a alt-above-terrain, next_destination should be too)
  146. bool set_spline_destination(const Vector3f& destination, bool terrain_alt, bool stopped_at_start, spline_segment_end_type seg_end_type, const Vector3f& next_destination);
  147. /// set_spline_origin_and_destination - set origin and destination waypoints using position vectors (distance from ekf origin in cm)
  148. /// terrain_alt should be true if origin.z and destination.z are desired altitudes above terrain (false if desired altitudes above ekf origin)
  149. /// stopped_at_start should be set to true if vehicle is stopped at the origin
  150. /// seg_end_type should be set to stopped, straight or spline depending upon the next segment's type
  151. /// next_destination should be set to the next segment's destination if the seg_end_type is SEGMENT_END_STRAIGHT or SEGMENT_END_SPLINE
  152. bool set_spline_origin_and_destination(const Vector3f& origin, const Vector3f& destination, bool terrain_alt, bool stopped_at_start, spline_segment_end_type seg_end_type, const Vector3f& next_destination);
  153. /// reached_spline_destination - true when we have come within RADIUS cm of the waypoint
  154. bool reached_spline_destination() const { return _flags.reached_destination; }
  155. /// update_spline - update spline controller
  156. bool update_spline();
  157. ///
  158. /// shared methods
  159. ///
  160. /// get desired roll, pitch which should be fed into stabilize controllers
  161. float get_roll() const { return _pos_control.get_roll(); }
  162. float get_pitch() const { return _pos_control.get_pitch(); }
  163. /// advance_wp_target_along_track - move target location along track from origin to destination
  164. bool advance_wp_target_along_track(float dt);
  165. /// return the crosstrack_error - horizontal error of the actual position vs the desired position
  166. float crosstrack_error() const { return _track_error_xy;}
  167. static const struct AP_Param::GroupInfo var_info[];
  168. protected:
  169. // segment types, either straight or spine
  170. enum SegmentType {
  171. SEGMENT_STRAIGHT = 0,
  172. SEGMENT_SPLINE = 1
  173. };
  174. // flags structure
  175. struct wpnav_flags {
  176. uint8_t reached_destination : 1; // true if we have reached the destination
  177. 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
  178. uint8_t slowing_down : 1; // true when target point is slowing down before reaching the destination
  179. uint8_t recalc_wp_leash : 1; // true if we need to recalculate the leash lengths because of changes in speed or acceleration
  180. uint8_t new_wp_destination : 1; // true if we have just received a new destination. allows us to freeze the position controller's xy feed forward
  181. SegmentType segment_type : 1; // active segment is either straight or spline
  182. uint8_t wp_yaw_set : 1; // true if yaw target has been set
  183. } _flags;
  184. /// calc_slow_down_distance - calculates distance before waypoint that target point should begin to slow-down assuming it is traveling at full speed
  185. void calc_slow_down_distance(float speed_cms, float accel_cmss);
  186. /// get_slow_down_speed - returns target speed of target point based on distance from the destination (in cm)
  187. float get_slow_down_speed(float dist_from_dest_cm, float accel_cmss);
  188. /// spline protected functions
  189. /// update_spline_solution - recalculates hermite_spline_solution grid
  190. void update_spline_solution(const Vector3f& origin, const Vector3f& dest, const Vector3f& origin_vel, const Vector3f& dest_vel);
  191. /// advance_spline_target_along_track - move target location along track from origin to destination
  192. /// returns false if it is unable to advance (most likely because of missing terrain data)
  193. bool advance_spline_target_along_track(float dt);
  194. /// calc_spline_pos_vel - update position and velocity from given spline time
  195. /// relies on update_spline_solution being called since the previous
  196. void calc_spline_pos_vel(float spline_time, Vector3f& position, Vector3f& velocity);
  197. // 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)
  198. bool get_terrain_offset(float& offset_cm);
  199. // 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
  200. // returns false if conversion failed (likely because terrain data was not available)
  201. bool get_vector_NEU(const Location &loc, Vector3f &vec, bool &terrain_alt);
  202. // set heading used for spline and waypoint navigation
  203. void set_yaw_cd(float heading_cd);
  204. // references and pointers to external libraries
  205. const AP_InertialNav& _inav;
  206. const AP_AHRS_View& _ahrs;
  207. AC_PosControl& _pos_control;
  208. const AC_AttitudeControl& _attitude_control;
  209. AP_Terrain *_terrain;
  210. // parameters
  211. AP_Float _wp_speed_cms; // default maximum horizontal speed in cm/s during missions
  212. AP_Float _wp_speed_up_cms; // default maximum climb rate in cm/s
  213. AP_Float _wp_speed_down_cms; // default maximum descent rate in cm/s
  214. AP_Float _wp_radius_cm; // distance from a waypoint in cm that, when crossed, indicates the wp has been reached
  215. AP_Float _wp_accel_cmss; // horizontal acceleration in cm/s/s during missions
  216. AP_Float _wp_accel_z_cmss; // vertical acceleration in cm/s/s during missions
  217. // waypoint controller internal variables
  218. uint32_t _wp_last_update; // time of last update_wpnav call
  219. Vector3f _origin; // starting point of trip to next waypoint in cm from ekf origin
  220. Vector3f _destination; // target destination in cm from ekf origin
  221. Vector3f _pos_delta_unit; // each axis's percentage of the total track from origin to destination
  222. float _track_error_xy; // horizontal error of the actual position vs the desired position
  223. float _track_length; // distance in cm between origin and destination
  224. float _track_length_xy; // horizontal distance in cm between origin and destination
  225. float _track_desired; // our desired distance along the track in cm
  226. float _limited_speed_xy_cms; // horizontal speed in cm/s used to advance the intermediate target towards the destination. used to limit extreme acceleration after passing a waypoint
  227. float _track_accel; // acceleration along track
  228. float _track_speed; // speed in cm/s along track
  229. float _track_leash_length; // leash length along track
  230. float _slow_down_dist; // vehicle should begin to slow down once it is within this distance from the destination
  231. // spline variables
  232. float _spline_time; // current spline time between origin and destination
  233. float _spline_time_scale; // current spline time between origin and destination
  234. Vector3f _spline_origin_vel; // the target velocity vector at the origin of the spline segment
  235. Vector3f _spline_destination_vel;// the target velocity vector at the destination point of the spline segment
  236. Vector3f _hermite_spline_solution[4]; // array describing spline path between origin and destination
  237. float _spline_vel_scaler; //
  238. float _yaw; // heading according to yaw
  239. // terrain following variables
  240. bool _terrain_alt; // true if origin and destination.z are alt-above-terrain, false if alt-above-ekf-origin
  241. bool _rangefinder_available;
  242. AP_Int8 _rangefinder_use;
  243. bool _rangefinder_healthy;
  244. float _rangefinder_alt_cm;
  245. };