Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
node_hybrid.hpp
1 // Copyright (c) 2020, Samsung Research America
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License. Reserved.
14 
15 #ifndef NAV2_SMAC_PLANNER__NODE_HYBRID_HPP_
16 #define NAV2_SMAC_PLANNER__NODE_HYBRID_HPP_
17 
18 #include <math.h>
19 #include <vector>
20 #include <cmath>
21 #include <iostream>
22 #include <functional>
23 #include <queue>
24 #include <memory>
25 #include <utility>
26 #include <limits>
27 
28 #include "ompl/base/StateSpace.h"
29 
30 #include "nav2_smac_planner/constants.hpp"
31 #include "nav2_smac_planner/types.hpp"
32 #include "nav2_smac_planner/collision_checker.hpp"
33 #include "nav2_smac_planner/costmap_downsampler.hpp"
34 #include "nav2_costmap_2d/costmap_2d_ros.hpp"
35 #include "nav2_costmap_2d/inflation_layer.hpp"
36 
37 namespace nav2_smac_planner
38 {
39 
40 typedef std::vector<float> LookupTable;
41 typedef std::pair<double, double> TrigValues;
42 
43 typedef std::pair<float, uint64_t> ObstacleHeuristicElement;
45 {
46  bool operator()(const ObstacleHeuristicElement & a, const ObstacleHeuristicElement & b) const
47  {
48  return a.first > b.first;
49  }
50 };
51 
52 typedef std::vector<ObstacleHeuristicElement> ObstacleHeuristicQueue;
53 
54 // Must forward declare
55 class NodeHybrid;
56 
62 {
67 
75  void initDubin(
76  unsigned int & size_x_in,
77  unsigned int & size_y_in,
78  unsigned int & angle_quantization_in,
79  SearchInfo & search_info);
80 
88  void initReedsShepp(
89  unsigned int & size_x_in,
90  unsigned int & size_y_in,
91  unsigned int & angle_quantization_in,
92  SearchInfo & search_info);
93 
99  MotionPoses getProjections(const NodeHybrid * node);
100 
106  unsigned int getClosestAngularBin(const double & theta);
107 
113  float getAngleFromBin(const unsigned int & bin_idx);
114 
120  double getAngle(const double & theta);
121 
122  MotionModel motion_model = MotionModel::UNKNOWN;
123  MotionPoses projections;
124  unsigned int size_x;
125  unsigned int num_angle_quantization;
126  float num_angle_quantization_float;
127  float min_turning_radius;
128  float bin_size;
129  float change_penalty;
130  float non_straight_penalty;
131  float cost_penalty;
132  float reverse_penalty;
133  float travel_distance_reward;
134  bool downsample_obstacle_heuristic;
135  bool use_quadratic_cost_penalty;
136  ompl::base::StateSpacePtr state_space;
137  std::vector<std::vector<double>> delta_xs;
138  std::vector<std::vector<double>> delta_ys;
139  std::vector<TrigValues> trig_values;
140  std::vector<float> travel_costs;
141 };
142 
148 {
149 public:
150  typedef NodeHybrid * NodePtr;
151  typedef std::unique_ptr<std::vector<NodeHybrid>> Graph;
152  typedef std::vector<NodePtr> NodeVector;
153 
158  struct Coordinates
159  {
164 
171  Coordinates(const float & x_in, const float & y_in, const float & theta_in)
172  : x(x_in), y(y_in), theta(theta_in)
173  {}
174 
175  inline bool operator==(const Coordinates & rhs)
176  {
177  return this->x == rhs.x && this->y == rhs.y && this->theta == rhs.theta;
178  }
179 
180  inline bool operator!=(const Coordinates & rhs)
181  {
182  return !(*this == rhs);
183  }
184 
185  float x, y, theta;
186  };
187 
188  typedef std::vector<Coordinates> CoordinateVector;
189 
194  explicit NodeHybrid(const uint64_t index);
195 
199  ~NodeHybrid();
200 
206  bool operator==(const NodeHybrid & rhs)
207  {
208  return this->_index == rhs._index;
209  }
210 
215  inline void setPose(const Coordinates & pose_in)
216  {
217  pose = pose_in;
218  }
219 
223  void reset();
224 
229  inline float getAccumulatedCost()
230  {
231  return _accumulated_cost;
232  }
233 
238  inline void setAccumulatedCost(const float & cost_in)
239  {
240  _accumulated_cost = cost_in;
241  }
242 
247  inline void setMotionPrimitiveIndex(const unsigned int & idx, const TurnDirection & turn_dir)
248  {
249  _motion_primitive_index = idx;
250  _turn_dir = turn_dir;
251  }
252 
257  inline unsigned int & getMotionPrimitiveIndex()
258  {
259  return _motion_primitive_index;
260  }
261 
266  inline TurnDirection & getTurnDirection()
267  {
268  return _turn_dir;
269  }
270 
275  inline float getCost()
276  {
277  return _cell_cost;
278  }
279 
284  inline bool wasVisited()
285  {
286  return _was_visited;
287  }
288 
292  inline void visited()
293  {
294  _was_visited = true;
295  }
296 
301  inline uint64_t getIndex()
302  {
303  return _index;
304  }
305 
312  bool isNodeValid(
313  const bool & traverse_unknown,
314  GridCollisionChecker * collision_checker);
315 
321  float getTraversalCost(const NodePtr & child);
322 
332  static inline uint64_t getIndex(
333  const unsigned int & x, const unsigned int & y, const unsigned int & angle,
334  const unsigned int & width, const unsigned int & angle_quantization)
335  {
336  return static_cast<uint64_t>(angle) + static_cast<uint64_t>(x) *
337  static_cast<uint64_t>(angle_quantization) +
338  static_cast<uint64_t>(y) * static_cast<uint64_t>(width) *
339  static_cast<uint64_t>(angle_quantization);
340  }
341 
349  static inline uint64_t getIndex(
350  const unsigned int & x, const unsigned int & y, const unsigned int & angle)
351  {
352  return getIndex(
353  x, y, angle, motion_table.size_x,
354  motion_table.num_angle_quantization);
355  }
356 
364  static inline Coordinates getCoords(
365  const uint64_t & index,
366  const unsigned int & width, const unsigned int & angle_quantization)
367  {
368  return Coordinates(
369  (index / angle_quantization) % width, // x
370  index / (angle_quantization * width), // y
371  index % angle_quantization); // theta
372  }
373 
380  static float getHeuristicCost(
381  const Coordinates & node_coords,
382  const Coordinates & goal_coordinates);
383 
392  static void initMotionModel(
393  const MotionModel & motion_model,
394  unsigned int & size_x,
395  unsigned int & size_y,
396  unsigned int & angle_quantization,
397  SearchInfo & search_info);
398 
407  static void precomputeDistanceHeuristic(
408  const float & lookup_table_dim,
409  const MotionModel & motion_model,
410  const unsigned int & dim_3_size,
411  const SearchInfo & search_info);
412 
419  static float getObstacleHeuristic(
420  const Coordinates & node_coords,
421  const Coordinates & goal_coords,
422  const float & cost_penalty);
423 
432  static float getDistanceHeuristic(
433  const Coordinates & node_coords,
434  const Coordinates & goal_coords,
435  const float & obstacle_heuristic);
436 
442  static void resetObstacleHeuristic(
443  std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros,
444  const unsigned int & start_x, const unsigned int & start_y,
445  const unsigned int & goal_x, const unsigned int & goal_y);
446 
454  void getNeighbors(
455  std::function<bool(const uint64_t &,
456  nav2_smac_planner::NodeHybrid * &)> & validity_checker,
457  GridCollisionChecker * collision_checker,
458  const bool & traverse_unknown,
459  NodeVector & neighbors);
460 
466  bool backtracePath(CoordinateVector & path);
467 
472  static void destroyStaticAssets()
473  {
474  costmap_ros.reset();
475  }
476 
477  NodeHybrid * parent;
478  Coordinates pose;
479 
480  // Constants required across all nodes but don't want to allocate more than once
481  static float travel_distance_cost;
482  static HybridMotionTable motion_table;
483  // Wavefront lookup and queue for continuing to expand as needed
484  static LookupTable obstacle_heuristic_lookup_table;
485  static ObstacleHeuristicQueue obstacle_heuristic_queue;
486 
487  static std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros;
488  // Dubin / Reeds-Shepp lookup and size for dereferencing
489  static LookupTable dist_heuristic_lookup_table;
490  static float size_lookup;
491 
492 private:
493  float _cell_cost;
494  float _accumulated_cost;
495  uint64_t _index;
496  bool _was_visited;
497  unsigned int _motion_primitive_index;
498  TurnDirection _turn_dir;
499  bool _is_node_valid{false};
500 };
501 
502 } // namespace nav2_smac_planner
503 
504 #endif // NAV2_SMAC_PLANNER__NODE_HYBRID_HPP_
A costmap grid collision checker.
NodeHybrid implementation for graph, Hybrid-A*.
static void precomputeDistanceHeuristic(const float &lookup_table_dim, const MotionModel &motion_model, const unsigned int &dim_3_size, const SearchInfo &search_info)
Compute the SE2 distance heuristic.
uint64_t getIndex()
Gets cell index.
bool isNodeValid(const bool &traverse_unknown, GridCollisionChecker *collision_checker)
Check if this node is valid.
void setAccumulatedCost(const float &cost_in)
Sets the accumulated cost at this node.
float getTraversalCost(const NodePtr &child)
Get traversal cost of parent node to child node.
void setPose(const Coordinates &pose_in)
setting continuous coordinate search poses (in partial-cells)
~NodeHybrid()
A destructor for nav2_smac_planner::NodeHybrid.
void getNeighbors(std::function< bool(const uint64_t &, nav2_smac_planner::NodeHybrid *&)> &validity_checker, GridCollisionChecker *collision_checker, const bool &traverse_unknown, NodeVector &neighbors)
Retrieve all valid neighbors of a node.
float getCost()
Gets the costmap cost at this node.
static void destroyStaticAssets()
Destroy shared pointer assets at the end of the process that don't require normal destruction handlin...
float getAccumulatedCost()
Gets the accumulated cost at this node.
static void initMotionModel(const MotionModel &motion_model, unsigned int &size_x, unsigned int &size_y, unsigned int &angle_quantization, SearchInfo &search_info)
Initialize motion models.
void reset()
Reset method for new search.
bool operator==(const NodeHybrid &rhs)
operator== for comparisons
static uint64_t getIndex(const unsigned int &x, const unsigned int &y, const unsigned int &angle, const unsigned int &width, const unsigned int &angle_quantization)
Get index at coordinates.
void setMotionPrimitiveIndex(const unsigned int &idx, const TurnDirection &turn_dir)
Sets the motion primitive index used to achieve node in search.
unsigned int & getMotionPrimitiveIndex()
Gets the motion primitive index used to achieve node in search.
NodeHybrid(const uint64_t index)
A constructor for nav2_smac_planner::NodeHybrid.
static Coordinates getCoords(const uint64_t &index, const unsigned int &width, const unsigned int &angle_quantization)
Get coordinates at index.
static float getObstacleHeuristic(const Coordinates &node_coords, const Coordinates &goal_coords, const float &cost_penalty)
Compute the Obstacle heuristic.
static uint64_t getIndex(const unsigned int &x, const unsigned int &y, const unsigned int &angle)
Get index at coordinates.
static float getDistanceHeuristic(const Coordinates &node_coords, const Coordinates &goal_coords, const float &obstacle_heuristic)
Compute the Distance heuristic.
bool wasVisited()
Gets if cell has been visited in search.
static float getHeuristicCost(const Coordinates &node_coords, const Coordinates &goal_coordinates)
Get cost of heuristic of node.
TurnDirection & getTurnDirection()
Gets the motion primitive turning direction used to achieve node in search.
bool backtracePath(CoordinateVector &path)
Set the starting pose for planning, as a node index.
void visited()
Sets if cell has been visited in search.
static void resetObstacleHeuristic(std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap_ros, const unsigned int &start_x, const unsigned int &start_y, const unsigned int &goal_x, const unsigned int &goal_y)
reset the obstacle heuristic state
A table of motion primitives and related functions.
Definition: node_hybrid.hpp:62
void initReedsShepp(unsigned int &size_x_in, unsigned int &size_y_in, unsigned int &angle_quantization_in, SearchInfo &search_info)
Initializing using Reeds-Shepp model.
MotionPoses getProjections(const NodeHybrid *node)
Get projections of motion models.
double getAngle(const double &theta)
Get the angle scaled across bins from a raw orientation.
HybridMotionTable()
A constructor for nav2_smac_planner::HybridMotionTable.
Definition: node_hybrid.hpp:66
float getAngleFromBin(const unsigned int &bin_idx)
Get the raw orientation from an angular bin.
unsigned int getClosestAngularBin(const double &theta)
Get the angular bin to use from a raw orientation.
void initDubin(unsigned int &size_x_in, unsigned int &size_y_in, unsigned int &angle_quantization_in, SearchInfo &search_info)
Initializing using Dubin model.
Definition: node_hybrid.cpp:56
NodeHybrid implementation of coordinate structure.
Coordinates()
A constructor for nav2_smac_planner::NodeHybrid::Coordinates.
Coordinates(const float &x_in, const float &y_in, const float &theta_in)
A constructor for nav2_smac_planner::NodeHybrid::Coordinates.
Search properties and penalties.
Definition: types.hpp:36