00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00050 }
00051
00052 SBPLPlanner2D::~SBPLPlanner2D() {
00053
00054 }
00055
00056 void SBPLPlanner2D::goalCallback(const geometry_msgs::PoseStampedConstPtr& goal_pose){
00057
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
00067 if (start_received_)
00068 plan();
00069 }
00070
00071 void SBPLPlanner2D::startCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr& start_pose){
00072
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
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
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
00164 path_costs_ = double(solution_cost) / ENVNAV2D_COSTMULT * map_->getResolution();
00165
00166
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
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
00201 setPlanner();
00202
00203
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