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 #ifndef NDT_CELL_HH
00036 #define NDT_CELL_HH
00037
00038 #include <ndt_map/impl/EventCounterData.hpp>
00039 #include <pcl/point_cloud.h>
00040 #include <pcl/point_types.h>
00041 #include <vector>
00042 #include <cstdio>
00043 #include <fstream>
00044
00045 #include <Eigen/Eigen>
00046
00050 #define CELL_UPDATE_MODE_COVARIANCE_INTERSECTION 0
00051
00052 #define CELL_UPDATE_MODE_SAMPLE_VARIANCE 1
00053
00054 #define CELL_UPDATE_MODE_ERROR_REFINEMENT 2
00055
00056 #define CELL_UPDATE_MODE_SAMPLE_VARIANCE_SURFACE_ESTIMATION 3
00057
00058 #define CELL_UPDATE_MODE_STUDENT_T 4
00059
00060 #define REFACTORED
00061
00062 #define JFFERR(x) std::cerr << x << std::endl; return -1;
00063 #define _JFFVERSION_ "#JFF V0.50"
00064
00065
00066 namespace lslgeneric
00067 {
00068
00074
00075 class NDTCell
00076 {
00077 public:
00078 bool hasGaussian_;
00079 double cost;
00080 char isEmpty;
00081 double consistency_score;
00082 enum CellClass {HORIZONTAL=0, VERTICAL, INCLINED, ROUGH, UNKNOWN};
00083 std::vector<pcl::PointXYZ,Eigen::aligned_allocator<pcl::PointXYZ> > points_;
00084
00085 NDTCell()
00086 {
00087 hasGaussian_ = false;
00088 if(!parametersSet_)
00089 {
00090 setParameters();
00091 }
00092 N = 0;
00093 R = 0;
00094 G = 0;
00095 B = 0;
00096 occ = 0;
00097 emptyval = 0;
00098 isEmpty=0;
00099 emptylik = 0;
00100 emptydist = 0;
00101 max_occu_ = 1;
00102 consistency_score=0;
00103 cost=INT_MAX;
00104 }
00105
00106 virtual ~NDTCell()
00107 {
00108 points_.clear();
00109 }
00110
00111 NDTCell(pcl::PointXYZ ¢er, double &xsize, double &ysize, double &zsize)
00112 {
00113 center_ = center;
00114 xsize_ = xsize;
00115 ysize_ = ysize;
00116 zsize_ = zsize;
00117 hasGaussian_ = false;
00118 N = 0;
00119 R = 0;
00120 G = 0;
00121 B = 0;
00122 occ = 0;
00123 emptyval = 0;
00124 isEmpty = 0;
00125 emptylik = 0;
00126 emptydist = 0;
00127 if(!parametersSet_)
00128 {
00129 setParameters();
00130 }
00131 consistency_score=0;
00132 cost=INT_MAX;
00133 }
00134
00135 NDTCell(const NDTCell& other)
00136 {
00137 this->center_ = other.center_;
00138 this->xsize_ = other.xsize_;
00139 this->ysize_ = other.ysize_;
00140 this->zsize_ = other.zsize_;
00141 this->hasGaussian_ = other.hasGaussian_;
00142 this->R = other.R;
00143 this->G = other.G;
00144 this->B = other.B;
00145 this->N = other.N;
00146 this->occ = other.occ;
00147 this->emptyval = other.emptyval;
00148 this->edata = other.edata;
00149 this->consistency_score=other.consistency_score;
00150 this->isEmpty = other.isEmpty;
00151 if(this->hasGaussian_) {
00152 this->setMean(other.getMean());
00153 this->setCov(other.getCov());
00154 }
00155 this->cost=other.cost;
00156 }
00157
00158 virtual NDTCell* clone() const;
00159 virtual NDTCell* copy() const;
00160
00161 inline void setCenter(const pcl::PointXYZ &cn)
00162 {
00163 center_ = cn;
00164 }
00165 inline void setDimensions(const double &xs, const double &ys, const double &zs)
00166 {
00167 xsize_ = xs;
00168 ysize_ = ys;
00169 zsize_ = zs;
00170 }
00171
00172 inline pcl::PointXYZ getCenter() const
00173 {
00174 return center_;
00175 }
00176 inline void getDimensions(double &xs, double &ys, double &zs) const
00177 {
00178 xs = xsize_;
00179 ys = ysize_;
00180 zs = zsize_;
00181 }
00182 inline bool isInside(const pcl::PointXYZ pt) const
00183 {
00184 if(pt.x < center_.x-xsize_/2 || pt.x > center_.x+xsize_/2)
00185 {
00186 return false;
00187 }
00188 if(pt.y < center_.y-ysize_/2 || pt.y > center_.y+ysize_/2)
00189 {
00190 return false;
00191 }
00192 if(pt.z < center_.z-zsize_/2 || pt.z > center_.z+zsize_/2)
00193 {
00194 return false;
00195 }
00196 return true;
00197 }
00198 virtual double getDiagonal() const
00199 {
00200 return std::sqrt(xsize_*xsize_+ysize_*ysize_+zsize_*zsize_);
00201 }
00208 void updateSampleVariance(const Eigen::Matrix3d &cov2,const Eigen::Vector3d &m2, unsigned int numpointsindistribution,
00209 bool updateOccupancyFlag=true, float max_occu=1024, unsigned int maxnumpoints=1e9);
00210
00224 void computeGaussian(int mode=CELL_UPDATE_MODE_SAMPLE_VARIANCE, unsigned int maxnumpoints=1e9, float occupancy_limit=255, Eigen::Vector3d origin = Eigen::Vector3d(0,0,0), double sensor_noise=0.1);
00225
00229 void computeGaussianSimple();
00233 void updateColorInformation();
00234
00235
00236 void rescaleCovariance();
00242 bool rescaleCovariance(Eigen::Matrix3d &cov, Eigen::Matrix3d &invCov);
00243
00244
00245 void classify();
00246
00247 int writeToJFF(FILE * jffout);
00248 int loadFromJFF(FILE * jffin);
00249
00250 inline CellClass getClass() const
00251 {
00252 return cl_;
00253 }
00254 inline Eigen::Matrix3d getCov() const
00255 {
00256 return cov_;
00257 }
00258 inline Eigen::Matrix3d getInverseCov() const
00259 {
00260 return icov_;
00261 }
00262 inline Eigen::Vector3d getMean() const
00263 {
00264 return mean_;
00265 }
00266 inline Eigen::Matrix3d getEvecs() const
00267 {
00268 return evecs_;
00269 }
00270 inline Eigen::Vector3d getEvals() const
00271 {
00272 return evals_;
00273 }
00274
00275
00276 void setCov(const Eigen::Matrix3d &cov);
00277
00278 inline void setMean(const Eigen::Vector3d &mean)
00279 {
00280 mean_ = mean;
00281 }
00282 inline void setEvals(const Eigen::Vector3d &ev)
00283 {
00284 evals_ = ev;
00285 }
00286
00287
00288
00290 static void setParameters(double _EVAL_ROUGH_THR =0.1,
00291 double _EVEC_INCLINED_THR=8*M_PI/18,
00292 double _EVAL_FACTOR =100);
00296 double getLikelihood(const pcl::PointXYZ &pt) const;
00297
00302 virtual void addPoint(pcl::PointXYZ &pt)
00303 {
00304 points_.push_back(pt);
00305 }
00306
00307 virtual void addPoints(pcl::PointCloud<pcl::PointXYZ> &pt)
00308 {
00309 points_.insert(points_.begin(),pt.points.begin(),pt.points.end());
00310 }
00311
00313 void setRGB(float r, float g, float b)
00314 {
00315 R=r;
00316 G = g;
00317 B = b;
00318 }
00319 void getRGB(float &r, float &g, float &b)
00320 {
00321 r = R;
00322 g = G;
00323 b = B;
00324 }
00325
00330 void updateOccupancy(float occ_val, float max_occu=255.0)
00331 {
00332 occ+=occ_val;
00333 if(occ>max_occu) occ = max_occu;
00334 if(occ<-max_occu) occ = -max_occu;
00335 max_occu_= max_occu;
00336 }
00337
00341 float getOccupancy()
00342 {
00343 return occ;
00344 }
00348 float getOccupancyRescaled()
00349 {
00350 float occupancy = 1 - 1/(1+exp(occ));
00351 return occupancy > 1 ? 1 : (occupancy < 0 ? 0 : occupancy);
00352 }
00353
00354 void updateEmpty(double elik, double dist)
00355 {
00356 emptyval++;
00357 emptylik+=elik;
00358 emptydist+=dist;
00359 }
00360
00361 float getDynamicLikelihood(unsigned int N)
00362 {
00363 return edata.computeSemiStaticLikelihood(N);
00364 }
00365 void setOccupancy(float occ_)
00366 {
00367 occ = occ_;
00368 }
00369 void setEmptyval(int emptyval_)
00370 {
00371 emptyval=emptyval_;
00372 }
00373 void setEventData(TEventData _ed)
00374 {
00375 edata = _ed;
00376 }
00377 int getEmptyval()
00378 {
00379 return emptyval;
00380 }
00381 TEventData getEventData()
00382 {
00383 return edata;
00384 }
00385 void setN(int N_)
00386 {
00387 N = N_;
00388 }
00389 int getN()
00390 {
00391 return N;
00392 }
00404 double computeMaximumLikelihoodAlongLine(const pcl::PointXYZ &p1, const pcl::PointXYZ &p2, Eigen::Vector3d &out);
00405
00406 private:
00407 pcl::PointXYZ center_;
00408 double xsize_, ysize_, zsize_;
00409 Eigen::Matrix3d cov_;
00410 Eigen::Matrix3d icov_;
00411 Eigen::Matrix3d evecs_;
00412 Eigen::Vector3d mean_;
00413 Eigen::Vector3d evals_;
00414 CellClass cl_;
00415 static bool parametersSet_;
00416 static double EVAL_ROUGH_THR;
00417 static double EVEC_INCLINED_THR;
00418 static double EVAL_FACTOR;
00419 double d1_,d2_;
00420 unsigned int N;
00421 int emptyval;
00422 double emptylik;
00423 double emptydist;
00424 float R,G,B;
00425 float occ;
00426 float max_occu_;
00427 TEventData edata;
00428
00432 void studentT();
00433
00434 double squareSum(const Eigen::Matrix3d &C,const Eigen::Vector3d &x){
00435 double sum;
00436 sum = C(0,0)*x(0)*x(0) + C(1,1)*x(1)*x(1) + C(2,2)*x(2)*x(2);
00437 sum += 2.0*C(0,1)*x(0)*x(1) + 2.0*C(0,2)*x(0)*x(2) + 2.0*C(1,2)*x(1)*x(2);
00438 return sum;
00439 }
00440
00441
00442 void writeJFFMatrix(FILE * jffout, Eigen::Matrix3d &mat);
00443 void writeJFFVector(FILE * jffout, Eigen::Vector3d &vec);
00444 void writeJFFEventData(FILE * jffout, TEventData &evdata);
00445 int loadJFFMatrix(FILE * jffin, Eigen::Matrix3d &mat);
00446 int loadJFFVector(FILE * jffin, Eigen::Vector3d &vec);
00447 int loadJFFEventData(FILE * jffin, TEventData &evdata);
00448
00449 public:
00450 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00451
00452 };
00453 };
00454
00455
00456
00457 #endif