49 : costmap_(NULL), planner_(), initialized_(false), allow_unknown_(true) {}
89 ROS_WARN(
"This planner has already been initialized, you can't call it twice, doing nothing");
102 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
107 geometry_msgs::Point p;
110 p.y = world_point.y - tolerance;
112 while(p.y <= world_point.y + tolerance){
113 p.x = world_point.x - tolerance;
114 while(p.x <= world_point.x + tolerance){
129 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
137 unsigned int index = my *
planner_->nx + mx;
143 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
166 return planner_->calcNavFnDijkstra();
171 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
180 makePlan(req.start, req.goal, resp.plan.poses);
194 const geometry_msgs::PoseStamped&
goal, std::vector<geometry_msgs::PoseStamped>& plan){
199 const geometry_msgs::PoseStamped&
goal,
double tolerance, std::vector<geometry_msgs::PoseStamped>& plan){
200 boost::mutex::scoped_lock lock(
mutex_);
202 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
213 ROS_ERROR(
"The goal pose passed to this planner must be in the %s frame. It is instead in the %s frame.",
219 ROS_ERROR(
"The start pose passed to this planner must be in the %s frame. It is instead in the %s frame.",
224 double wx = start.pose.position.x;
225 double wy = start.pose.position.y;
229 ROS_WARN(
"The robot's start position is off the global costmap. Planning will always fail, are you sure the robot has been properly localized?");
244 wx = goal.pose.position.x;
245 wy = goal.pose.position.y;
248 if(tolerance <= 0.0){
249 ROS_WARN_THROTTLE(1.0,
"The goal sent to the navfn planner is off the global costmap. Planning will always fail to this goal.");
267 geometry_msgs::PoseStamped p, best_pose;
270 bool found_legal =
false;
271 double best_sdist = DBL_MAX;
273 p.pose.position.y = goal.pose.position.y - tolerance;
275 while(p.pose.position.y <= goal.pose.position.y + tolerance){
276 p.pose.position.x = goal.pose.position.x - tolerance;
277 while(p.pose.position.x <= goal.pose.position.x + tolerance){
280 if(potential <
POT_HIGH && sdist < best_sdist){
285 p.pose.position.x += resolution;
287 p.pose.position.y += resolution;
294 geometry_msgs::PoseStamped goal_copy = best_pose;
296 plan.push_back(goal_copy);
299 ROS_ERROR(
"Failed to get a plan from potential when a legal potential was found. This shouldn't happen.");
306 sensor_msgs::PointCloud2 cloud;
313 "y", 1, sensor_msgs::PointField::FLOAT32,
314 "z", 1, sensor_msgs::PointField::FLOAT32,
315 "pot", 1, sensor_msgs::PointField::FLOAT32);
340 return !plan.empty();
343 void NavfnROS::publishPlan(
const std::vector<geometry_msgs::PoseStamped>& path,
double r,
double g,
double b,
double a){
345 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
350 nav_msgs::Path gui_path;
351 gui_path.poses.resize(path.size());
358 gui_path.header.frame_id = path[0].header.frame_id;
359 gui_path.header.stamp = path[0].header.stamp;
363 for(
unsigned int i=0; i < path.size(); i++){
364 gui_path.poses[i] = path[i];
372 ROS_ERROR(
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
381 ROS_ERROR(
"The goal pose passed to this planner must be in the %s frame. It is instead in the %s frame.",
386 double wx = goal.pose.position.x;
387 double wy = goal.pose.position.y;
392 ROS_WARN_THROTTLE(1.0,
"The goal sent to the navfn planner is off the global costmap. Planning will always fail to this goal.");
410 for(
int i = len - 1; i >= 0; --i){
412 double world_x, world_y;
415 geometry_msgs::PoseStamped pose;
416 pose.header.stamp = plan_time;
418 pose.pose.position.x = world_x;
419 pose.pose.position.y = world_y;
420 pose.pose.position.z = 0.0;
421 pose.pose.orientation.x = 0.0;
422 pose.pose.orientation.y = 0.0;
423 pose.pose.orientation.z = 0.0;
424 pose.pose.orientation.w = 1.0;
425 plan.push_back(pose);
430 return !plan.empty();
void setCost(unsigned int mx, unsigned int my, unsigned char cost)
unsigned int getSizeInCellsX() const
void clearRobotCell(const geometry_msgs::PoseStamped &global_pose, unsigned int mx, unsigned int my)
bool visualize_potential_
void publishPlan(const std::vector< geometry_msgs::PoseStamped > &path, double r, double g, double b, double a)
Publish a path for visualization purposes.
boost::shared_ptr< NavFn > planner_
unsigned int getSizeInCellsY() const
bool computePotential(const geometry_msgs::Point &world_point)
Computes the full navigation function for the map given a point in the world to start from...
std::string getGlobalFrameID()
costmap_2d::Costmap2D * costmap_
Store a copy of the current costmap in costmap. Called by makePlan.
Provides a ROS wrapper for the navfn planner which runs a fast, interpolated navigation function on a...
void setPointCloud2Fields(int n_fields,...)
bool validPointPotential(const geometry_msgs::Point &world_point)
Check for a valid potential value at a given point in the world (Note: You should call computePotenti...
double getOriginY() const
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool makePlan(const geometry_msgs::PoseStamped &start, const geometry_msgs::PoseStamped &goal, std::vector< geometry_msgs::PoseStamped > &plan)
Given a goal pose in the world, compute a plan.
static const unsigned char FREE_SPACE
ros::Publisher potarr_pub_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
ros::ServiceServer make_plan_srv_
unsigned char * getCharMap() const
#define ROS_WARN_THROTTLE(period,...)
double sq_distance(const geometry_msgs::PoseStamped &p1, const geometry_msgs::PoseStamped &p2)
Navigation function class. Holds buffers for costmap, navfn map. Maps are pixel-based. Origin is upper left, x is right, y is down.
double getPointPotential(const geometry_msgs::Point &world_point)
Get the potential, or naviagation cost, at a given point in the world (Note: You should call computeP...
bool getPlanFromPotential(const geometry_msgs::PoseStamped &goal, std::vector< geometry_msgs::PoseStamped > &plan)
Compute a plan to a goal after the potential for a start point has already been computed (Note: You s...
bool makePlanService(nav_msgs::GetPlan::Request &req, nav_msgs::GetPlan::Response &resp)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double default_tolerance_
NavfnROS()
Default constructor for the NavFnROS object.
double getOriginX() const
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
void mapToWorld(double mx, double my, double &wx, double &wy)
double getResolution() const
std::string global_frame_
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void initialize(std::string name, costmap_2d::Costmap2DROS *costmap_ros)
Initialization function for the NavFnROS object.