map_grid.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2008, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
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     //don't allow construction of zero size grid
00065     ROS_ASSERT(size_y_ != 0 && size_x_ != 0);
00066 
00067     map_.resize(size_y_ * size_x_);
00068 
00069     //make each cell aware of its location in the grid
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   //reset the path_dist and goal_dist fields for all cells
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   //update what map cells are considered path based on the global_plan
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(&current);
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(&current);
00154     }
00155     ROS_INFO("MapGrid::setPathCells: Local goal: %f, %f", goal_x_, goal_y_);
00156 
00157     //compute our distances
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 };


iri_ackermann_local_planner
Author(s): Sergi Hernandez Juan
autogenerated on Fri Dec 6 2013 23:50:17