00001
00004
00005
00006
00007
00008 #include <iostream>
00009 #include "../../../include/cost_map_core/operators/inflation.hpp"
00010
00011
00012
00013
00014
00015 namespace cost_map {
00016
00017
00018
00019
00020
00021 void Inflate::operator()(const std::string layer_source,
00022 const std::string layer_destination,
00023 const float& inflation_radius,
00024 const InflationComputer& inflation_computer,
00025 CostMap& cost_map
00026 ) {
00027
00028
00029 unsigned int size_x = cost_map.getSize().x();
00030 unsigned int size_y = cost_map.getSize().y();
00031 unsigned int size = size_x*size_y;
00032 const cost_map::Matrix& data_source = cost_map.get(layer_source);
00033 cost_map.add(layer_destination, data_source);
00034
00035
00036 seen_.resize(size_x, size_y);
00037 seen_.setConstant(false);
00038 unsigned int new_cell_inflation_radius = static_cast<unsigned int>(std::max(0.0, std::ceil(inflation_radius / cost_map.getResolution())));
00039 if (new_cell_inflation_radius != cell_inflation_radius_ ) {
00040 cell_inflation_radius_ = new_cell_inflation_radius;
00041 computeCaches(cost_map.getResolution(), inflation_computer);
00042 }
00043
00044
00045
00046 for (unsigned int j = 0, number_of_rows = data_source.rows(), number_of_columns = data_source.cols(); j < number_of_columns; ++j) {
00047 for (unsigned int i = 0; i < number_of_rows; ++i) {
00048 unsigned char cost = data_source(i, j);
00049 if (cost == LETHAL_OBSTACLE) {
00050 unsigned int index = j*number_of_rows + i;
00051 enqueue(cost_map.get(layer_source), cost_map.get(layer_destination), i, j, i, j);
00052 }
00053 }
00054 }
00055 while (!inflation_queue_.empty())
00056 {
00057
00058 const CellData& current_cell = inflation_queue_.top();
00059
00060 unsigned int mx = current_cell.x_;
00061 unsigned int my = current_cell.y_;
00062 unsigned int sx = current_cell.src_x_;
00063 unsigned int sy = current_cell.src_y_;
00064
00065
00066 inflation_queue_.pop();
00067
00068
00069 if (mx > 0) {
00070 enqueue(cost_map.get(layer_source), cost_map.get(layer_destination), mx - 1, my, sx, sy);
00071 }
00072 if (my > 0) {
00073 enqueue(cost_map.get(layer_source), cost_map.get(layer_destination), mx, my - 1, sx, sy);
00074 }
00075 if (mx < size_x - 1) {
00076 enqueue(cost_map.get(layer_source), cost_map.get(layer_destination), mx + 1, my, sx, sy);
00077 }
00078 if (my < size_y - 1) {
00079 enqueue(cost_map.get(layer_source), cost_map.get(layer_destination), mx, my + 1, sx, sy);
00080 }
00081 }
00082 }
00083
00084 void Inflate::enqueue(const cost_map::Matrix& data_source,
00085 cost_map::Matrix& data_destination,
00086 unsigned int mx, unsigned int my,
00087 unsigned int src_x, unsigned int src_y
00088 )
00089 {
00090
00091 if (!seen_(mx, my))
00092 {
00093
00094 double distance = distanceLookup(mx, my, src_x, src_y);
00095
00096
00097 if (distance > cell_inflation_radius_) {
00098 return;
00099 }
00100
00101
00102 unsigned char cost = costLookup(mx, my, src_x, src_y);
00103 unsigned char old_cost = data_source(mx, my);
00104
00105 if (old_cost == NO_INFORMATION && cost >= INSCRIBED_OBSTACLE)
00106 data_destination(mx, my) = cost;
00107 else
00108 data_destination(mx, my) = std::max(old_cost, cost);
00109
00110
00111 seen_(mx, my) = true;
00112 CellData data(distance, mx, my, src_x, src_y);
00113 inflation_queue_.push(data);
00114 }
00115 }
00116
00117 double Inflate::distanceLookup(int mx, int my, int src_x, int src_y)
00118 {
00119 unsigned int dx = abs(mx - src_x);
00120 unsigned int dy = abs(my - src_y);
00121 return cached_distances_(dx, dy);
00122 }
00123
00124 unsigned char Inflate::costLookup(int mx, int my, int src_x, int src_y)
00125 {
00126 unsigned int dx = abs(mx - src_x);
00127 unsigned int dy = abs(my - src_y);
00128 return cached_costs_(dx, dy);
00129 }
00130
00131 void Inflate::computeCaches(const float& resolution, const InflationComputer& compute_cost)
00132 {
00133 cached_costs_.resize(cell_inflation_radius_ + 2, cell_inflation_radius_ + 2);
00134 cached_distances_.resize(cell_inflation_radius_ + 2, cell_inflation_radius_ + 2);
00135
00136 for (unsigned int i = 0; i <= cell_inflation_radius_ + 1; ++i) {
00137 for (unsigned int j = 0; j <= cell_inflation_radius_ + 1; ++j) {
00138 cached_distances_(i,j) = std::hypot(i, j);
00139 }
00140 }
00141
00142 for (unsigned int i = 0; i <= cell_inflation_radius_ + 1; ++i) {
00143 for (unsigned int j = 0; j <= cell_inflation_radius_ + 1; ++j) {
00144 cached_costs_(i, j) = compute_cost(resolution*cached_distances_(i, j));
00145 }
00146 }
00147 }
00148
00149
00150
00151
00152
00153 ROSInflationComputer::ROSInflationComputer(
00154 const float& inscribed_radius,
00155 const float& weight)
00156 : inscribed_radius_(inscribed_radius)
00157 , weight_(weight)
00158 {
00159 }
00160
00161 unsigned char ROSInflationComputer::operator()(const float &distance) const {
00162 unsigned char cost = 0;
00163 if (distance == 0.0)
00164 cost = LETHAL_OBSTACLE;
00165 else if (distance <= inscribed_radius_)
00166 cost = INSCRIBED_OBSTACLE;
00167 else
00168 {
00169
00170 double factor = std::exp(-1.0 * weight_ * (distance - inscribed_radius_));
00171 cost = (unsigned char)((INSCRIBED_OBSTACLE - 1) * factor);
00172 }
00173 return cost;
00174 }
00175
00176
00177
00178
00179
00180 Deflate::Deflate(const bool& do_not_strip_inscribed_region)
00181 : do_not_strip_inscribed_region(do_not_strip_inscribed_region)
00182 {
00183 }
00184
00185 void Deflate::operator()(const std::string layer_source,
00186 const std::string layer_destination,
00187 CostMap& cost_map
00188 )
00189 {
00190
00191
00192 cost_map::Matrix data_source = cost_map.get(layer_source);
00193
00194 cost_map.add(layer_destination);
00195 cost_map::Matrix& data_destination = cost_map.get(layer_destination);
00196
00197 unsigned char cost_threshold = do_not_strip_inscribed_region ? cost_map::INSCRIBED_OBSTACLE : cost_map::LETHAL_OBSTACLE;
00198
00199
00200 for (unsigned int j = 0, number_of_rows = data_source.rows(), number_of_columns = data_source.cols(); j < number_of_columns; ++j) {
00201 for (unsigned int i = 0; i < number_of_rows; ++i) {
00202 unsigned char cost = data_source(i, j);
00203 data_destination(i, j) = (cost >= cost_threshold ) ? cost : cost_map::FREE_SPACE;
00204 }
00205 }
00206 }
00207
00208
00209
00210
00211
00212
00213 }