38 #include "nav2_costmap_2d/costmap_2d.hpp"
44 #include "nav2_costmap_2d/cost_values.hpp"
45 #include "nav2_util/occ_grid_values.hpp"
50 unsigned int cells_size_x,
unsigned int cells_size_y,
double resolution,
51 double origin_x,
double origin_y,
unsigned char default_value)
52 : size_x_(cells_size_x), size_y_(cells_size_y), resolution_(resolution), origin_x_(origin_x),
53 origin_y_(origin_y), costmap_(NULL), default_value_(default_value)
55 access_ =
new mutex_t();
63 : default_value_(FREE_SPACE)
65 access_ =
new mutex_t();
68 size_x_ = map.info.width;
69 size_y_ = map.info.height;
70 resolution_ = map.info.resolution;
71 origin_x_ = map.info.origin.position.x;
72 origin_y_ = map.info.origin.position.y;
75 costmap_ =
new unsigned char[size_x_ * size_y_];
79 for (
unsigned int it = 0; it < size_x_ * size_y_; it++) {
81 if (data == nav2_util::OCC_GRID_UNKNOWN) {
82 costmap_[it] = NO_INFORMATION;
86 costmap_[it] = std::round(
87 static_cast<double>(data) * (LETHAL_OBSTACLE - FREE_SPACE) /
88 (nav2_util::OCC_GRID_OCCUPIED - nav2_util::OCC_GRID_FREE));
96 std::unique_lock<mutex_t> lock(*access_);
103 std::unique_lock<mutex_t> lock(*access_);
105 costmap_ =
new unsigned char[size_x * size_y];
109 unsigned int size_x,
unsigned int size_y,
double resolution,
110 double origin_x,
double origin_y)
114 resolution_ = resolution;
115 origin_x_ = origin_x;
116 origin_y_ = origin_y;
126 std::unique_lock<mutex_t> lock(*access_);
127 memset(costmap_, default_value_, size_x_ * size_y_ *
sizeof(
unsigned char));
136 unsigned int x0,
unsigned int y0,
unsigned int xn,
unsigned int yn,
unsigned char value)
138 std::unique_lock<mutex_t> lock(*(access_));
139 unsigned int len = xn - x0;
140 for (
unsigned int y = y0 * size_x_ + x0; y < yn * size_x_ + x0; y += size_x_) {
141 memset(costmap_ + y, value, len *
sizeof(
unsigned char));
146 const Costmap2D & map,
double win_origin_x,
double win_origin_y,
160 unsigned int lower_left_x, lower_left_y, upper_right_x, upper_right_y;
161 if (!map.
worldToMap(win_origin_x, win_origin_y, lower_left_x, lower_left_y) ||
163 win_origin_x + win_size_x, win_origin_y + win_size_y, upper_right_x,
170 size_x_ = upper_right_x - lower_left_x;
171 size_y_ = upper_right_y - lower_left_y;
172 resolution_ = map.resolution_;
173 origin_x_ = win_origin_x;
174 origin_y_ = win_origin_y;
181 map.costmap_, lower_left_x, lower_left_y, map.size_x_, costmap_, 0, 0, size_x_,
189 unsigned int sx0,
unsigned int sy0,
unsigned int sxn,
unsigned int syn,
190 unsigned int dx0,
unsigned int dy0)
192 const unsigned int sz_x = sxn - sx0;
193 const unsigned int sz_y = syn - sy0;
199 if (dx0 + sz_x > size_x_ || dy0 + sz_y > size_y_) {
204 source.costmap_, sx0, sy0, source.size_x_,
205 costmap_, dx0, dy0, size_x_,
220 size_x_ = map.size_x_;
221 size_y_ = map.size_y_;
222 resolution_ = map.resolution_;
223 origin_x_ = map.origin_x_;
224 origin_y_ = map.origin_y_;
230 memcpy(costmap_, map.costmap_, size_x_ * size_y_ *
sizeof(
unsigned char));
238 access_ =
new mutex_t();
244 : size_x_(0), size_y_(0), resolution_(0.0), origin_x_(0.0), origin_y_(0.0), costmap_(NULL)
246 access_ =
new mutex_t();
257 double cells_dist = std::max(0.0, ceil(world_dist / resolution_));
258 return (
unsigned int)cells_dist;
273 return costmap_[undex];
283 wx = origin_x_ + (mx + 0.5) * resolution_;
284 wy = origin_y_ + (my + 0.5) * resolution_;
289 if (wx < origin_x_ || wy < origin_y_) {
293 mx =
static_cast<unsigned int>((wx - origin_x_) / resolution_);
294 my =
static_cast<unsigned int>((wy - origin_y_) / resolution_);
296 if (mx < size_x_ && my < size_y_) {
304 mx =
static_cast<int>((wx - origin_x_) / resolution_);
305 my =
static_cast<int>((wy - origin_y_) / resolution_);
313 if (wx < origin_x_) {
315 }
else if (wx > resolution_ * size_x_ + origin_x_) {
318 mx =
static_cast<int>((wx - origin_x_) / resolution_);
321 if (wy < origin_y_) {
323 }
else if (wy > resolution_ * size_y_ + origin_y_) {
326 my =
static_cast<int>((wy - origin_y_) / resolution_);
333 int cell_ox, cell_oy;
334 cell_ox =
static_cast<int>((new_origin_x - origin_x_) / resolution_);
335 cell_oy =
static_cast<int>((new_origin_y - origin_y_) / resolution_);
339 double new_grid_ox, new_grid_oy;
340 new_grid_ox = origin_x_ + cell_ox * resolution_;
341 new_grid_oy = origin_y_ + cell_oy * resolution_;
344 int size_x = size_x_;
345 int size_y = size_y_;
348 int lower_left_x, lower_left_y, upper_right_x, upper_right_y;
349 lower_left_x = std::min(std::max(cell_ox, 0), size_x);
350 lower_left_y = std::min(std::max(cell_oy, 0), size_y);
351 upper_right_x = std::min(std::max(cell_ox + size_x, 0), size_x);
352 upper_right_y = std::min(std::max(cell_oy + size_y, 0), size_y);
354 unsigned int cell_size_x = upper_right_x - lower_left_x;
355 unsigned int cell_size_y = upper_right_y - lower_left_y;
358 unsigned char * local_map =
new unsigned char[cell_size_x * cell_size_y];
362 costmap_, lower_left_x, lower_left_y, size_x_, local_map, 0, 0, cell_size_x,
370 origin_x_ = new_grid_ox;
371 origin_y_ = new_grid_oy;
374 int start_x = lower_left_x - cell_ox;
375 int start_y = lower_left_y - cell_oy;
379 local_map, 0, 0, cell_size_x, costmap_, start_x, start_y, size_x_, cell_size_x,
387 const std::vector<geometry_msgs::msg::Point> & polygon,
388 unsigned char cost_value)
392 std::vector<MapLocation> map_polygon;
393 for (
unsigned int i = 0; i < polygon.size(); ++i) {
395 if (!
worldToMap(polygon[i].x, polygon[i].y, loc.x, loc.y)) {
399 map_polygon.push_back(loc);
402 std::vector<MapLocation> polygon_cells;
408 for (
unsigned int i = 0; i < polygon_cells.size(); ++i) {
409 unsigned int index =
getIndex(polygon_cells[i].x, polygon_cells[i].y);
410 costmap_[index] = cost_value;
416 const std::vector<MapLocation> & polygon,
417 std::vector<MapLocation> & polygon_cells)
420 for (
unsigned int i = 0; i < polygon.size() - 1; ++i) {
421 raytraceLine(cell_gatherer, polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y);
423 if (!polygon.empty()) {
424 unsigned int last_index = polygon.size() - 1;
427 cell_gatherer, polygon[last_index].x, polygon[last_index].y, polygon[0].x,
433 const std::vector<MapLocation> & polygon,
434 std::vector<MapLocation> & polygon_cells)
437 if (polygon.size() < 3) {
447 while (i < polygon_cells.size() - 1) {
448 if (polygon_cells[i].x > polygon_cells[i + 1].x) {
449 swap = polygon_cells[i];
450 polygon_cells[i] = polygon_cells[i + 1];
451 polygon_cells[i + 1] = swap;
464 unsigned int min_x = polygon_cells[0].x;
465 unsigned int max_x = polygon_cells[polygon_cells.size() - 1].x;
468 for (
unsigned int x = min_x; x <= max_x; ++x) {
469 if (i >= polygon_cells.size() - 1) {
473 if (polygon_cells[i].y < polygon_cells[i + 1].y) {
474 min_pt = polygon_cells[i];
475 max_pt = polygon_cells[i + 1];
477 min_pt = polygon_cells[i + 1];
478 max_pt = polygon_cells[i];
482 while (i < polygon_cells.size() && polygon_cells[i].x == x) {
483 if (polygon_cells[i].y < min_pt.y) {
484 min_pt = polygon_cells[i];
485 }
else if (polygon_cells[i].y > max_pt.y) {
486 max_pt = polygon_cells[i];
493 for (
unsigned int y = min_pt.y; y <= max_pt.y; ++y) {
496 polygon_cells.push_back(pt);
513 return (size_x_ - 1 + 0.5) * resolution_;
518 return (size_y_ - 1 + 0.5) * resolution_;
538 FILE * fp = fopen(file_name.c_str(),
"w");
544 fprintf(fp,
"P2\n%u\n%u\n%u\n", size_x_, size_y_, 0xff);
545 for (
unsigned int iy = 0; iy < size_y_; iy++) {
546 for (
unsigned int ix = 0; ix < size_x_; ix++) {
547 unsigned char cost =
getCost(ix, iy);
548 fprintf(fp,
"%d ", cost);
A 2D costmap provides a mapping between points in the world and their associated "costs".
void mapToWorld(unsigned int mx, unsigned int my, double &wx, double &wy) const
Convert from map coordinates to world coordinates.
void resetMap(unsigned int x0, unsigned int y0, unsigned int xn, unsigned int yn)
Reset the costmap in bounds.
unsigned int getIndex(unsigned int mx, unsigned int my) const
Given two map coordinates... compute the associated index.
void resetMapToValue(unsigned int x0, unsigned int y0, unsigned int xn, unsigned int yn, unsigned char value)
Reset the costmap in bounds to a value.
void resizeMap(unsigned int size_x, unsigned int size_y, double resolution, double origin_x, double origin_y)
Resize the costmap.
unsigned char getCost(unsigned int mx, unsigned int my) const
Get the cost of a cell in the costmap.
virtual ~Costmap2D()
Destructor.
void polygonOutlineCells(const std::vector< MapLocation > &polygon, std::vector< MapLocation > &polygon_cells)
Get the map cells that make up the outline of a polygon.
virtual void deleteMaps()
Deletes the costmap, static_map, and markers data structures.
bool saveMap(std::string file_name)
Save the costmap out to a pgm file.
bool copyWindow(const Costmap2D &source, unsigned int sx0, unsigned int sy0, unsigned int sxn, unsigned int syn, unsigned int dx0, unsigned int dy0)
Copies the (x0,y0)..(xn,yn) window from source costmap into a current costmap.
void raytraceLine(ActionType at, unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int max_length=UINT_MAX, unsigned int min_length=0)
Raytrace a line and apply some action at each step.
void worldToMapEnforceBounds(double wx, double wy, int &mx, int &my) const
Convert from world coordinates to map coordinates, constraining results to legal bounds.
unsigned char * getCharMap() const
Will return a pointer to the underlying unsigned char array used as the costmap.
bool worldToMap(double wx, double wy, unsigned int &mx, unsigned int &my) const
Convert from world coordinates to map coordinates.
void copyMapRegion(data_type *source_map, unsigned int sm_lower_left_x, unsigned int sm_lower_left_y, unsigned int sm_size_x, data_type *dest_map, unsigned int dm_lower_left_x, unsigned int dm_lower_left_y, unsigned int dm_size_x, unsigned int region_size_x, unsigned int region_size_y)
Copy a region of a source map into a destination map.
void convexFillCells(const std::vector< MapLocation > &polygon, std::vector< MapLocation > &polygon_cells)
Get the map cells that fill a convex polygon.
double getResolution() const
Accessor for the resolution of the costmap.
virtual void updateOrigin(double new_origin_x, double new_origin_y)
Move the origin of the costmap to a new location.... keeping data when it can.
Costmap2D()
Default constructor.
bool setConvexPolygonCost(const std::vector< geometry_msgs::msg::Point > &polygon, unsigned char cost_value)
Sets the cost of a convex polygon to a desired value.
double getSizeInMetersY() const
Accessor for the y size of the costmap in meters.
double getSizeInMetersX() const
Accessor for the x size of the costmap in meters.
void worldToMapNoBounds(double wx, double wy, int &mx, int &my) const
Convert from world coordinates to map coordinates without checking for legal bounds.
virtual void initMaps(unsigned int size_x, unsigned int size_y)
Initializes the costmap, static_map, and markers data structures.
bool copyCostmapWindow(const Costmap2D &map, double win_origin_x, double win_origin_y, double win_size_x, double win_size_y)
Turn this costmap into a copy of a window of a costmap passed in.
unsigned int getSizeInCellsX() const
Accessor for the x size of the costmap in cells.
virtual void resetMaps()
Resets the costmap and static_map to be unknown space.
double getOriginY() const
Accessor for the y origin of the costmap.
unsigned int getSizeInCellsY() const
Accessor for the y size of the costmap in cells.
double getOriginX() const
Accessor for the x origin of the costmap.
void setCost(unsigned int mx, unsigned int my, unsigned char cost)
Set the cost of a cell in the costmap.
unsigned int cellDistance(double world_dist)
Given distance in the world... convert it to cells.
Costmap2D & operator=(const Costmap2D &map)
Overloaded assignment operator.