15 #include <type_traits>
17 #include "ompl/base/ScopedState.h"
18 #include "ompl/base/spaces/DubinsStateSpace.h"
19 #include "ompl/base/spaces/ReedsSheppStateSpace.h"
20 #include "ompl/base/spaces/SE2StateSpace.h"
21 #include "nav2_smac_planner/distance_heuristic.hpp"
22 #include "nav2_smac_planner/node_hybrid.hpp"
23 #include "nav2_smac_planner/node_lattice.hpp"
25 namespace nav2_smac_planner
29 template<
typename MotionTableT>
31 const float & lookup_table_dim,
32 const MotionModel & motion_model,
33 const unsigned int & dim_3_size,
34 const SearchInfo & search_info,
35 MotionTableT & motion_table)
38 if (motion_model == MotionModel::DUBIN) {
39 motion_table.state_space = std::make_shared<ompl::base::DubinsStateSpace>(
40 search_info.minimum_turning_radius);
41 }
else if (motion_model == MotionModel::REEDS_SHEPP) {
42 motion_table.state_space = std::make_shared<ompl::base::ReedsSheppStateSpace>(
43 search_info.minimum_turning_radius);
45 throw std::runtime_error(
46 "Node attempted to precompute distance heuristics "
47 "with invalid motion model!");
50 ompl::base::ScopedState<> from(motion_table.state_space), to(motion_table.state_space);
54 size_lookup_ = lookup_table_dim;
55 float motion_heuristic = 0.0;
56 unsigned int index = 0;
57 int dim_3_size_int =
static_cast<int>(dim_3_size);
58 float angular_bin_size = 2 * M_PI /
static_cast<float>(dim_3_size);
65 dist_heuristic_lookup_table_.resize(size_lookup_ * ceil(size_lookup_ / 2.0) * dim_3_size_int);
66 for (
float x = ceil(-size_lookup_ / 2.0); x <= floor(size_lookup_ / 2.0); x += 1.0) {
67 for (
float y = 0.0; y <= floor(size_lookup_ / 2.0); y += 1.0) {
68 for (
int heading = 0; heading != dim_3_size_int; heading++) {
71 from[2] = heading * angular_bin_size;
72 motion_heuristic = motion_table.state_space->distance(from(), to());
73 dist_heuristic_lookup_table_[index] = motion_heuristic;
81 template<
typename MotionTableT>
83 const float & lookup_table_dim,
85 const unsigned int & dim_3_size,
86 const SearchInfo & search_info,
87 MotionTableT & motion_table)
89 motion_table.lattice_metadata =
93 if (motion_table.lattice_metadata.motion_model ==
"omni") {
95 motion_table.state_space = std::make_shared<ompl::base::SE2StateSpace>();
96 motion_table.motion_model = MotionModel::OMNI;
97 }
else if (!search_info.allow_reverse_expansion) {
98 motion_table.state_space = std::make_shared<ompl::base::DubinsStateSpace>(
99 search_info.minimum_turning_radius);
100 motion_table.motion_model = MotionModel::DUBIN;
102 motion_table.state_space = std::make_shared<ompl::base::ReedsSheppStateSpace>(
103 search_info.minimum_turning_radius);
104 motion_table.motion_model = MotionModel::REEDS_SHEPP;
107 ompl::base::ScopedState<> from(motion_table.state_space), to(motion_table.state_space);
111 size_lookup_ = lookup_table_dim;
112 float motion_heuristic = 0.0;
113 unsigned int index = 0;
114 int dim_3_size_int =
static_cast<int>(dim_3_size);
121 dist_heuristic_lookup_table_.resize(size_lookup_ * ceil(size_lookup_ / 2.0) * dim_3_size_int);
122 for (
float x = ceil(-size_lookup_ / 2.0); x <= floor(size_lookup_ / 2.0); x += 1.0) {
123 for (
float y = 0.0; y <= floor(size_lookup_ / 2.0); y += 1.0) {
124 for (
int heading = 0; heading != dim_3_size_int; heading++) {
127 from[2] = motion_table.getAngleFromBin(heading);
128 motion_heuristic = motion_table.state_space->distance(from(), to());
129 dist_heuristic_lookup_table_[index] = motion_heuristic;
136 template<
typename NodeT>
137 template<
typename MotionTableT>
141 const float & obstacle_heuristic,
142 MotionTableT & motion_table)
151 const TrigValues & trig_vals = motion_table.trig_values[goal_coords.theta];
152 const float cos_th = trig_vals.first;
153 const float sin_th = -trig_vals.second;
154 const float dx = node_coords.x - goal_coords.x;
155 const float dy = node_coords.y - goal_coords.y;
157 double dtheta_bin = node_coords.theta - goal_coords.theta;
158 if (dtheta_bin < 0) {
159 dtheta_bin += motion_table.num_angle_quantization;
161 if (dtheta_bin > motion_table.num_angle_quantization) {
162 dtheta_bin -= motion_table.num_angle_quantization;
166 round(dx * cos_th - dy * sin_th),
167 round(dx * sin_th + dy * cos_th),
173 float motion_heuristic = 0.0;
174 const int floored_size = floor(size_lookup_ / 2.0);
175 const int ceiling_size = ceil(size_lookup_ / 2.0);
176 const float mirrored_relative_y = abs(node_coords_relative.y);
177 if (abs(node_coords_relative.x) < floored_size && mirrored_relative_y < floored_size) {
180 if (node_coords_relative.y < 0.0) {
181 theta_pos = motion_table.num_angle_quantization - node_coords_relative.theta;
183 theta_pos = node_coords_relative.theta;
185 const int x_pos = node_coords_relative.x + floored_size;
186 const int y_pos =
static_cast<int>(mirrored_relative_y);
188 x_pos * ceiling_size * motion_table.num_angle_quantization +
189 y_pos * motion_table.num_angle_quantization +
191 motion_heuristic = dist_heuristic_lookup_table_[index];
192 }
else if (obstacle_heuristic <= 0.0) {
193 ompl::base::ScopedState<> from(motion_table.state_space), to(motion_table.state_space);
194 to[0] = goal_coords.x;
195 to[1] = goal_coords.y;
196 from[0] = node_coords.x;
197 from[1] = node_coords.y;
198 if constexpr (std::is_base_of_v<NodeHybrid, NodeT>) {
199 to[2] = goal_coords.theta * motion_table.num_angle_quantization;
200 from[2] = node_coords.theta * motion_table.num_angle_quantization;
202 to[2] = motion_table.getAngleFromBin(goal_coords.theta);
203 from[2] = motion_table.getAngleFromBin(node_coords.theta);
205 motion_heuristic = motion_table.state_space->distance(from(), to());
208 return motion_heuristic;
213 const float &,
const MotionModel &,
const unsigned int &,
const SearchInfo &,
216 const float &,
const MotionModel &,
const unsigned int &,
const SearchInfo &,
Distance Heuristic implementation for graph, Hybrid-A*.
void precomputeDistanceHeuristic(const float &lookup_table_dim, const MotionModel &motion_model, const unsigned int &dim_3_size, const SearchInfo &search_info, MotionTableT &motion_table)
Compute the SE2 distance heuristic.
float getDistanceHeuristic(const Coordinates &node_coords, const Coordinates &goal_coords, const float &obstacle_heuristic, MotionTableT &motion_table)
Compute the Distance heuristic.
Implementation of coordinate2d structure.
A table of motion primitives and related functions.
A table of motion primitives and related functions.
static LatticeMetadata getLatticeMetadata(const std::string &lattice_filepath)
Get file metadata needed.
Search properties and penalties.