15 #include "nav2_smac_planner/obstacle_heuristic.hpp"
17 namespace nav2_smac_planner
21 std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros_i,
22 const unsigned int & start_x,
const unsigned int & start_y,
23 const unsigned int & goal_x,
const unsigned int & goal_y,
24 const bool downsample_obstacle_heuristic)
30 costmap_ros = costmap_ros_i;
31 auto costmap = costmap_ros->getCostmap();
34 unsigned int size = 0u;
35 unsigned int size_x = 0u;
36 if (downsample_obstacle_heuristic) {
37 size_x = ceil(
static_cast<float>(costmap->getSizeInCellsX()) / 2.0f);
39 ceil(
static_cast<float>(costmap->getSizeInCellsY()) / 2.0f);
41 size_x = costmap->getSizeInCellsX();
42 size = size_x * costmap->getSizeInCellsY();
45 if (obstacle_heuristic_lookup_table_.size() == size) {
48 obstacle_heuristic_lookup_table_.begin(),
49 obstacle_heuristic_lookup_table_.end(), 0.0f);
51 unsigned int obstacle_size = obstacle_heuristic_lookup_table_.size();
52 obstacle_heuristic_lookup_table_.resize(size, 0.0f);
55 obstacle_heuristic_lookup_table_.begin(), obstacle_size, 0.0f);
58 obstacle_heuristic_queue_.clear();
59 obstacle_heuristic_queue_.reserve(size);
62 unsigned int goal_index;
63 if (downsample_obstacle_heuristic) {
64 goal_index = floor(goal_y / 2.0f) * size_x + floor(goal_x / 2.0f);
66 goal_index = floor(goal_y) * size_x + floor(goal_x);
69 obstacle_heuristic_queue_.emplace_back(
70 distanceHeuristic2D(goal_index, size_x, start_x, start_y), goal_index);
74 obstacle_heuristic_lookup_table_[goal_index] = -0.00001f;
79 const float & cost_penalty,
80 const bool use_quadratic_cost_penalty,
81 const bool downsample_obstacle_heuristic)
84 auto costmap = costmap_ros->getCostmap();
85 unsigned int size_x = 0u;
86 unsigned int size_y = 0u;
87 if (downsample_obstacle_heuristic) {
88 size_x = ceil(
static_cast<float>(costmap->getSizeInCellsX()) / 2.0f);
89 size_y = ceil(
static_cast<float>(costmap->getSizeInCellsY()) / 2.0f);
91 size_x = costmap->getSizeInCellsX();
92 size_y = costmap->getSizeInCellsY();
96 unsigned int start_y, start_x;
97 if (downsample_obstacle_heuristic) {
98 start_y = floor(node_coords.y / 2.0f);
99 start_x = floor(node_coords.x / 2.0f);
101 start_y = floor(node_coords.y);
102 start_x = floor(node_coords.x);
105 const unsigned int start_index = start_y * size_x + start_x;
106 const float & requested_node_cost = obstacle_heuristic_lookup_table_[start_index];
107 if (requested_node_cost > 0.0f) {
109 return downsample_obstacle_heuristic ? 2.0f * requested_node_cost : requested_node_cost;
120 for (
auto & n : obstacle_heuristic_queue_) {
121 n.first = -obstacle_heuristic_lookup_table_[n.second] +
122 distanceHeuristic2D(n.second, size_x, start_x, start_y);
125 obstacle_heuristic_queue_.begin(), obstacle_heuristic_queue_.end(),
128 const int size_x_int =
static_cast<int>(size_x);
129 const float sqrt2 = sqrtf(2.0f);
130 float c_cost, cost, travel_cost, new_cost, existing_cost;
132 unsigned int idx, new_idx = 0;
134 const std::vector<int> neighborhood = {1, -1,
135 size_x_int, -size_x_int,
136 size_x_int + 1, size_x_int - 1,
137 -size_x_int + 1, -size_x_int - 1};
139 while (!obstacle_heuristic_queue_.empty()) {
140 idx = obstacle_heuristic_queue_.front().second;
142 obstacle_heuristic_queue_.begin(), obstacle_heuristic_queue_.end(),
144 obstacle_heuristic_queue_.pop_back();
145 c_cost = obstacle_heuristic_lookup_table_[idx];
152 obstacle_heuristic_lookup_table_[idx] = c_cost;
155 for (
unsigned int i = 0; i != neighborhood.size(); i++) {
156 new_idx =
static_cast<unsigned int>(
static_cast<int>(idx) + neighborhood[i]);
159 if (new_idx < size_x * size_y) {
160 if (downsample_obstacle_heuristic) {
162 unsigned int y_offset = (new_idx / size_x) * 2;
163 unsigned int x_offset = (new_idx - ((new_idx / size_x) * size_x)) * 2;
164 cost = costmap->getCost(x_offset, y_offset);
165 for (
unsigned int k = 0; k < 2u; ++k) {
166 unsigned int mxd = x_offset + k;
167 if (mxd >= costmap->getSizeInCellsX()) {
170 for (
unsigned int j = 0; j < 2u; ++j) {
171 unsigned int myd = y_offset + j;
172 if (myd >= costmap->getSizeInCellsY()) {
175 if (k == 0 && j == 0) {
178 cost = std::min(cost,
static_cast<float>(costmap->getCost(mxd, myd)));
182 cost =
static_cast<float>(costmap->getCost(new_idx));
185 if (cost >= INSCRIBED_COST) {
189 my = new_idx / size_x;
190 mx = new_idx - (my * size_x);
192 if (mx >= size_x - 3 || mx <= 3) {
195 if (my >= size_y - 3 || my <= 3) {
199 existing_cost = obstacle_heuristic_lookup_table_[new_idx];
200 if (existing_cost <= 0.0f) {
201 if (use_quadratic_cost_penalty) {
203 (i <= 3 ? 1.0f : sqrt2) * (1.0f + (cost_penalty * cost * cost / 63504.0f));
206 ((i <= 3) ? 1.0f : sqrt2) * (1.0f + (cost_penalty * cost / 252.0f));
209 new_cost = c_cost + travel_cost;
210 if (existing_cost == 0.0f || -existing_cost > new_cost) {
212 obstacle_heuristic_lookup_table_[new_idx] = -new_cost;
213 obstacle_heuristic_queue_.emplace_back(
214 new_cost + distanceHeuristic2D(new_idx, size_x, start_x, start_y), new_idx);
216 obstacle_heuristic_queue_.begin(), obstacle_heuristic_queue_.end(),
223 if (idx == start_index) {
227 return downsample_obstacle_heuristic ? 2.0f * requested_node_cost : requested_node_cost;
float getObstacleHeuristic(const Coordinates &node_coords, const float &cost_penalty, const bool use_quadratic_cost_penalty, const bool downsample_obstacle_heuristic)
Compute the Obstacle heuristic.
void resetObstacleHeuristic(std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap_ros_i, const unsigned int &start_x, const unsigned int &start_y, const unsigned int &goal_x, const unsigned int &goal_y, const bool downsample_obstacle_heuristic)
Compute the wavefront heuristic.
Implementation of coordinate2d structure.