SBPLPlanner2D.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2013 Armin Hornung, University of Freiburg
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *
00007  *     * Redistributions of source code must retain the above copyright
00008  *       notice, this list of conditions and the following disclaimer.
00009  *     * Redistributions in binary form must reproduce the above copyright
00010  *       notice, this list of conditions and the following disclaimer in the
00011  *       documentation and/or other materials provided with the distribution.
00012  *     * Neither the name of the University of Freiburg nor the names of its
00013  *       contributors may be used to endorse or promote products derived from
00014  *       this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #include "humanoid_planner_2d/SBPLPlanner2D.h"
00030 
00031 SBPLPlanner2D::SBPLPlanner2D()
00032   : nh_(),
00033   robot_radius_(0.25),
00034   start_received_(false), goal_received_(false),
00035   path_costs_(0.0)
00036 {
00037   
00038   // private NodeHandle for parameters:
00039   ros::NodeHandle nh_private("~");
00040   nh_private.param("planner_type", planner_type_, std::string("ARAPlanner"));
00041   nh_private.param("search_until_first_solution", search_until_first_solution_, false);
00042   nh_private.param("allocated_time", allocated_time_, 7.0);
00043   nh_private.param("forward_search", forward_search_, false);
00044   nh_private.param("initial_epsilon", initial_epsilon_, 3.0);
00045   nh_private.param("robot_radius", robot_radius_, robot_radius_);
00046 
00047   path_pub_ = nh_.advertise<nav_msgs::Path>("path", 0);
00048 
00049   // subscriptions in SBPLPlanner2DNode
00050 }
00051 
00052 SBPLPlanner2D::~SBPLPlanner2D() {
00053 
00054 }
00055 
00056 void SBPLPlanner2D::goalCallback(const geometry_msgs::PoseStampedConstPtr& goal_pose){
00057   // set goal:
00058   goal_pose_ = goal_pose->pose;
00059   goal_received_ = true;
00060   ROS_DEBUG("Received goal: %f %f", goal_pose_.position.x, goal_pose_.position.y);
00061 
00062   if (goal_pose->header.frame_id != map_->getFrameID()){
00063     ROS_WARN("Goal pose frame id \"%s\" different from map frame id \"%s\"", goal_pose->header.frame_id.c_str(), map_->getFrameID().c_str());
00064   }
00065   
00066   // planning?
00067   if (start_received_)
00068     plan();
00069 }
00070 
00071 void SBPLPlanner2D::startCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr& start_pose){
00072   // set start:
00073   start_pose_ = start_pose->pose.pose;
00074   start_received_ = true;
00075   ROS_DEBUG("Received start: %f %f", start_pose_.position.x, start_pose_.position.y);
00076 
00077   if (start_pose->header.frame_id != map_->getFrameID()){
00078     ROS_WARN("Start pose frame id \"%s\" different from map frame id \"%s\"", start_pose->header.frame_id.c_str(), map_->getFrameID().c_str());
00079   }
00080   
00081   // planning?
00082   if (goal_received_)
00083     plan();
00084 }
00085 
00086 bool SBPLPlanner2D::plan(const geometry_msgs::Pose& start, const geometry_msgs::Pose& goal){
00087   start_pose_ = start;
00088   goal_pose_ = goal;
00089 
00090   start_received_ = true;
00091   goal_received_ = true;
00092 
00093   return plan();
00094 }
00095 
00096 bool SBPLPlanner2D::plan(double startX, double startY, double goalX, double goalY){
00097   start_pose_.position.x = startX;
00098   start_pose_.position.y = startY;
00099 
00100   goal_pose_.position.x = goalX;
00101   goal_pose_.position.y = goalY;
00102 
00103   start_received_ = true;
00104   goal_received_ = true;
00105 
00106   return plan();
00107 }
00108 
00109 bool SBPLPlanner2D::plan(){
00110   path_.poses.clear();
00111 
00112   if (!map_){
00113     ROS_ERROR("Map not set");
00114     return false;
00115   }
00116 
00117   unsigned start_x, start_y, goal_x, goal_y;
00118   if (!map_->worldToMap(start_pose_.position.x, start_pose_.position.y, start_x, start_y)){
00119     ROS_ERROR("Start coordinates out of map bounds");
00120     return false;
00121   }
00122   if (!map_->worldToMap(goal_pose_.position.x, goal_pose_.position.y, goal_x, goal_y)){
00123     ROS_ERROR("Goal coordinates out of map bounds");
00124     return false;
00125   }
00126 
00127   if (map_->isOccupiedAtCell(start_x, start_y)){
00128     ROS_ERROR("Start coordinate (%f %f) is occupied in map", start_pose_.position.x, start_pose_.position.y);
00129     return false;
00130   }
00131   if (map_->isOccupiedAtCell(goal_x, goal_y)){
00132     ROS_ERROR("Goal coordinate (%f %f) is occupied in map", goal_pose_.position.x, goal_pose_.position.y);
00133     return false;
00134   }
00135 
00136   int start_id = planner_environment_->SetStart(start_x, start_y);
00137   int goal_id = planner_environment_->SetGoal(goal_x, goal_y);
00138 
00139   if (start_id < 0 || planner_->set_start(start_id) == 0){
00140     ROS_ERROR("Failed to set start state");
00141     return false;
00142   }
00143 
00144   if (goal_id < 0 || planner_->set_goal(goal_id) == 0){
00145     ROS_ERROR("Failed to set goal state");
00146     return false;
00147   }
00148 
00149   // set planner params:
00150   planner_->set_initialsolution_eps(initial_epsilon_);
00151   planner_->set_search_mode(search_until_first_solution_);
00152   std::vector<int> solution_stateIDs;
00153   int solution_cost;
00154 
00155 
00156   if(planner_->replan(allocated_time_, &solution_stateIDs, &solution_cost))
00157     ROS_DEBUG("Solution found. Costs: %d;  final eps: %f", solution_cost, planner_->get_final_epsilon());
00158   else{
00159     ROS_INFO("Solution not found");
00160     return false;
00161   }
00162 
00163   // scale costs (SBPL uses mm and does not know map res)
00164   path_costs_ = double(solution_cost) / ENVNAV2D_COSTMULT * map_->getResolution();
00165 
00166   // extract / publish path:
00167   path_.poses.reserve(solution_stateIDs.size());
00168   path_.header.frame_id = map_->getFrameID();
00169   path_.header.stamp = ros::Time::now();
00170 
00171   geometry_msgs::PoseStamped pose;
00172   pose.header = path_.header;
00173   for (size_t i = 0; i < solution_stateIDs.size(); i++) {
00174     int mx, my;
00175     planner_environment_->GetCoordFromState(solution_stateIDs[i], mx, my);
00176     //ROS_INFO("p: %d - [%d %d]", solution_stateIDs[i], mx, my);
00177     double wx,wy;
00178     map_->mapToWorld(mx,my,wx,wy);
00179 
00180 
00181     pose.pose.position.x = wx;
00182     pose.pose.position.y = wy;
00183     pose.pose.position.z = 0.0;
00184     path_.poses.push_back(pose);
00185   }
00186 
00187   path_pub_.publish(path_);
00188 
00189   return true;
00190 }
00191 
00192 void SBPLPlanner2D::mapCallback(const nav_msgs::OccupancyGridConstPtr& occupancy_map){
00193   gridmap_2d::GridMap2DPtr map(new gridmap_2d::GridMap2D(occupancy_map));
00194   updateMap(map);
00195 }
00196 
00197 bool SBPLPlanner2D::updateMap(gridmap_2d::GridMap2DPtr map){
00198   planner_environment_.reset(new EnvironmentNAV2D());
00199   planner_environment_->InitializeEnv(int(map->getInfo().width), int(map->getInfo().height), 0, OBSTACLE_COST);
00200   // environment is set up, reset planner:
00201   setPlanner();
00202 
00203   // store local copy:
00204   map_.reset(new gridmap_2d::GridMap2D(*map));
00205   map_->inflateMap(robot_radius_);
00206 
00207 
00208   for(unsigned int j = 0; j < map_->getInfo().height; ++j){
00209     for(unsigned int i = 0; i < map_->getInfo().width; ++i){
00210       if (map_->isOccupiedAtCell(i,j))
00211         planner_environment_->UpdateCost(i, j, OBSTACLE_COST);
00212       else
00213         planner_environment_->UpdateCost(i,j,0);
00214 
00215     }
00216   }
00217 
00218   ROS_DEBUG("Map set");
00219 
00220   return true;
00221 }
00222 
00223 void SBPLPlanner2D::setPlanner(){
00224   if (planner_type_ == "ARAPlanner"){
00225     planner_.reset(new ARAPlanner(planner_environment_.get(),forward_search_));
00226   } else if (planner_type_ == "ADPlanner"){
00227     planner_.reset(new ADPlanner(planner_environment_.get(),forward_search_));
00228   } else if (planner_type_ == "RSTARPlanner"){
00229     planner_.reset(new RSTARPlanner(planner_environment_.get(),forward_search_));
00230   }
00231 }
00232 
00233 


humanoid_planner_2d
Author(s): Armin Hornung
autogenerated on Sat Jun 8 2019 20:21:15