Go to the documentation of this file.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 #ifndef __GridMapBase_h_
00030 #define __GridMapBase_h_
00031
00032 #include <Eigen/Geometry>
00033 #include <Eigen/LU>
00034
00035 #include "MapDimensionProperties.h"
00036
00037 namespace hectorslam {
00038
00043 template<typename ConcreteCellType>
00044 class GridMapBase
00045 {
00046
00047 public:
00048
00049 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00050
00055 bool hasGridValue(int x, int y) const
00056 {
00057 return (x >= 0) && (y >= 0) && (x < this->getSizeX()) && (y < this->getSizeY());
00058 }
00059
00060 const Eigen::Vector2i& getMapDimensions() const { return mapDimensionProperties.getMapDimensions(); };
00061 int getSizeX() const { return mapDimensionProperties.getSizeX(); };
00062 int getSizeY() const { return mapDimensionProperties.getSizeY(); };
00063
00064 bool pointOutOfMapBounds(const Eigen::Vector2f& pointMapCoords) const
00065 {
00066 return mapDimensionProperties.pointOutOfMapBounds(pointMapCoords);
00067 }
00068
00069 virtual void reset()
00070 {
00071 this->clear();
00072 }
00073
00077 void clear()
00078 {
00079 int size = this->getSizeX() * this->getSizeY();
00080
00081 for (int i = 0; i < size; ++i) {
00082 this->mapArray[i].resetGridCell();
00083 }
00084
00085
00086
00087 }
00088
00089
00090 const MapDimensionProperties& getMapDimProperties() const { return mapDimensionProperties; };
00091
00095 GridMapBase(float mapResolution, const Eigen::Vector2i& size, const Eigen::Vector2f& offset)
00096 : mapArray(0)
00097 , lastUpdateIndex(-1)
00098 {
00099 Eigen::Vector2i newMapDimensions (size);
00100
00101 this->setMapGridSize(newMapDimensions);
00102 sizeX = size[0];
00103
00104 setMapTransformation(offset, mapResolution);
00105
00106 this->clear();
00107 }
00108
00112 virtual ~GridMapBase()
00113 {
00114 deleteArray();
00115 }
00116
00120 void allocateArray(const Eigen::Vector2i& newMapDims)
00121 {
00122 int sizeX = newMapDims.x();
00123 int sizeY = newMapDims.y();
00124
00125 mapArray = new ConcreteCellType [sizeX*sizeY];
00126
00127 mapDimensionProperties.setMapCellDims(newMapDims);
00128 }
00129
00130 void deleteArray()
00131 {
00132 if (mapArray != 0){
00133
00134 delete[] mapArray;
00135
00136 mapArray = 0;
00137 mapDimensionProperties.setMapCellDims(Eigen::Vector2i(-1,-1));
00138 }
00139 }
00140
00141 ConcreteCellType& getCell(int x, int y)
00142 {
00143 return mapArray[y * sizeX + x];
00144 }
00145
00146 const ConcreteCellType& getCell(int x, int y) const
00147 {
00148 return mapArray[y * sizeX + x];
00149 }
00150
00151 ConcreteCellType& getCell(int index)
00152 {
00153 return mapArray[index];
00154 }
00155
00156 const ConcreteCellType& getCell(int index) const
00157 {
00158 return mapArray[index];
00159 }
00160
00161 void setMapGridSize(const Eigen::Vector2i& newMapDims)
00162 {
00163 if (newMapDims != mapDimensionProperties.getMapDimensions() ){
00164 deleteArray();
00165 allocateArray(newMapDims);
00166 this->reset();
00167 }
00168 }
00169
00173 GridMapBase(const GridMapBase& other)
00174 {
00175 allocateArray(other.getMapDimensions());
00176 *this = other;
00177 }
00178
00182 GridMapBase& operator=(const GridMapBase& other)
00183 {
00184 if ( !(this->mapDimensionProperties == other.mapDimensionProperties)){
00185 this->setMapGridSize(other.mapDimensionProperties.getMapDimensions());
00186 }
00187
00188 this->mapDimensionProperties = other.mapDimensionProperties;
00189
00190 this->worldTmap = other.worldTmap;
00191 this->mapTworld = other.mapTworld;
00192 this->worldTmap3D = other.worldTmap3D;
00193
00194 this->scaleToMap = other.scaleToMap;
00195
00196
00197 int sizeX = this->getSizeX();
00198 int sizeY = this->getSizeY();
00199
00200 size_t concreteCellSize = sizeof(ConcreteCellType);
00201
00202 memcpy(this->mapArray, other.mapArray, sizeX*sizeY*concreteCellSize);
00203
00204 return *this;
00205 }
00206
00210 inline Eigen::Vector2f getWorldCoords(const Eigen::Vector2f& mapCoords) const
00211 {
00212 return worldTmap * mapCoords;
00213 }
00214
00218 inline Eigen::Vector2f getMapCoords(const Eigen::Vector2f& worldCoords) const
00219 {
00220 return mapTworld * worldCoords;
00221 }
00222
00226 inline Eigen::Vector3f getWorldCoordsPose(const Eigen::Vector3f& mapPose) const
00227 {
00228 Eigen::Vector2f worldCoords (worldTmap * mapPose.head<2>());
00229 return Eigen::Vector3f(worldCoords[0], worldCoords[1], mapPose[2]);
00230 }
00231
00235 inline Eigen::Vector3f getMapCoordsPose(const Eigen::Vector3f& worldPose) const
00236 {
00237 Eigen::Vector2f mapCoords (mapTworld * worldPose.head<2>());
00238 return Eigen::Vector3f(mapCoords[0], mapCoords[1], worldPose[2]);
00239 }
00240
00241 void setDimensionProperties(const Eigen::Vector2f& topLeftOffsetIn, const Eigen::Vector2i& mapDimensionsIn, float cellLengthIn)
00242 {
00243 setDimensionProperties(MapDimensionProperties(topLeftOffsetIn,mapDimensionsIn,cellLengthIn));
00244 }
00245
00246 void setDimensionProperties(const MapDimensionProperties& newMapDimProps)
00247 {
00248
00249 if (!newMapDimProps.hasEqualDimensionProperties(this->mapDimensionProperties)){
00250 this->setMapGridSize(newMapDimProps.getMapDimensions());
00251 }
00252
00253
00254 if(!newMapDimProps.hasEqualTransformationProperties(this->mapDimensionProperties)){
00255 this->setMapTransformation(newMapDimProps.getTopLeftOffset(), newMapDimProps.getCellLength());
00256 }
00257 }
00258
00265 void setMapTransformation(const Eigen::Vector2f& topLeftOffset, float cellLength)
00266 {
00267 mapDimensionProperties.setCellLength(cellLength);
00268 mapDimensionProperties.setTopLeftOffset(topLeftOffset);
00269
00270 scaleToMap = 1.0f / cellLength;
00271
00272 mapTworld = Eigen::AlignedScaling2f(scaleToMap, scaleToMap) * Eigen::Translation2f(topLeftOffset[0], topLeftOffset[1]);
00273
00274 worldTmap3D = Eigen::AlignedScaling3f(scaleToMap, scaleToMap, 1.0f) * Eigen::Translation3f(topLeftOffset[0], topLeftOffset[1], 0);
00275
00276
00277 worldTmap3D = worldTmap3D.inverse();
00278
00279 worldTmap = mapTworld.inverse();
00280 }
00281
00282
00287 float getScaleToMap() const
00288 {
00289 return scaleToMap;
00290 }
00291
00296 float getCellLength() const
00297 {
00298 return mapDimensionProperties.getCellLength();
00299 }
00300
00305 const Eigen::Affine2f& getWorldTmap() const
00306 {
00307 return worldTmap;
00308 }
00309
00314 const Eigen::Affine3f& getWorldTmap3D() const
00315 {
00316 return worldTmap3D;
00317 }
00318
00323 const Eigen::Affine2f& getMapTworld() const
00324 {
00325 return mapTworld;
00326 }
00327
00328 void setUpdated() { lastUpdateIndex++; };
00329 int getUpdateIndex() const { return lastUpdateIndex; };
00330
00334 bool getMapExtends(int& xMax, int& yMax, int& xMin, int& yMin) const
00335 {
00336 int lowerStart = -1;
00337 int upperStart = 10000;
00338
00339 int xMaxTemp = lowerStart;
00340 int yMaxTemp = lowerStart;
00341 int xMinTemp = upperStart;
00342 int yMinTemp = upperStart;
00343
00344 int sizeX = this->getSizeX();
00345 int sizeY = this->getSizeY();
00346
00347 for (int x = 0; x < sizeX; ++x) {
00348 for (int y = 0; y < sizeY; ++y) {
00349 if (this->mapArray[x][y].getValue() != 0.0f) {
00350
00351 if (x > xMaxTemp) {
00352 xMaxTemp = x;
00353 }
00354
00355 if (x < xMinTemp) {
00356 xMinTemp = x;
00357 }
00358
00359 if (y > yMaxTemp) {
00360 yMaxTemp = y;
00361 }
00362
00363 if (y < yMinTemp) {
00364 yMinTemp = y;
00365 }
00366 }
00367 }
00368 }
00369
00370 if ((xMaxTemp != lowerStart) &&
00371 (yMaxTemp != lowerStart) &&
00372 (xMinTemp != upperStart) &&
00373 (yMinTemp != upperStart)) {
00374
00375 xMax = xMaxTemp;
00376 yMax = yMaxTemp;
00377 xMin = xMinTemp;
00378 yMin = yMinTemp;
00379 return true;
00380 } else {
00381 return false;
00382 }
00383 }
00384
00385 protected:
00386
00387 ConcreteCellType *mapArray;
00388
00389 float scaleToMap;
00390
00391 Eigen::Affine2f worldTmap;
00392 Eigen::Affine3f worldTmap3D;
00393 Eigen::Affine2f mapTworld;
00394
00395 MapDimensionProperties mapDimensionProperties;
00396 int sizeX;
00397
00398 private:
00399 int lastUpdateIndex;
00400 };
00401
00402 }
00403
00404 #endif