64 const geometry_msgs::Pose2D& start,
const geometry_msgs::Pose2D& goal,
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);
106 if (index == finish_index || (fabs(current.x - finish_x) <=
step_size_ && fabs(current.y - finish_y) <=
step_size_))
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);
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",
190 if (x == 0.0 && y == 0.0)
194 index =
gridStep(potential_grid, index);
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;
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)
368 float cv = potential_grid(index);
372 float south_p = index.
y > 0 ? 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;
406 float norm =
hypot(dx, dy);
unsigned int size() const
NavGridInfo getInfo() const
nav_grid::Index gridStep(const dlux_global_planner::PotentialGrid &potential_grid, const nav_grid::Index &index)
nav_2d_msgs::Path2D mapPathToWorldPath(const nav_2d_msgs::Path2D &original, const nav_grid::NavGridInfo &info)
nav_grid::VectorNavGrid< double > grady_
INLINE Rall1d< T, V, S > hypot(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void calculateGradient(const dlux_global_planner::PotentialGrid &potential_grid, const nav_grid::Index &index)
#define ROS_DEBUG_NAMED(name,...)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
unsigned int getWidth() const
bool grid_step_near_high_
nav_2d_msgs::Path2D getPath(const dlux_global_planner::PotentialGrid &potential_grid, const geometry_msgs::Pose2D &start, const geometry_msgs::Pose2D &goal, double &path_cost) override
unsigned int getHeight() const
const float HIGH_POTENTIAL
CostInterpreter::Ptr cost_interpreter_
void setInfo(const NavGridInfo &new_info) override
void setValue(const unsigned int x, const unsigned int y, const T &value) override
std::shared_ptr< CostInterpreter > Ptr
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.
bool shouldGridStep(const dlux_global_planner::PotentialGrid &potential_grid, const nav_grid::Index &index)
nav_grid::VectorNavGrid< double > gradx_
void initialize(ros::NodeHandle &private_nh, dlux_global_planner::CostInterpreter::Ptr cost_interpreter) override