50 cost_interpreter_ = cost_interpreter;
51 private_nh.
param(
"step_size", step_size_, 0.5);
52 private_nh.
param(
"lethal_cost", lethal_cost_, 250.0);
56 private_nh.
param(
"iteration_factor", iteration_factor_, 4.0);
60 private_nh.
param(
"grid_step_near_high", grid_step_near_high_,
false);
64 const geometry_msgs::Pose2D& start,
const geometry_msgs::Pose2D& goal,
68 if (gradx_.getInfo() != info)
76 nav_2d_msgs::Path2D path;
84 double x_int_part, y_int_part;
85 float dx = modf(map_x, &x_int_part),
86 dy = modf(map_y, &y_int_part);
87 nav_grid::Index index(static_cast<unsigned int>(x_int_part), static_cast<unsigned int>(y_int_part));
91 double finish_x = floor(map_x),
92 finish_y = floor(map_y);
93 nav_grid::Index finish_index(static_cast<unsigned int>(finish_x), static_cast<unsigned int>(finish_y));
95 unsigned int c = 0, max_iterations =
static_cast<unsigned int>(potential_grid.
size() * iteration_factor_);
96 geometry_msgs::Pose2D current;
98 while (c++ < max_iterations)
100 current.x = index.
x + dx;
101 current.y = index.
y + dy;
102 path.poses.push_back(current);
103 path_cost += step_size_ * cost_interpreter_->getCost(index.
x, index.
y);
106 if (index == finish_index || (fabs(current.x - finish_x) <= step_size_ && fabs(current.y - finish_y) <= step_size_))
108 nav_2d_msgs::Path2D world_path = mapPathToWorldPath(path, potential_grid.
getInfo());
109 world_path.poses.push_back(goal);
113 ROS_DEBUG_NAMED(
"GradientPath",
"xy: %.2f %.2f (%d %.2f, %d %.2f)", current.x, current.y,
114 index.
x, dx, index.
y, dy);
117 bool oscillation_detected =
false;
118 int npath = path.poses.size();
119 if (npath > 2 && path.poses[npath - 1].x == path.poses[npath - 3].x
120 && path.poses[npath - 1].y == path.poses[npath - 3].y)
122 oscillation_detected =
true;
137 if (shouldGridStep(potential_grid, index) || oscillation_detected)
140 if (oscillation_detected)
141 error =
"Oscillation detected.";
143 error =
"High Potential Nearby.";
145 index = gridStep(potential_grid, index);
149 ROS_DEBUG_NAMED(
"GradientPath",
"Potential: %0.1f position: %0.1f,%0.1f",
150 potential_grid(index), path.poses[npath - 1].x, path.poses[npath - 1].y);
169 index_n(index.
x, index.
y + 1),
170 index_ne(index.
x + 1, index.
y + 1);
171 calculateGradient(potential_grid, index);
172 calculateGradient(potential_grid, index_e);
173 calculateGradient(potential_grid, index_n);
174 calculateGradient(potential_grid, index_ne);
177 float x1 = (1.0 - dx) * gradx_(index) + dx * gradx_(index_e);
178 float x2 = (1.0 - dx) * gradx_(index_n) + dx * gradx_(index_ne);
179 float x = (1.0 - dy) * x1 + dy * x2;
180 float y1 = (1.0 - dx) * grady_(index) + dx * grady_(index_e);
181 float y2 = (1.0 - dx) * grady_(index_n) + dx * grady_(index_ne);
182 float y = (1.0 - dy) * y1 + dy * y2;
185 ROS_DEBUG_NAMED(
"GradientPath",
"%0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f %0.2f,%0.2f; final x=%.3f, y=%.3f",
186 gradx_(index), grady_(index), gradx_(index_e), grady_(index_e),
187 gradx_(index_n), grady_(index_n), gradx_(index_ne), grady_(index_ne), x, y);
190 if (x == 0.0 && y == 0.0)
194 index = gridStep(potential_grid, index);
201 float ss = step_size_ / hypot(x, y);
228 ROS_DEBUG_NAMED(
"GradientPath",
"Potential: %0.1f gradient: %0.1f,%0.1f position: %0.1f,%0.1f\n",
229 potential_grid(index), dx, dy, path.poses[npath - 1].x, path.poses[npath - 1].y);
238 bool near_edge = index.
x == 0 || index.
x >= potential_grid.
getWidth() - 1 ||
239 index.
y == 0 || index.
y >= potential_grid.
getHeight() - 1;
240 if (near_edge || !grid_step_near_high_)
244 return potential_grid(index) >= HIGH_POTENTIAL ||
245 potential_grid(index.
x + 1, index.
y) >= HIGH_POTENTIAL ||
246 potential_grid(index.
x - 1, index.
y) >= HIGH_POTENTIAL ||
247 potential_grid(index.
x, index.
y + 1) >= HIGH_POTENTIAL ||
248 potential_grid(index.
x, index.
y - 1) >= HIGH_POTENTIAL ||
249 potential_grid(index.
x + 1, index.
y + 1) >= HIGH_POTENTIAL ||
250 potential_grid(index.
x + 1, index.
y - 1) >= HIGH_POTENTIAL ||
251 potential_grid(index.
x - 1, index.
y + 1) >= HIGH_POTENTIAL ||
252 potential_grid(index.
x - 1, index.
y - 1) >= HIGH_POTENTIAL;
260 float min_potential = potential_grid(index);
268 if (potential_grid(index_s) < min_potential)
270 min_potential = potential_grid(index_s);
278 if (potential_grid(index_sw) < min_potential)
280 min_potential = potential_grid(index_sw);
281 min_index = index_sw;
286 if (index.
x < potential_grid.
getWidth() - 1)
289 if (potential_grid(index_se) < min_potential)
291 min_potential = potential_grid(index_se);
292 min_index = index_se;
301 if (potential_grid(index_w) < min_potential)
303 min_potential = potential_grid(index_w);
308 if (index.
x < potential_grid.
getWidth() - 1)
311 if (potential_grid(index_e) < min_potential)
313 min_potential = potential_grid(index_e);
322 if (potential_grid(index_n) < min_potential)
324 min_potential = potential_grid(index_n);
332 if (potential_grid(index_nw) < min_potential)
334 min_potential = potential_grid(index_nw);
335 min_index = index_nw;
340 if (index.
x < potential_grid.
getWidth() - 1)
343 if (potential_grid(index_ne) < min_potential)
345 min_potential = potential_grid(index_ne);
346 min_index = index_ne;
350 if (min_index == index)
354 else if (potential_grid(min_index) >= HIGH_POTENTIAL)
365 if (gradx_(index) + grady_(index) > 0.0)
368 float cv = potential_grid(index);
372 float south_p = index.
y > 0 ? potential_grid(index.
x, index.
y - 1) : HIGH_POTENTIAL;
373 float north_p = index.
y < potential_grid.
getHeight() - 1 ? potential_grid(index.
x, index.
y + 1) : HIGH_POTENTIAL;
374 float west_p = index.
x > 0 ? potential_grid(index.
x - 1, index.
y) : HIGH_POTENTIAL;
375 float east_p = index.
x < potential_grid.
getWidth() - 1 ? potential_grid(index.
x + 1, index.
y) : HIGH_POTENTIAL;
378 if (cv >= HIGH_POTENTIAL)
380 if (west_p < HIGH_POTENTIAL)
382 else if (east_p < HIGH_POTENTIAL)
385 if (south_p < HIGH_POTENTIAL)
387 else if (north_p < HIGH_POTENTIAL)
393 if (west_p < HIGH_POTENTIAL)
395 if (east_p < HIGH_POTENTIAL)
399 if (south_p < HIGH_POTENTIAL)
401 if (north_p < HIGH_POTENTIAL)
406 float norm = hypot(dx, dy);
410 gradx_.setValue(index, norm * dx);
411 grady_.setValue(index, norm * dy);
TFSIMD_FORCE_INLINE const tfScalar & y() const
#define ROS_DEBUG_NAMED(name,...)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
unsigned int getHeight() const
TFSIMD_FORCE_INLINE const tfScalar & x() const
std::shared_ptr< CostInterpreter > Ptr
unsigned int size() const
unsigned int getWidth() const
NavGridInfo getInfo() const
void worldToGrid(const NavGridInfo &info, double wx, double wy, double &mx, double &my)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
Traceback function that creates a smooth gradient from the start to the goal.