AP_Avoidance.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #pragma once
  2. /*
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. Situational awareness for ArduPilot
  16. - record a series of moving points in space which should be avoided
  17. - produce messages for GCS if a collision risk is detected
  18. Peter Barker, May 2016
  19. based on AP_ADSB, Tom Pittenger, November 2015
  20. */
  21. #include <AP_ADSB/AP_ADSB.h>
  22. // F_RCVRY possible parameter values
  23. #define AP_AVOIDANCE_RECOVERY_REMAIN_IN_AVOID_ADSB 0
  24. #define AP_AVOIDANCE_RECOVERY_RESUME_PREVIOUS_FLIGHTMODE 1
  25. #define AP_AVOIDANCE_RECOVERY_RTL 2
  26. #define AP_AVOIDANCE_RECOVERY_RESUME_IF_AUTO_ELSE_LOITER 3
  27. #define AP_AVOIDANCE_STATE_RECOVERY_TIME_MS 2000 // we will not downgrade state any faster than this (2 seconds)
  28. #define AP_AVOIDANCE_ESCAPE_TIME_SEC 2 // vehicle runs from thread for 2 seconds
  29. class AP_Avoidance {
  30. public:
  31. // constructor
  32. AP_Avoidance(class AP_ADSB &adsb);
  33. // obstacle class to hold latest information for a known obstacles
  34. class Obstacle {
  35. public:
  36. MAV_COLLISION_SRC src;
  37. uint32_t src_id;
  38. uint32_t timestamp_ms;
  39. Location _location;
  40. Vector3f _velocity;
  41. // fields relating to this being a threat. These would be the reason to have a separate list of threats:
  42. MAV_COLLISION_THREAT_LEVEL threat_level;
  43. float closest_approach_xy; // metres
  44. float closest_approach_z; // metres
  45. float time_to_closest_approach; // seconds, 3D approach
  46. float distance_to_closest_approach; // metres, 3D
  47. uint32_t last_gcs_report_time; // millis
  48. };
  49. // add obstacle to the list of known obstacles
  50. void add_obstacle(uint32_t obstacle_timestamp_ms,
  51. const MAV_COLLISION_SRC src,
  52. uint32_t src_id,
  53. const Location &loc,
  54. const Vector3f &vel_ned);
  55. void add_obstacle(uint32_t obstacle_timestamp_ms,
  56. const MAV_COLLISION_SRC src,
  57. uint32_t src_id,
  58. const Location &loc,
  59. float cog,
  60. float hspeed,
  61. float vspeed);
  62. // update should be called at 10hz or higher
  63. void update();
  64. // enable or disable avoidance
  65. void enable() { _enabled = true; };
  66. void disable() { _enabled = false; };
  67. // current overall threat level
  68. MAV_COLLISION_THREAT_LEVEL current_threat_level() const;
  69. // add obstacles into the Avoidance system from MAVLink messages
  70. void handle_msg(const mavlink_message_t &msg);
  71. // for holding parameters
  72. static const struct AP_Param::GroupInfo var_info[];
  73. protected:
  74. // top level avoidance handler. This calls the vehicle specific handle_avoidance with requested action
  75. void handle_avoidance_local(AP_Avoidance::Obstacle *threat);
  76. // avoid the most significant threat. child classes must override this method
  77. // function returns the action that it is actually taking
  78. virtual MAV_COLLISION_ACTION handle_avoidance(const AP_Avoidance::Obstacle *obstacle, MAV_COLLISION_ACTION requested_action) = 0;
  79. // recover after all threats have cleared. child classes must override this method
  80. // recovery_action is from F_RCVRY parameter
  81. virtual void handle_recovery(uint8_t recovery_action) = 0;
  82. uint32_t _last_state_change_ms = 0;
  83. MAV_COLLISION_THREAT_LEVEL _threat_level = MAV_COLLISION_THREAT_LEVEL_NONE;
  84. // gcs notification
  85. // specifies how long we should continue sending messages about a threat after it has cleared
  86. static const uint8_t _gcs_cleared_messages_duration = 5; // seconds
  87. uint32_t _gcs_cleared_messages_first_sent;
  88. void handle_threat_gcs_notify(AP_Avoidance::Obstacle *threat);
  89. AP_Avoidance::Obstacle *most_serious_threat();
  90. // returns an entry from the MAV_COLLISION_ACTION representative
  91. // of what the current avoidance handler is up to.
  92. MAV_COLLISION_ACTION mav_avoidance_action() { return _latest_action; }
  93. // get target destination that best gets vehicle away from the nearest obstacle
  94. bool get_destination_perpendicular(const AP_Avoidance::Obstacle *obstacle, Vector3f &newdest_neu, const float wp_speed_xy, const float wp_speed_z, const uint8_t _minimum_avoid_height);
  95. // get unit vector away from the nearest obstacle
  96. bool get_vector_perpendicular(const AP_Avoidance::Obstacle *obstacle, Vector3f &vec_neu);
  97. // helper functions to calculate destination to get us away from obstacle
  98. // Note: v1 is NED
  99. static Vector3f perpendicular_xyz(const Location &p1, const Vector3f &v1, const Location &p2);
  100. static Vector2f perpendicular_xy(const Location &p1, const Vector3f &v1, const Location &p2);
  101. private:
  102. void send_collision_all(const AP_Avoidance::Obstacle &threat, MAV_COLLISION_ACTION behaviour) const;
  103. // constants
  104. const uint32_t MAX_OBSTACLE_AGE_MS = 5000; // obstacles that have not been heard from for 5 seconds are removed from the list
  105. const static uint8_t _gcs_notify_interval = 1; // seconds
  106. // speed below which we will fly directly away from a threat
  107. // rather than perpendicular to its velocity:
  108. const uint8_t _low_velocity_threshold = 1; // meters/second
  109. // check to see if we are initialised (and possibly do initialisation)
  110. bool check_startup();
  111. // initialize _obstacle_list
  112. void init();
  113. // free _obstacle_list
  114. void deinit();
  115. // get unique id for adsb
  116. uint32_t src_id_for_adsb_vehicle(const AP_ADSB::adsb_vehicle_t &vehicle) const;
  117. void check_for_threats();
  118. void update_threat_level(const Location &my_loc,
  119. const Vector3f &my_vel,
  120. AP_Avoidance::Obstacle &obstacle);
  121. // calls into the AP_ADSB library to retrieve vehicle data
  122. void get_adsb_samples();
  123. // returns true if the obstacle should be considered more of a
  124. // threat than the current most serious threat
  125. bool obstacle_is_more_serious_threat(const AP_Avoidance::Obstacle &obstacle) const;
  126. // internal variables
  127. AP_Avoidance::Obstacle *_obstacles;
  128. uint8_t _obstacles_allocated;
  129. uint8_t _obstacle_count;
  130. int8_t _current_most_serious_threat;
  131. MAV_COLLISION_ACTION _latest_action = MAV_COLLISION_ACTION_NONE;
  132. // external references
  133. class AP_ADSB &_adsb;
  134. // parameters
  135. AP_Int8 _enabled;
  136. AP_Int8 _obstacles_max;
  137. AP_Int8 _fail_action;
  138. AP_Int8 _fail_recovery;
  139. AP_Int8 _fail_time_horizon;
  140. AP_Int16 _fail_distance_xy;
  141. AP_Int16 _fail_distance_z;
  142. AP_Int16 _fail_altitude_minimum;
  143. AP_Int8 _warn_action;
  144. AP_Int8 _warn_time_horizon;
  145. AP_Float _warn_distance_xy;
  146. AP_Float _warn_distance_z;
  147. // multi-thread support for avoidance
  148. HAL_Semaphore_Recursive _rsem;
  149. };
  150. float closest_approach_xy(const Location &my_loc,
  151. const Vector3f &my_vel,
  152. const Location &obstacle_loc,
  153. const Vector3f &obstacle_vel,
  154. uint8_t time_horizon);
  155. float closest_approach_z(const Location &my_loc,
  156. const Vector3f &my_vel,
  157. const Location &obstacle_loc,
  158. const Vector3f &obstacle_vel,
  159. uint8_t time_horizon);