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 };