17 #ifndef NAV2_SMAC_PLANNER__GOAL_MANAGER_HPP_
18 #define NAV2_SMAC_PLANNER__GOAL_MANAGER_HPP_
22 #include <type_traits>
23 #include <unordered_set>
26 #include "nav2_smac_planner/types.hpp"
27 #include "nav2_smac_planner/node_2d.hpp"
28 #include "nav2_smac_planner/node_hybrid.hpp"
29 #include "nav2_smac_planner/node_lattice.hpp"
30 #include "nav2_smac_planner/node_basic.hpp"
31 #include "nav2_smac_planner/collision_checker.hpp"
34 namespace nav2_smac_planner
41 template<
typename NodeT>
45 typedef NodeT * NodePtr;
46 typedef std::vector<NodePtr> NodeVector;
47 typedef std::unordered_set<NodePtr> NodeSet;
48 typedef std::vector<GoalState<NodeT>> GoalStateVector;
49 typedef typename NodeT::Coordinates Coordinates;
50 typedef typename NodeT::CoordinateVector CoordinateVector;
51 using NodeContext =
typename NodeT::NodeContext;
57 : _goals_set(NodeSet()),
58 _goals_state(GoalStateVector()),
59 _goals_coordinate(CoordinateVector()),
60 _ref_goal_coord(Coordinates())
84 return _goals_state.empty();
93 _goals_state.push_back({goal,
true});
102 _goals_state.clear();
103 _goals_coordinate.clear();
113 NodeVector & coarse_check_goals, NodeVector & fine_check_goals,
114 int coarse_search_resolution)
116 for (
unsigned int i = 0; i < _goals_state.size(); i++) {
117 if (_goals_state[i].is_valid) {
118 if (i % coarse_search_resolution == 0) {
119 coarse_check_goals.push_back(_goals_state[i].goal);
121 fine_check_goals.push_back(_goals_state[i].goal);
139 const bool & traverse_unknown)
const
148 auto getIndexFromPoint = [
this, &size_x](
const Coordinates & point) {
149 unsigned int index = 0;
151 const auto mx =
static_cast<unsigned int>(point.x);
152 const auto my =
static_cast<unsigned int>(point.y);
154 if constexpr (!std::is_base_of_v<Node2D, NodeT>) {
155 const auto angle =
static_cast<unsigned int>(point.theta);
156 index = NodeT::getIndex(mx, my, angle, _ctx->motion_table.size_x,
157 _ctx->motion_table.num_angle_quantization);
159 index = NodeT::getIndex(mx, my, size_x);
165 const Coordinates & center_point = node->pose;
166 const float min_x = std::max(0.0f, std::floor(center_point.x - radius));
167 const float min_y = std::max(0.0f, std::floor(center_point.y - radius));
169 std::min(
static_cast<float>(size_x - 1), std::ceil(center_point.x + radius));
171 std::min(
static_cast<float>(size_y - 1), std::ceil(center_point.y + radius));
172 const float radius_sq = radius * radius;
175 for (m.x = min_x; m.x <= max_x; m.x += 1.0f) {
176 for (m.y = min_y; m.y <= max_y; m.y += 1.0f) {
177 const float dx = m.x - center_point.x;
178 const float dy = m.y - center_point.y;
180 if (dx * dx + dy * dy > radius_sq) {
184 NodeT current_node(getIndexFromPoint(m), _ctx);
185 current_node.setPose(m);
187 if (current_node.isNodeValid(traverse_unknown, collision_checker)) {
206 const float & tolerance,
208 const bool & traverse_unknown)
211 if (!_goals_set.empty() || !_goals_coordinate.empty()) {
212 throw std::runtime_error(
213 "Goal set should be cleared before calling "
214 "removeinvalidgoals");
216 for (
unsigned int i = 0; i < _goals_state.size(); i++) {
217 if (_goals_state[i].goal->isNodeValid(traverse_unknown, collision_checker) ||
218 isZoneValid(_goals_state[i].goal, tolerance, collision_checker, traverse_unknown))
220 _goals_state[i].is_valid =
true;
221 _goals_set.insert(_goals_state[i].goal);
222 _goals_coordinate.push_back(_goals_state[i].goal->pose);
224 _goals_state[i].is_valid =
false;
236 return _goals_set.find(node) != _goals_set.end();
263 return _goals_coordinate;
272 _ref_goal_coord = coord;
288 return _ref_goal_coord != coord;
293 GoalStateVector _goals_state;
294 CoordinateVector _goals_coordinate;
296 NodeContext * _ctx =
nullptr;
unsigned int getSizeInCellsX() const
Accessor for the x size of the costmap in cells.
unsigned int getSizeInCellsY() const
Accessor for the y size of the costmap in cells.
Responsible for managing multiple variables storing information on the goal.
GoalManager()
Constructor: Initializes empty goal state. sets and coordinate lists.
void setContext(NodeContext *ctx)
Sets the node context for goal nodes.
~GoalManager()=default
Destructor for the GoalManager.
bool isZoneValid(const NodePtr node, const float &radius, GridCollisionChecker *collision_checker, const bool &traverse_unknown) const
Checks if zone within the radius of a node is feasible. Returns true if there's at least one non-leth...
void removeInvalidGoals(const float &tolerance, GridCollisionChecker *collision_checker, const bool &traverse_unknown)
Filters and marks invalid goals based on collision checking and tolerance thresholds.
NodeSet & getGoalsSet()
Get pointer reference to goals set vector.
bool hasGoalChanged(const Coordinates &coord)
Checks whether the Reference goal coordinate has changed.
void addGoal(NodePtr &goal)
Adds goal to the goal vector.
void prepareGoalsForAnalyticExpansion(NodeVector &coarse_check_goals, NodeVector &fine_check_goals, int coarse_search_resolution)
Populates coarse and fine goal lists for analytic expansion.
GoalStateVector & getGoalsState()
Get pointer reference to goals state.
void setRefGoalCoordinates(const Coordinates &coord)
Set the Reference goal coordinate.
void clear()
Clears all internal goal data, including goals, states, and coordinates.
bool goalsIsEmpty()
Checks if the goals set is empty.
bool isGoal(const NodePtr &node)
Check if a given node is part of the goal set.
CoordinateVector & getGoalsCoordinates()
Get pointer reference to goals coordinates.
A costmap grid collision checker.
Implementation of coordinate2d structure.