29 #ifndef __HectorMapTools_h_ 30 #define __HectorMapTools_h_ 32 #include <nav_msgs/OccupancyGrid.h> 33 #include <nav_msgs/MapMetaData.h> 40 template<
typename ConcreteScalar>
62 origo_ = (Eigen::Matrix<ConcreteScalar, 2, 1>(
static_cast<ConcreteScalar
>(meta.origin.position.x),static_cast<ConcreteScalar>(meta.origin.position.y)));
63 scale_ = (
static_cast<ConcreteScalar
>(meta.resolution));
64 inv_scale_ = (
static_cast<ConcreteScalar
>(1.0f / meta.resolution));
68 const Eigen::Matrix<ConcreteScalar, 2, 1>& origoCS2,
const Eigen::Matrix<ConcreteScalar, 2, 1>& endCS2)
70 Eigen::Matrix<ConcreteScalar, 2, 1> map_t_geotiff_x_factors =
getLinearTransform(Eigen::Vector2f(origoCS1[0], endCS1[0]), Eigen::Vector2f(origoCS2[0], endCS2[0]));
71 Eigen::Matrix<ConcreteScalar, 2, 1> map_t_geotiff_y_factors =
getLinearTransform(Eigen::Vector2f(origoCS1[1], endCS1[1]), Eigen::Vector2f(origoCS2[1], endCS2[1]));
75 origo_.x() = map_t_geotiff_x_factors[1];
76 origo_.y() = map_t_geotiff_y_factors[1];
78 scale_ = map_t_geotiff_x_factors[0];
84 Eigen::Matrix<ConcreteScalar, 2, 1>
getC1Coords(
const Eigen::Matrix<ConcreteScalar, 2, 1>& mapCoords)
const 89 Eigen::Matrix<ConcreteScalar, 2, 1>
getC2Coords(
const Eigen::Matrix<ConcreteScalar, 2, 1>& worldCoords)
const 106 Eigen::Matrix<ConcreteScalar, 2, 1>
getLinearTransform(
const Eigen::Matrix<ConcreteScalar, 2, 1>& coordSystem1,
const Eigen::Matrix<ConcreteScalar, 2, 1>& coordSystem2)
108 ConcreteScalar scaling = (coordSystem2[0] - coordSystem2[1]) / (coordSystem1[0] - coordSystem1[1]);
109 ConcreteScalar translation = coordSystem2[0] - coordSystem1[0] * scaling;
110 return Eigen::Vector2f (scaling, translation);
113 Eigen::Matrix<ConcreteScalar, 2, 1>
origo_;
126 void setMap(
const nav_msgs::OccupancyGridConstPtr map)
130 world_map_transformer_.setTransforms(*map_ptr_);
133 float getDist(
const Eigen::Vector2f& begin_world,
const Eigen::Vector2f& end_world, Eigen::Vector2f* hitCoords = 0)
135 Eigen::Vector2i end_point_map;
137 Eigen::Vector2i begin_map (world_map_transformer_.getC2Coords(begin_world).cast<
int>());
138 Eigen::Vector2i end_map (world_map_transformer_.getC2Coords(end_world).cast<
int>());
139 float dist = checkOccupancyBresenhami(begin_map, end_map, &end_point_map);
142 *hitCoords = world_map_transformer_.getC1Coords(end_point_map.cast<
float>());
145 return world_map_transformer_.getC1Scale(dist);
148 inline float checkOccupancyBresenhami(
const Eigen::Vector2i& beginMap,
const Eigen::Vector2i& endMap, Eigen::Vector2i* hitCoords = 0,
unsigned int max_length = UINT_MAX){
150 int x0 = beginMap[0];
151 int y0 = beginMap[1];
153 int sizeX = map_ptr_->info.width;
154 int sizeY = map_ptr_->info.height;
157 if ((x0 < 0) || (x0 >= sizeX) || (y0 < 0) || (y0 >= sizeY)) {
167 if ((x1 < 0) || (x1 >= sizeX) || (y1 < 0) || (y1 >= sizeY)) {
174 unsigned int abs_dx = abs(dx);
175 unsigned int abs_dy = abs(dy);
177 int offset_dx = dx > 0 ? 1 : -1;
178 int offset_dy = (dy > 0 ? 1 : -1) * sizeX;
180 unsigned int startOffset = beginMap.y() * sizeX + beginMap.x();
185 if(abs_dx >= abs_dy){
186 int error_y = abs_dx / 2;
187 end_offset = bresenham2D(abs_dx, abs_dy, error_y, offset_dx, offset_dy, startOffset,5000);
190 int error_x = abs_dy / 2;
191 end_offset = bresenham2D(abs_dy, abs_dx, error_x, offset_dy, offset_dx, startOffset,5000);
194 if (end_offset != -1){
195 Eigen::Vector2i end_coords(end_offset % sizeX, end_offset / sizeX);
197 int distMap = ((beginMap - end_coords).cast<float>()).norm();
200 *hitCoords = end_coords;
212 inline int bresenham2D(
unsigned int abs_da,
unsigned int abs_db,
int error_b,
int offset_a,
int offset_b,
213 unsigned int offset,
unsigned int max_length){
214 unsigned int end = std::min(max_length, abs_da);
216 const std::vector<int8_t>& data = map_ptr_->data;
218 for(
unsigned int i = 0; i < end; ++i){
219 if (data[offset] == 100){
220 return static_cast<int>(offset);
225 if((
unsigned int)error_b >= abs_da){
241 static bool getMapExtends(
const nav_msgs::OccupancyGrid& map, Eigen::Vector2i& topLeft, Eigen::Vector2i& bottomRight)
244 int upperStart = 10000000;
246 int xMaxTemp = lowerStart;
247 int yMaxTemp = lowerStart;
248 int xMinTemp = upperStart;
249 int yMinTemp = upperStart;
251 int width = map.info.width;
252 int height = map.info.height;
254 for (
int y = 0; y < height; ++y){
255 for (
int x = 0; x < width; ++x){
257 if ( map.data[x+y*width] != -1){
278 if ((xMaxTemp != lowerStart) &&
279 (yMaxTemp != lowerStart) &&
280 (xMinTemp != upperStart) &&
281 (yMinTemp != upperStart)) {
283 topLeft = Eigen::Vector2i(xMinTemp,yMinTemp);
284 bottomRight = Eigen::Vector2i(xMaxTemp+1, yMaxTemp+1);