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 
00030 
00031 
00032 
00033 
00034 #include <map_grid.h>
00035 
00036 using namespace std;
00037 
00038 namespace iri_ackermann_local_planner{
00039 
00040   MapGrid::MapGrid()
00041     : size_x_(0), size_y_(0)
00042   {
00043   }
00044 
00045   MapGrid::MapGrid(unsigned int size_x, unsigned int size_y) 
00046     : size_x_(size_x), size_y_(size_y)
00047   {
00048     commonInit();
00049   }
00050 
00051   MapGrid::MapGrid(unsigned int size_x, unsigned int size_y, double s, double x, double y)
00052     : size_x_(size_x), size_y_(size_y), scale(s), origin_x(x), origin_y(y)
00053   {
00054     commonInit();
00055   }
00056 
00057   MapGrid::MapGrid(const MapGrid& mg){
00058     size_y_ = mg.size_y_;
00059     size_x_ = mg.size_x_;
00060     map_ = mg.map_;
00061   }
00062 
00063   void MapGrid::commonInit(){
00064     
00065     ROS_ASSERT(size_y_ != 0 && size_x_ != 0);
00066 
00067     map_.resize(size_y_ * size_x_);
00068 
00069     
00070     for(unsigned int i = 0; i < size_y_; ++i){
00071       for(unsigned int j = 0; j < size_x_; ++j){
00072         unsigned int id = size_x_ * i + j;
00073         map_[id].cx = j;
00074         map_[id].cy = i;
00075       }
00076     }
00077   }
00078 
00079   size_t MapGrid::getIndex(int x, int y){
00080     return size_x_ * y + x;
00081   }
00082 
00083   MapGrid& MapGrid::operator= (const MapGrid& mg){
00084     size_y_ = mg.size_y_;
00085     size_x_ = mg.size_x_;
00086     map_ = mg.map_;
00087     return *this;
00088   }
00089 
00090   void MapGrid::sizeCheck(unsigned int size_x, unsigned int size_y, double o_x, double o_y){
00091     if(map_.size() != size_x * size_y)
00092       map_.resize(size_x * size_y);
00093 
00094     if(size_x_ != size_x || size_y_ != size_y){
00095       size_x_ = size_x;
00096       size_y_ = size_y;
00097 
00098       for(unsigned int i = 0; i < size_y_; ++i){
00099         for(unsigned int j = 0; j < size_x_; ++j){
00100           int index = size_x_ * i + j;
00101           map_[index].cx = j;
00102           map_[index].cy = i;
00103         }
00104       }
00105     }
00106     origin_x = o_x;
00107     origin_y = o_y;
00108   }
00109 
00110   
00111   void MapGrid::resetPathDist(){
00112     for(unsigned int i = 0; i < map_.size(); ++i){
00113       map_[i].path_dist = DBL_MAX;
00114       map_[i].goal_dist = DBL_MAX;
00115       map_[i].path_mark = false;
00116       map_[i].goal_mark = false;
00117       map_[i].within_robot = false;
00118     }
00119   }
00120 
00121   
00122   void MapGrid::setPathCells(const costmap_2d::Costmap2D& costmap, const std::vector<geometry_msgs::PoseStamped>& global_plan){
00123     sizeCheck(costmap.getSizeInCellsX(), costmap.getSizeInCellsY(), costmap.getOriginX(), costmap.getOriginY());
00124     int local_goal_x = -1;
00125     int local_goal_y = -1;
00126     bool started_path = false;
00127     queue<MapCell*> path_dist_queue;
00128     queue<MapCell*> goal_dist_queue;
00129     for(unsigned int i = 0; i < global_plan.size(); ++i){
00130       double g_x = global_plan[i].pose.position.x;
00131       double g_y = global_plan[i].pose.position.y;
00132       unsigned int map_x, map_y;
00133       if(costmap.worldToMap(g_x, g_y, map_x, map_y) && costmap.getCost(map_x, map_y) != costmap_2d::NO_INFORMATION){
00134         MapCell& current = getCell(map_x, map_y);
00135         current.path_dist = 0.0;
00136         current.path_mark = true;
00137         path_dist_queue.push(¤t);
00138         local_goal_x = map_x;
00139         local_goal_y = map_y;
00140         started_path = true;
00141       }
00142       else{
00143         if(started_path)
00144           break;
00145       }
00146     }
00147 
00148     if(local_goal_x >= 0 && local_goal_y >= 0){
00149       MapCell& current = getCell(local_goal_x, local_goal_y);
00150       costmap.mapToWorld(local_goal_x, local_goal_y, goal_x_, goal_y_);
00151       current.goal_dist = 0.0;
00152       current.goal_mark = true;
00153       goal_dist_queue.push(¤t);
00154     }
00155     ROS_INFO("MapGrid::setPathCells: Local goal: %f, %f", goal_x_, goal_y_);
00156 
00157     
00158     computePathDistance(path_dist_queue, costmap);
00159     computeGoalDistance(goal_dist_queue, costmap);
00160   }
00161 
00162   void MapGrid::computePathDistance(queue<MapCell*>& dist_queue, const costmap_2d::Costmap2D& costmap){
00163     MapCell* current_cell;
00164     MapCell* check_cell;
00165     unsigned int last_col = size_x_ - 1;
00166     unsigned int last_row = size_y_ - 1;
00167     while(!dist_queue.empty()){
00168       current_cell = dist_queue.front();
00169       check_cell = current_cell;
00170       dist_queue.pop();
00171 
00172       if(current_cell->cx > 0){
00173         check_cell = current_cell - 1;
00174         if(!check_cell->path_mark){
00175           updatePathCell(current_cell, check_cell, dist_queue, costmap);
00176         }
00177       }
00178 
00179       if(current_cell->cx < last_col){
00180         check_cell = current_cell + 1;
00181         if(!check_cell->path_mark){
00182           updatePathCell(current_cell, check_cell, dist_queue, costmap);
00183         }
00184       }
00185 
00186       if(current_cell->cy > 0){
00187         check_cell = current_cell - size_x_;
00188         if(!check_cell->path_mark){
00189           updatePathCell(current_cell, check_cell, dist_queue, costmap);
00190         }
00191       }
00192 
00193       if(current_cell->cy < last_row){
00194         check_cell = current_cell + size_x_;
00195         if(!check_cell->path_mark){
00196           updatePathCell(current_cell, check_cell, dist_queue, costmap);
00197         }
00198       }
00199     }
00200   }
00201 
00202   void MapGrid::computeGoalDistance(queue<MapCell*>& dist_queue, const costmap_2d::Costmap2D& costmap){
00203     MapCell* current_cell;
00204     MapCell* check_cell;
00205     unsigned int last_col = size_x_ - 1;
00206     unsigned int last_row = size_y_ - 1;
00207     while(!dist_queue.empty()){
00208       current_cell = dist_queue.front();
00209       current_cell->goal_mark = true;
00210       check_cell = current_cell;
00211       dist_queue.pop();
00212 
00213       if(current_cell->cx > 0){
00214         check_cell = current_cell - 1;
00215         if(!check_cell->goal_mark){
00216           updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00217         }
00218       }
00219 
00220       if(current_cell->cx < last_col){
00221         check_cell = current_cell + 1;
00222         if(!check_cell->goal_mark){
00223           updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00224         }
00225       }
00226 
00227       if(current_cell->cy > 0){
00228         check_cell = current_cell - size_x_;
00229         if(!check_cell->goal_mark){
00230           updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00231         }
00232       }
00233 
00234       if(current_cell->cy < last_row){
00235         check_cell = current_cell + size_x_;
00236         if(!check_cell->goal_mark){
00237           updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00238         }
00239       }
00240     }
00241   }
00242 
00243 
00244 };