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