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 __OccGridMapBase_h_
00030 #define __OccGridMapBase_h_
00031
00032 #include "GridMapBase.h"
00033
00034 #include "../scan/DataPointContainer.h"
00035 #include "../util/UtilFunctions.h"
00036
00037 #include <Eigen/Geometry>
00038
00039 namespace hectorslam {
00040
00041 template<typename ConcreteCellType, typename ConcreteGridFunctions>
00042 class OccGridMapBase
00043 : public GridMapBase<ConcreteCellType>
00044 {
00045
00046 public:
00047
00048 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00049
00050 OccGridMapBase(float mapResolution, const Eigen::Vector2i& size, const Eigen::Vector2f& offset)
00051 : GridMapBase<ConcreteCellType>(mapResolution, size, offset)
00052 , currUpdateIndex(0)
00053 , currMarkOccIndex(-1)
00054 , currMarkFreeIndex(-1)
00055 {}
00056
00057 virtual ~OccGridMapBase() {}
00058
00059 void updateSetOccupied(int index)
00060 {
00061 concreteGridFunctions.updateSetOccupied(this->getCell(index));
00062 }
00063
00064 void updateSetFree(int index)
00065 {
00066 concreteGridFunctions.updateSetFree(this->getCell(index));
00067 }
00068
00069 void updateUnsetFree(int index)
00070 {
00071 concreteGridFunctions.updateUnsetFree(this->getCell(index));
00072 }
00073
00074 float getGridProbabilityMap(int index) const
00075 {
00076 return concreteGridFunctions.getGridProbability(this->getCell(index));
00077 }
00078
00079 bool isOccupied(int xMap, int yMap) const
00080 {
00081 return (this->getCell(xMap,yMap).isOccupied());
00082 }
00083
00084 bool isFree(int xMap, int yMap) const
00085 {
00086 return (this->getCell(xMap,yMap).isFree());
00087 }
00088
00089 bool isOccupied(int index) const
00090 {
00091 return (this->getCell(index).isOccupied());
00092 }
00093
00094 bool isFree(int index) const
00095 {
00096 return (this->getCell(index).isFree());
00097 }
00098
00099 float getObstacleThreshold() const
00100 {
00101 ConcreteCellType temp;
00102 temp.resetGridCell();
00103 return concreteGridFunctions.getGridProbability(temp);
00104 }
00105
00106 void setUpdateFreeFactor(float factor)
00107 {
00108 concreteGridFunctions.setUpdateFreeFactor(factor);
00109 }
00110
00111 void setUpdateOccupiedFactor(float factor)
00112 {
00113 concreteGridFunctions.setUpdateOccupiedFactor(factor);
00114 }
00115
00121 void updateByScan(const DataContainer& dataContainer, const Eigen::Vector3f& robotPoseWorld)
00122 {
00123 currMarkFreeIndex = currUpdateIndex + 1;
00124 currMarkOccIndex = currUpdateIndex + 2;
00125
00126
00127 Eigen::Vector3f mapPose(this->getMapCoordsPose(robotPoseWorld));
00128
00129
00130 Eigen::Affine2f poseTransform((Eigen::Translation2f(
00131 mapPose[0], mapPose[1]) * Eigen::Rotation2Df(mapPose[2])));
00132
00133
00134 Eigen::Vector2f scanBeginMapf(poseTransform * dataContainer.getOrigo());
00135
00136
00137 Eigen::Vector2i scanBeginMapi(scanBeginMapf[0] + 0.5f, scanBeginMapf[1] + 0.5f);
00138
00139
00140 int numValidElems = dataContainer.getSize();
00141
00142
00143
00144
00145 for (int i = 0; i < numValidElems; ++i) {
00146
00147
00148 Eigen::Vector2f scanEndMapf(poseTransform * (dataContainer.getVecEntry(i)));
00149
00150
00151
00152 scanEndMapf.array() += (0.5f);
00153
00154
00155 Eigen::Vector2i scanEndMapi(scanEndMapf.cast<int>());
00156
00157
00158 if (scanBeginMapi != scanEndMapi){
00159 updateLineBresenhami(scanBeginMapi, scanEndMapi);
00160 }
00161 }
00162
00163
00164 this->setUpdated();
00165
00166
00167 currUpdateIndex += 3;
00168 }
00169
00170 inline void updateLineBresenhami( const Eigen::Vector2i& beginMap, const Eigen::Vector2i& endMap, unsigned int max_length = UINT_MAX){
00171
00172 int x0 = beginMap[0];
00173 int y0 = beginMap[1];
00174
00175
00176 if ((x0 < 0) || (x0 >= this->getSizeX()) || (y0 < 0) || (y0 >= this->getSizeY())) {
00177 return;
00178 }
00179
00180 int x1 = endMap[0];
00181 int y1 = endMap[1];
00182
00183
00184
00185
00186 if ((x1 < 0) || (x1 >= this->getSizeX()) || (y1 < 0) || (y1 >= this->getSizeY())) {
00187 return;
00188 }
00189
00190 int dx = x1 - x0;
00191 int dy = y1 - y0;
00192
00193 unsigned int abs_dx = abs(dx);
00194 unsigned int abs_dy = abs(dy);
00195
00196 int offset_dx = util::sign(dx);
00197 int offset_dy = util::sign(dy) * this->sizeX;
00198
00199 unsigned int startOffset = beginMap.y() * this->sizeX + beginMap.x();
00200
00201
00202 if(abs_dx >= abs_dy){
00203 int error_y = abs_dx / 2;
00204 bresenham2D(abs_dx, abs_dy, error_y, offset_dx, offset_dy, startOffset);
00205 }else{
00206
00207 int error_x = abs_dy / 2;
00208 bresenham2D(abs_dy, abs_dx, error_x, offset_dy, offset_dx, startOffset);
00209 }
00210
00211 unsigned int endOffset = endMap.y() * this->sizeX + endMap.x();
00212 this->bresenhamCellOcc(endOffset);
00213
00214 }
00215
00216 inline void bresenhamCellFree(unsigned int offset)
00217 {
00218 ConcreteCellType& cell (this->getCell(offset));
00219
00220 if (cell.updateIndex < currMarkFreeIndex) {
00221 concreteGridFunctions.updateSetFree(cell);
00222 cell.updateIndex = currMarkFreeIndex;
00223 }
00224 }
00225
00226 inline void bresenhamCellOcc(unsigned int offset)
00227 {
00228 ConcreteCellType& cell (this->getCell(offset));
00229
00230 if (cell.updateIndex < currMarkOccIndex) {
00231
00232
00233 if (cell.updateIndex == currMarkFreeIndex) {
00234 concreteGridFunctions.updateUnsetFree(cell);
00235 }
00236
00237 concreteGridFunctions.updateSetOccupied(cell);
00238
00239 cell.updateIndex = currMarkOccIndex;
00240 }
00241 }
00242
00243 inline void bresenham2D( unsigned int abs_da, unsigned int abs_db, int error_b, int offset_a, int offset_b, unsigned int offset){
00244
00245 this->bresenhamCellFree(offset);
00246
00247 unsigned int end = abs_da-1;
00248
00249 for(unsigned int i = 0; i < end; ++i){
00250 offset += offset_a;
00251 error_b += abs_db;
00252
00253 if((unsigned int)error_b >= abs_da){
00254 offset += offset_b;
00255 error_b -= abs_da;
00256 }
00257
00258 this->bresenhamCellFree(offset);
00259 }
00260 }
00261
00262 protected:
00263
00264 ConcreteGridFunctions concreteGridFunctions;
00265 int currUpdateIndex;
00266 int currMarkOccIndex;
00267 int currMarkFreeIndex;
00268 };
00269
00270
00271 }
00272
00273 #endif