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 <base_local_planner/map_grid.h>
00035
00036 using namespace std;
00037
00038 namespace base_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
00156 computePathDistance(path_dist_queue, costmap);
00157 computeGoalDistance(goal_dist_queue, costmap);
00158 }
00159
00160 void MapGrid::computePathDistance(queue<MapCell*>& dist_queue, const costmap_2d::Costmap2D& costmap){
00161 MapCell* current_cell;
00162 MapCell* check_cell;
00163 unsigned int last_col = size_x_ - 1;
00164 unsigned int last_row = size_y_ - 1;
00165 while(!dist_queue.empty()){
00166 current_cell = dist_queue.front();
00167 check_cell = current_cell;
00168 dist_queue.pop();
00169
00170 if(current_cell->cx > 0){
00171 check_cell = current_cell - 1;
00172 if(!check_cell->path_mark){
00173 updatePathCell(current_cell, check_cell, dist_queue, costmap);
00174 }
00175 }
00176
00177 if(current_cell->cx < last_col){
00178 check_cell = current_cell + 1;
00179 if(!check_cell->path_mark){
00180 updatePathCell(current_cell, check_cell, dist_queue, costmap);
00181 }
00182 }
00183
00184 if(current_cell->cy > 0){
00185 check_cell = current_cell - size_x_;
00186 if(!check_cell->path_mark){
00187 updatePathCell(current_cell, check_cell, dist_queue, costmap);
00188 }
00189 }
00190
00191 if(current_cell->cy < last_row){
00192 check_cell = current_cell + size_x_;
00193 if(!check_cell->path_mark){
00194 updatePathCell(current_cell, check_cell, dist_queue, costmap);
00195 }
00196 }
00197 }
00198 }
00199
00200 void MapGrid::computeGoalDistance(queue<MapCell*>& dist_queue, const costmap_2d::Costmap2D& costmap){
00201 MapCell* current_cell;
00202 MapCell* check_cell;
00203 unsigned int last_col = size_x_ - 1;
00204 unsigned int last_row = size_y_ - 1;
00205 while(!dist_queue.empty()){
00206 current_cell = dist_queue.front();
00207 current_cell->goal_mark = true;
00208 check_cell = current_cell;
00209 dist_queue.pop();
00210
00211 if(current_cell->cx > 0){
00212 check_cell = current_cell - 1;
00213 if(!check_cell->goal_mark){
00214 updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00215 }
00216 }
00217
00218 if(current_cell->cx < last_col){
00219 check_cell = current_cell + 1;
00220 if(!check_cell->goal_mark){
00221 updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00222 }
00223 }
00224
00225 if(current_cell->cy > 0){
00226 check_cell = current_cell - size_x_;
00227 if(!check_cell->goal_mark){
00228 updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00229 }
00230 }
00231
00232 if(current_cell->cy < last_row){
00233 check_cell = current_cell + size_x_;
00234 if(!check_cell->goal_mark){
00235 updateGoalCell(current_cell, check_cell, dist_queue, costmap);
00236 }
00237 }
00238 }
00239 }
00240
00241
00242 };