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
00035
00036
00037 #ifndef COSTMAP_COSTMAP_2D_H_
00038 #define COSTMAP_COSTMAP_2D_H_
00039
00040 #include <vector>
00041 #include <queue>
00042 #include <costmap_2d/observation.h>
00043 #include <costmap_2d/cell_data.h>
00044 #include <costmap_2d/cost_values.h>
00045 #include <sensor_msgs/PointCloud2.h>
00046 #include <boost/thread.hpp>
00047
00048 namespace costmap_2d {
00049 class Costmap2DConfig;
00050
00051
00052 struct MapLocation {
00053 unsigned int x;
00054 unsigned int y;
00055 };
00056
00061 class Costmap2D {
00062 friend class CostmapTester;
00063 public:
00084 Costmap2D(unsigned int cells_size_x, unsigned int cells_size_y,
00085 double resolution, double origin_x, double origin_y, double inscribed_radius = 0.0,
00086 double circumscribed_radius = 0.0, double inflation_radius = 0.0, double max_obstacle_range = 0.0,
00087 double max_obstacle_height = 0.0, double max_raytrace_range = 0.0, double weight = 25.0,
00088 const std::vector<unsigned char>& static_data = std::vector<unsigned char>(0), unsigned char lethal_threshold = 0,
00089 bool track_unknown_space = false, unsigned char unknown_cost_value = 0);
00090
00095 Costmap2D(const Costmap2D& map);
00096
00102 Costmap2D& operator=(const Costmap2D& map);
00103
00112 void copyCostmapWindow(const Costmap2D& map, double win_origin_x, double win_origin_y, double win_size_x, double win_size_y);
00113
00117 Costmap2D();
00118
00122 virtual ~Costmap2D();
00123
00124 void reconfigure(costmap_2d::Costmap2DConfig &config, const costmap_2d::Costmap2DConfig& last_config);
00125
00126 virtual void finishConfiguration(costmap_2d::Costmap2DConfig &config);
00127
00135 virtual void resetMapOutsideWindow(double wx, double wy, double w_size_x, double w_size_y);
00136
00145 void reinflateWindow(double wx, double wy, double w_size_x, double w_size_y, bool clear = true);
00146
00155 virtual void clearNonLethal(double wx, double wy, double w_size_x, double w_size_y, bool clear_no_info = false);
00156
00162 void updateWorld(double robot_x, double robot_y,
00163 const std::vector<Observation>& observations, const std::vector<Observation>& clearing_observations);
00164
00171 unsigned char getCost(unsigned int mx, unsigned int my) const;
00172
00179 void setCost(unsigned int mx, unsigned int my, unsigned char cost);
00180
00188 void mapToWorld(unsigned int mx, unsigned int my, double& wx, double& wy) const;
00189
00198 bool worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my) const;
00199
00208 void worldToMapNoBounds(double wx, double wy, int& mx, int& my) const;
00209
00216 inline unsigned int getIndex(unsigned int mx, unsigned int my) const{
00217 return my * size_x_ + mx;
00218 }
00219
00226 inline void indexToCells(unsigned int index, unsigned int& mx, unsigned int& my) const{
00227 my = index / size_x_;
00228 mx = index - (my * size_x_);
00229 }
00230
00235 const unsigned char* getCharMap() const;
00236
00241 unsigned int getSizeInCellsX() const;
00242
00247 unsigned int getSizeInCellsY() const;
00248
00253 double getSizeInMetersX() const;
00254
00259 double getSizeInMetersY() const;
00260
00265 double getOriginX() const;
00266
00271 double getOriginY() const;
00272
00277 double getResolution() const;
00278
00283 double getInscribedRadius() const { return inscribed_radius_; }
00284
00289 double getCircumscribedRadius() const { return circumscribed_radius_; }
00290
00295 double getInflationRadius() const { return inflation_radius_; }
00296
00303 bool setConvexPolygonCost(const std::vector<geometry_msgs::Point>& polygon, unsigned char cost_value);
00304
00310 void polygonOutlineCells(const std::vector<MapLocation>& polygon, std::vector<MapLocation>& polygon_cells);
00311
00317 void convexFillCells(const std::vector<MapLocation>& polygon, std::vector<MapLocation>& polygon_cells);
00318
00319
00325 virtual void updateOrigin(double new_origin_x, double new_origin_y);
00326
00334 bool isCircumscribedCell(unsigned int x, unsigned int y) const;
00335
00341 inline unsigned char computeCost(double distance) const {
00342 unsigned char cost = 0;
00343 if(distance == 0)
00344 cost = LETHAL_OBSTACLE;
00345 else if(distance <= cell_inscribed_radius_)
00346 cost = INSCRIBED_INFLATED_OBSTACLE;
00347 else {
00348
00349 double euclidean_distance = distance * resolution_;
00350 double factor = exp(-1.0 * weight_ * (euclidean_distance - inscribed_radius_));
00351 cost = (unsigned char) ((INSCRIBED_INFLATED_OBSTACLE - 1) * factor);
00352 }
00353 return cost;
00354 }
00355
00356
00357
00358
00359
00360 inline unsigned char getCircumscribedCost() const {
00361 return circumscribed_cost_lb_;
00362 }
00363
00368 void saveMap(std::string file_name);
00369
00378 void updateStaticMapWindow(double win_origin_x, double win_origin_y,
00379 unsigned int data_size_x, unsigned int data_size_y,
00380 const std::vector<unsigned char>& static_data);
00381
00390 void replaceFullMap(double win_origin_x, double win_origin_y,
00391 unsigned int data_size_x, unsigned int data_size_y,
00392 const std::vector<unsigned char>& static_data);
00393
00394
00395 protected:
00405 inline void enqueue(unsigned int index, unsigned int mx, unsigned int my,
00406 unsigned int src_x, unsigned int src_y, std::priority_queue<CellData>& inflation_queue){
00407 unsigned char* marked = &markers_[index];
00408
00409 if(*marked == 0){
00410
00411 double distance = distanceLookup(mx, my, src_x, src_y);
00412
00413
00414 if(distance > cell_inflation_radius_)
00415 return;
00416
00417
00418 updateCellCost(index, costLookup(mx, my, src_x, src_y));
00419
00420
00421 CellData data(distance, index, mx, my, src_x, src_y);
00422 inflation_queue.push(data);
00423 *marked = 1;
00424 }
00425 }
00426
00441 template <typename data_type>
00442 void copyMapRegion(data_type* source_map, unsigned int sm_lower_left_x, unsigned int sm_lower_left_y, unsigned int sm_size_x,
00443 data_type* dest_map, unsigned int dm_lower_left_x, unsigned int dm_lower_left_y, unsigned int dm_size_x,
00444 unsigned int region_size_x, unsigned int region_size_y){
00445
00446 data_type* sm_index = source_map + (sm_lower_left_y * sm_size_x + sm_lower_left_x);
00447 data_type* dm_index = dest_map + (dm_lower_left_y * dm_size_x + dm_lower_left_x);
00448
00449
00450 for(unsigned int i = 0; i < region_size_y; ++i){
00451 memcpy(dm_index, sm_index, region_size_x * sizeof(data_type));
00452 sm_index += sm_size_x;
00453 dm_index += dm_size_x;
00454 }
00455 }
00456
00462 unsigned int cellDistance(double world_dist);
00463
00467 virtual void deleteMaps();
00468
00472 virtual void resetMaps();
00473
00477 void deleteKernels();
00478
00484 virtual void initMaps(unsigned int size_x, unsigned int size_y);
00485
00491 void copyKernels(const Costmap2D& map, unsigned int cell_inflation_radius);
00492
00501 void reshapeStaticMap(double win_origin_x, double win_origin_y,
00502 unsigned int data_size_x, unsigned int data_size_y, const std::vector<unsigned char>& static_data);
00503
00512 void replaceStaticMapWindow(double win_origin_x, double win_origin_y,
00513 unsigned int data_size_x, unsigned int data_size_y,
00514 const std::vector<unsigned char>& static_data);
00515
00516 private:
00522 virtual void updateObstacles(const std::vector<Observation>& observations, std::priority_queue<CellData>& inflation_queue);
00523
00528 void raytraceFreespace(const std::vector<Observation>& clearing_observations);
00529
00534 virtual void raytraceFreespace(const Observation& clearing_observation);
00535
00545 void resetInflationWindow(double wx, double wy, double w_size_x, double w_size_y,
00546 std::priority_queue<CellData>& inflation_queue, bool clear = true );
00547
00551 void computeCaches();
00552
00562 template <class ActionType>
00563 inline void raytraceLine(ActionType at, unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, unsigned int max_length = UINT_MAX){
00564 int dx = x1 - x0;
00565 int dy = y1 - y0;
00566
00567 unsigned int abs_dx = abs(dx);
00568 unsigned int abs_dy = abs(dy);
00569
00570 int offset_dx = sign(dx);
00571 int offset_dy = sign(dy) * size_x_;
00572
00573 unsigned int offset = y0 * size_x_ + x0;
00574
00575
00576 double dist = sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
00577 double scale = std::min(1.0, max_length / dist);
00578
00579
00580 if(abs_dx >= abs_dy){
00581 int error_y = abs_dx / 2;
00582 bresenham2D(at, abs_dx, abs_dy, error_y, offset_dx, offset_dy, offset, (unsigned int)(scale * abs_dx));
00583 return;
00584 }
00585
00586
00587 int error_x = abs_dy / 2;
00588 bresenham2D(at, abs_dy, abs_dx, error_x, offset_dy, offset_dx, offset, (unsigned int)(scale * abs_dy));
00589
00590 }
00591
00595 template <class ActionType>
00596 inline void bresenham2D(ActionType at, unsigned int abs_da, unsigned int abs_db, int error_b, int offset_a, int offset_b,
00597 unsigned int offset, unsigned int max_length){
00598 unsigned int end = std::min(max_length, abs_da);
00599 for(unsigned int i = 0; i < end; ++i){
00600 at(offset);
00601 offset += offset_a;
00602 error_b += abs_db;
00603 if((unsigned int)error_b >= abs_da){
00604 offset += offset_b;
00605 error_b -= abs_da;
00606 }
00607 }
00608 at(offset);
00609 }
00610
00615 void inflateObstacles(std::priority_queue<CellData>& inflation_queue);
00616
00622 inline void updateCellCost(unsigned int index, unsigned char cost){
00623 unsigned char* cell_cost = &costmap_[index];
00624 if(*cell_cost != NO_INFORMATION)
00625 *cell_cost = std::max(cost, *cell_cost);
00626 else if(cost == LETHAL_OBSTACLE)
00627 *cell_cost = cost;
00628 }
00629
00638 inline char costLookup(int mx, int my, int src_x, int src_y){
00639 unsigned int dx = abs(mx - src_x);
00640 unsigned int dy = abs(my - src_y);
00641 return cached_costs_[dx][dy];
00642 }
00643
00652 inline double distanceLookup(int mx, int my, int src_x, int src_y){
00653 unsigned int dx = abs(mx - src_x);
00654 unsigned int dy = abs(my - src_y);
00655 return cached_distances_[dx][dy];
00656 }
00657
00658 inline int sign(int x){
00659 return x > 0 ? 1.0 : -1.0;
00660 }
00661
00662 boost::recursive_mutex configuration_mutex_;
00663 protected:
00664 unsigned int size_x_;
00665 unsigned int size_y_;
00666 double resolution_;
00667 double origin_x_;
00668 double origin_y_;
00669 unsigned char* static_map_;
00670 unsigned char* costmap_;
00671 unsigned char* markers_;
00672 double max_obstacle_range_;
00673 double max_obstacle_height_;
00674 double max_raytrace_range_;
00675 unsigned char** cached_costs_;
00676 double** cached_distances_;
00677 double inscribed_radius_, circumscribed_radius_, inflation_radius_;
00678 unsigned int cell_inscribed_radius_, cell_circumscribed_radius_, cell_inflation_radius_;
00679 double weight_;
00680 unsigned char circumscribed_cost_lb_, lethal_threshold_;
00681 bool track_unknown_space_;
00682 unsigned char unknown_cost_value_;
00683 std::priority_queue<CellData> inflation_queue_;
00684
00685
00686 class ClearCell {
00687 public:
00688 ClearCell(unsigned char* costmap) : costmap_(costmap) {}
00689 inline void operator()(unsigned int offset){
00690 costmap_[offset] = 0;
00691 }
00692 private:
00693 unsigned char* costmap_;
00694 };
00695
00696 class MarkCell {
00697 public:
00698 MarkCell(unsigned char* costmap) : costmap_(costmap) {}
00699 inline void operator()(unsigned int offset){
00700 costmap_[offset] = LETHAL_OBSTACLE;
00701 }
00702 private:
00703 unsigned char* costmap_;
00704 };
00705
00706 class PolygonOutlineCells {
00707 public:
00708 PolygonOutlineCells(const Costmap2D& costmap, const unsigned char* char_map, std::vector<MapLocation>& cells)
00709 : costmap_(costmap), char_map_(char_map), cells_(cells){}
00710
00711
00712 inline void operator()(unsigned int offset){
00713 MapLocation loc;
00714 costmap_.indexToCells(offset, loc.x, loc.y);
00715 cells_.push_back(loc);
00716 }
00717
00718 private:
00719 const Costmap2D& costmap_;
00720 const unsigned char* char_map_;
00721 std::vector<MapLocation>& cells_;
00722 };
00723 };
00724 };
00725
00726 #endif