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 : resolution_(resolution), origin_x_(origin_x),
53 origin_y_(origin_y), costmap_(NULL), default_value_(default_value)
55 access_ =
new mutex_t();
58 initMaps(cells_size_x, cells_size_y);
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_);
107 costmap_ =
new unsigned char[size_x * size_y];
111 unsigned int size_x,
unsigned int size_y,
double resolution,
112 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,
169 resolution_ = map.resolution_;
170 origin_x_ = win_origin_x;
171 origin_y_ = win_origin_y;
174 initMaps(upper_right_x - lower_left_x, upper_right_y - lower_left_y);
178 map.costmap_, lower_left_x, lower_left_y, map.size_x_, costmap_, 0, 0, size_x_,
186 unsigned int sx0,
unsigned int sy0,
unsigned int sxn,
unsigned int syn,
187 unsigned int dx0,
unsigned int dy0)
189 const unsigned int sz_x = sxn - sx0;
190 const unsigned int sz_y = syn - sy0;
196 if (dx0 + sz_x > size_x_ || dy0 + sz_y > size_y_) {
201 source.costmap_, sx0, sy0, source.size_x_,
202 costmap_, dx0, dy0, size_x_,
217 size_x_ = map.size_x_;
218 size_y_ = map.size_y_;
219 resolution_ = map.resolution_;
220 origin_x_ = map.origin_x_;
221 origin_y_ = map.origin_y_;
222 default_value_ = map.default_value_;
228 memcpy(costmap_, map.costmap_, size_x_ * size_y_ *
sizeof(
unsigned char));
236 access_ =
new mutex_t();
242 : size_x_(0), size_y_(0), resolution_(0.0), origin_x_(0.0), origin_y_(0.0), costmap_(NULL)
244 access_ =
new mutex_t();
255 double cells_dist = std::max(0.0, ceil(world_dist / resolution_));
256 return (
unsigned int)cells_dist;
271 return costmap_[undex];
281 wx = origin_x_ + (mx + 0.5) * resolution_;
282 wy = origin_y_ + (my + 0.5) * resolution_;
287 wx = origin_x_ + (mx + 0.5) * resolution_;
288 wy = origin_y_ + (my + 0.5) * resolution_;
293 if (wx < origin_x_ || wy < origin_y_) {
297 mx =
static_cast<unsigned int>((wx - origin_x_) / resolution_);
298 my =
static_cast<unsigned int>((wy - origin_y_) / resolution_);
300 if (mx < size_x_ && my < size_y_) {
308 if (wx < origin_x_ || wy < origin_y_) {
312 mx =
static_cast<float>((wx - origin_x_) / resolution_);
313 my =
static_cast<float>((wy - origin_y_) / resolution_);
315 if (mx < size_x_ && my < size_y_) {
323 mx =
static_cast<int>((wx - origin_x_) / resolution_);
324 my =
static_cast<int>((wy - origin_y_) / resolution_);
332 if (wx < origin_x_) {
334 }
else if (wx > resolution_ * size_x_ + origin_x_) {
337 mx =
static_cast<int>((wx - origin_x_) / resolution_);
340 if (wy < origin_y_) {
342 }
else if (wy > resolution_ * size_y_ + origin_y_) {
345 my =
static_cast<int>((wy - origin_y_) / resolution_);
352 int cell_ox, cell_oy;
353 cell_ox =
static_cast<int>((new_origin_x - origin_x_) / resolution_);
354 cell_oy =
static_cast<int>((new_origin_y - origin_y_) / resolution_);
358 double new_grid_ox, new_grid_oy;
359 new_grid_ox = origin_x_ + cell_ox * resolution_;
360 new_grid_oy = origin_y_ + cell_oy * resolution_;
363 int size_x = size_x_;
364 int size_y = size_y_;
367 int lower_left_x, lower_left_y, upper_right_x, upper_right_y;
368 lower_left_x = std::min(std::max(cell_ox, 0), size_x);
369 lower_left_y = std::min(std::max(cell_oy, 0), size_y);
370 upper_right_x = std::min(std::max(cell_ox + size_x, 0), size_x);
371 upper_right_y = std::min(std::max(cell_oy + size_y, 0), size_y);
373 unsigned int cell_size_x = upper_right_x - lower_left_x;
374 unsigned int cell_size_y = upper_right_y - lower_left_y;
377 unsigned char * local_map =
new unsigned char[cell_size_x * cell_size_y];
381 costmap_, lower_left_x, lower_left_y, size_x_, local_map, 0, 0, cell_size_x,
389 origin_x_ = new_grid_ox;
390 origin_y_ = new_grid_oy;
393 int start_x = lower_left_x - cell_ox;
394 int start_y = lower_left_y - cell_oy;
398 local_map, 0, 0, cell_size_x, costmap_, start_x, start_y, size_x_, cell_size_x,
406 const std::vector<geometry_msgs::msg::Point> & polygon,
407 unsigned char cost_value)
409 std::vector<MapLocation> polygon_map_region;
410 polygon_map_region.reserve(100);
421 const std::vector<MapLocation> & polygon_map_region,
422 unsigned char new_cost_value)
424 for (
const auto & cell : polygon_map_region) {
425 setCost(cell.x, cell.y, new_cost_value);
430 const std::vector<MapLocation> & polygon_map_region)
432 for (
const auto & cell : polygon_map_region) {
433 setCost(cell.x, cell.y, cell.cost);
438 const std::vector<geometry_msgs::msg::Point> & polygon,
439 std::vector<MapLocation> & polygon_map_region)
443 std::vector<MapLocation> map_polygon;
444 for (
const auto & cell : polygon) {
446 if (!
worldToMap(cell.x, cell.y, loc.x, loc.y)) {
450 map_polygon.push_back(loc);
460 const std::vector<MapLocation> & polygon,
461 std::vector<MapLocation> & polygon_cells)
464 for (
unsigned int i = 0; i < polygon.size() - 1; ++i) {
465 raytraceLine(cell_gatherer, polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y);
467 if (!polygon.empty()) {
468 unsigned int last_index = polygon.size() - 1;
471 cell_gatherer, polygon[last_index].x, polygon[last_index].y, polygon[0].x,
477 const std::vector<MapLocation> & polygon,
478 std::vector<MapLocation> & polygon_cells)
481 if (polygon.size() < 3) {
491 while (i < polygon_cells.size() - 1) {
492 if (polygon_cells[i].x > polygon_cells[i + 1].x) {
493 swap = polygon_cells[i];
494 polygon_cells[i] = polygon_cells[i + 1];
495 polygon_cells[i + 1] = swap;
508 unsigned int min_x = polygon_cells[0].x;
509 unsigned int max_x = polygon_cells[polygon_cells.size() - 1].x;
512 for (
unsigned int x = min_x; x <= max_x; ++x) {
513 if (i >= polygon_cells.size() - 1) {
517 if (polygon_cells[i].y < polygon_cells[i + 1].y) {
518 min_pt = polygon_cells[i];
519 max_pt = polygon_cells[i + 1];
521 min_pt = polygon_cells[i + 1];
522 max_pt = polygon_cells[i];
526 while (i < polygon_cells.size() && polygon_cells[i].x == x) {
527 if (polygon_cells[i].y < min_pt.y) {
528 min_pt = polygon_cells[i];
529 }
else if (polygon_cells[i].y > max_pt.y) {
530 max_pt = polygon_cells[i];
537 for (
unsigned int y = min_pt.y; y <= max_pt.y; ++y) {
541 polygon_cells.push_back(pt);
558 return (size_x_ - 1 + 0.5) * resolution_;
563 return (size_y_ - 1 + 0.5) * resolution_;
583 FILE * fp = fopen(file_name.c_str(),
"w");
589 fprintf(fp,
"P2\n%u\n%u\n%u\n", size_x_, size_y_, 0xff);
590 for (
unsigned int iy = 0; iy < size_y_; iy++) {
591 for (
unsigned int ix = 0; ix < size_x_; ix++) {
592 unsigned char cost =
getCost(ix, iy);
593 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.
void mapToWorldNoBounds(int mx, int my, double &wx, double &wy) const
Convert from map coordinates to world coordinates with no bounds checking.
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 setMapRegionOccupiedByPolygon(const std::vector< MapLocation > &polygon_map_region, unsigned char new_cost_value)
Sets the given map region to desired value.
void restoreMapRegionOccupiedByPolygon(const std::vector< MapLocation > &polygon_map_region)
Restores the corresponding map region using given map region.
void worldToMapNoBounds(double wx, double wy, int &mx, int &my) const
Convert from world coordinates to map coordinates without checking for legal bounds.
bool worldToMapContinuous(double wx, double wy, float &mx, float &my) const
Convert from world coordinates to map coordinates.
virtual void initMaps(unsigned int size_x, unsigned int size_y)
Initializes the costmap, static_map, and markers data structures.
bool getMapRegionOccupiedByPolygon(const std::vector< geometry_msgs::msg::Point > &polygon, std::vector< MapLocation > &polygon_map_region)
Gets the map region occupied by polygon.
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.