AP_OADijkstra.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #pragma once
  2. #include <AP_Common/AP_Common.h>
  3. #include <AP_Common/Location.h>
  4. #include <AP_Math/AP_Math.h>
  5. #include <AP_HAL/AP_HAL.h>
  6. #include "AP_OAVisGraph.h"
  7. /*
  8. * Dijkstra's algorithm for path planning around polygon fence
  9. */
  10. class AP_OADijkstra {
  11. public:
  12. AP_OADijkstra();
  13. /* Do not allow copies */
  14. AP_OADijkstra(const AP_OADijkstra &other) = delete;
  15. AP_OADijkstra &operator=(const AP_OADijkstra&) = delete;
  16. // set fence margin (in meters) used when creating "safe positions" within the polygon fence
  17. void set_fence_margin(float margin) { _polyfence_margin = MAX(margin, 0.0f); }
  18. // update return status enum
  19. enum AP_OADijkstra_State : uint8_t {
  20. DIJKSTRA_STATE_NOT_REQUIRED = 0,
  21. DIJKSTRA_STATE_ERROR,
  22. DIJKSTRA_STATE_SUCCESS
  23. };
  24. // calculate a destination to avoid the polygon fence
  25. // returns DIJKSTRA_STATE_SUCCESS and populates origin_new and destination_new if avoidance is required
  26. AP_OADijkstra_State update(const Location &current_loc, const Location &destination, Location& origin_new, Location& destination_new);
  27. private:
  28. // returns true if polygon fence is enabled
  29. bool polygon_fence_enabled() const;
  30. // check if polygon fence has been updated since we created the inner fence. returns true if changed
  31. bool check_polygon_fence_updated() const;
  32. // create a smaller polygon fence within the existing polygon fence
  33. // returns true on success
  34. bool create_polygon_fence_with_margin(float margin_cm);
  35. // create a visibility graph of the polygon fence
  36. // returns true on success
  37. // requires create_polygon_fence_with_margin to have been run
  38. bool create_polygon_fence_visgraph();
  39. // calculate shortest path from origin to destination
  40. // returns true on success
  41. // requires create_polygon_fence_with_margin and create_polygon_fence_visgraph to have been run
  42. // resulting path is stored in _shortest_path array as vector offsets from EKF origin
  43. bool calc_shortest_path(const Location &origin, const Location &destination);
  44. // shortest path state variables
  45. bool _polyfence_with_margin_ok;
  46. bool _polyfence_visgraph_ok;
  47. bool _shortest_path_ok;
  48. Location _destination_prev; // destination of previous iterations (used to determine if path should be re-calculated)
  49. uint8_t _path_idx_returned; // index into _path array which gives location vehicle should be currently moving towards
  50. // polygon fence (with margin) related variables
  51. float _polyfence_margin = 10;
  52. AP_ExpandingArray<Vector2f> _polyfence_pts;
  53. uint8_t _polyfence_numpoints;
  54. uint32_t _polyfence_update_ms; // system time of boundary update from AC_Fence (used to detect changes to polygon fence)
  55. // visibility graphs
  56. AP_OAVisGraph _polyfence_visgraph;
  57. AP_OAVisGraph _source_visgraph;
  58. AP_OAVisGraph _destination_visgraph;
  59. // updates visibility graph for a given position which is an offset (in cm) from the ekf origin
  60. // to add an additional position (i.e. the destination) set add_extra_position = true and provide the position in the extra_position argument
  61. // requires create_polygon_fence_with_margin to have been run
  62. // returns true on success
  63. bool update_visgraph(AP_OAVisGraph& visgraph, const AP_OAVisGraph::OAItemID& oaid, const Vector2f &position, bool add_extra_position = false, Vector2f extra_position = Vector2f(0,0));
  64. typedef uint8_t node_index; // indices into short path data
  65. struct ShortPathNode {
  66. AP_OAVisGraph::OAItemID id; // unique id for node (combination of type and id number)
  67. bool visited; // true if all this node's neighbour's distances have been updated
  68. node_index distance_from_idx; // index into _short_path_data from where distance was updated (or 255 if not set)
  69. float distance_cm; // distance from source (number is tentative until this node is the current node and/or visited = true)
  70. };
  71. AP_ExpandingArray<ShortPathNode> _short_path_data;
  72. node_index _short_path_data_numpoints; // number of elements in _short_path_data array
  73. // update total distance for all nodes visible from current node
  74. // curr_node_idx is an index into the _short_path_data array
  75. void update_visible_node_distances(node_index curr_node_idx);
  76. // find a node's index into _short_path_data array from it's id (i.e. id type and id number)
  77. // returns true if successful and node_idx is updated
  78. bool find_node_from_id(const AP_OAVisGraph::OAItemID &id, node_index &node_idx) const;
  79. // find index of node with lowest tentative distance (ignore visited nodes)
  80. // returns true if successful and node_idx argument is updated
  81. bool find_closest_node_idx(node_index &node_idx) const;
  82. // final path variables and functions
  83. AP_ExpandingArray<AP_OAVisGraph::OAItemID> _path; // ids of points on return path in reverse order (i.e. destination is first element)
  84. uint8_t _path_numpoints; // number of points on return path
  85. Vector2f _path_source; // source point used in shortest path calculations (offset in cm from EKF origin)
  86. Vector2f _path_destination; // destination position used in shortest path calculations (offset in cm from EKF origin)
  87. // return point from final path as an offset (in cm) from the ekf origin
  88. bool get_shortest_path_point(uint8_t point_num, Vector2f& pos);
  89. };