ndt_map.hpp
Go to the documentation of this file.
00001 #include <Eigen/Eigen>
00002 #include <pcl/point_cloud.h>
00003 #include <pcl/features/feature.h>
00004 
00005 #include <string>
00006 #include <climits>
00007 
00008 #include <oc_tree.h>
00009 #include <lazy_grid.h>
00010 #include <cell_vector.h>
00011 
00012 #include <cstring>
00013 #include <cstdio>
00014 
00015 #define _JFFVERSION_ "#JFF V0.50"
00016 #define JFFERR(x) std::cerr << x << std::endl; return -1;
00017 
00018 namespace lslgeneric
00019 {
00020 
00030 template<typename PointT>
00031 void NDTMap<PointT>::loadPointCloud(const pcl::PointCloud<PointT> &pc, double range_limit)
00032 {
00033     if(index_ != NULL)
00034     {
00035         //std::cout<<"CLONE INDEX\n";
00036         SpatialIndex<PointT> *si = index_->clone();
00037         //cout<<"allocating index\n";
00038         if(!isFirstLoad_)
00039         {
00040             //std::cout<<"deleting old index\n";
00041             delete index_;
00042         }
00043         isFirstLoad_ = false;
00044         index_ = si;
00045     }
00046     else
00047     {
00048         //NULL index in constructor, abort!
00049         //ERR("constructor must specify a non-NULL spatial index\n");
00050         return;
00051     }
00052     
00053     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00054     if(lz == NULL)
00055     {
00056         fprintf(stderr,"Unfortunately This works only with Lazygrid!\n");
00057         exit(1);
00058     }
00059 
00060     if(index_ == NULL)
00061     {
00062         //ERR("Problem creating index, unimplemented method\n");
00063         return;
00064     }
00065 
00066     typename pcl::PointCloud<PointT>::const_iterator it = pc.points.begin();
00067     if(guess_size_) 
00068     {
00069         double maxDist = 0;//, distCeil = 200;
00070 
00071         Eigen::Vector3d centroid(0,0,0);
00072         int npts = 0;
00073         while(it!=pc.points.end())
00074         {
00075             Eigen::Vector3d d;
00076             if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00077             {
00078                 it++;
00079                 continue;
00080             }
00081             d << it->x, it->y, it->z;
00082             if(range_limit>0)
00083             {
00084                 if(d.norm()>range_limit)
00085                 {
00086                     it++;
00087                     continue;
00088                 }
00089             }
00090             centroid += d;
00091             it++;
00092             npts++;
00093         }
00094 
00095         centroid /= (double)npts;
00096         double maxz=-1000, minz=10000;
00097         //Eigen::Vector4f centroid(0,0,0,0);
00098         //pcl::compute3DCentroid(pc,centroid);
00099 
00100         //compute distance to furthest point
00101         it = pc.points.begin();
00102         while(it!=pc.points.end())
00103         {
00104             Eigen::Vector3d d;
00105             if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00106             {
00107                 it++;
00108                 continue;
00109             }
00110             if(range_limit>0)
00111             {
00112                 d << it->x, it->y, it->z;
00113                 if(d.norm()>range_limit)
00114                 {
00115                     it++;
00116                     continue;
00117                 }
00118             }
00119             d << centroid(0)-it->x, centroid(1)-it->y, centroid(2)-it->z;
00120             double dist = d.norm();
00121             maxDist = (dist > maxDist) ? dist : maxDist;
00122             maxz = ((centroid(2)-it->z) > maxz) ? (centroid(2)-it->z) : maxz;
00123             minz = ((centroid(2)-it->z) < minz) ? (centroid(2)-it->z) : minz;
00124             it++;
00125         }
00126         // cout<<"Points = " <<pc.points.size()<<" maxDist = "<<maxDist<<endl;
00127         NDTCell<PointT> *ptCell = new NDTCell<PointT>();
00128         index_->setCellType(ptCell);
00129         delete ptCell;
00130         index_->setCenter(centroid(0),centroid(1),centroid(2));
00131 
00132         if(map_sizex >0 && map_sizey >0 && map_sizez >0)
00133         {
00134             index_->setSize(map_sizex,map_sizey,map_sizez);
00135         }
00136         else
00137         {
00138             index_->setSize(4*maxDist,4*maxDist,3*(maxz-minz));
00139         }
00140     }
00141     else
00142     {
00143         //set sizes
00144         NDTCell<PointT> *ptCell = new NDTCell<PointT>();
00145         index_->setCellType(ptCell);
00146         delete ptCell;
00147         index_->setCenter(centerx,centery,centerz);
00148         if(map_sizex >0 && map_sizey >0 && map_sizez >0)
00149         {
00150             index_->setSize(map_sizex,map_sizey,map_sizez);
00151         }
00152     }
00153 
00154     //    ROS_INFO("centroid is %f,%f,%f", centroid(0),centroid(1),centroid(2));
00155     //    ROS_INFO("maxDist is %lf", maxDist);
00156 
00157     it = pc.points.begin();
00158     while(it!=pc.points.end())
00159     {
00160         Eigen::Vector3d d;
00161         if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00162         {
00163             it++;
00164             continue;
00165         }
00166         if(range_limit>0)
00167         {
00168             d << it->x, it->y, it->z;
00169             if(d.norm()>range_limit)
00170             {
00171                 it++;
00172                 continue;
00173             }
00174         }
00175         index_->addPoint(*it);
00176         NDTCell<PointT> *ptCell;
00177         lz->getNDTCellAt(*it,ptCell);
00178 #ifdef REFACTORED
00179         if(ptCell!=NULL) {
00180         //    std::cerr<<"adding to update set\n";
00181             update_set.insert(ptCell);
00182         }
00183 #endif
00184         it++;
00185     }
00186 
00187     isFirstLoad_ = false;
00188 }
00189 
00190 
00196 template<typename PointT>
00197 void NDTMap<PointT>::loadPointCloudCentroid(const pcl::PointCloud<PointT> &pc, const Eigen::Vector3d &origin,
00198                                                                                                                                                                                 const Eigen::Vector3d &old_centroid,const Eigen::Vector3d &map_size, double range_limit){
00199     if(index_ != NULL){
00200         SpatialIndex<PointT> *si = index_->clone();
00201         if(!isFirstLoad_) delete index_;
00202         
00203         isFirstLoad_ = false;
00204         index_ = si;
00205     }
00206     else{
00207         return;
00208     }
00209 
00210     if(index_ == NULL) return; 
00211 
00212     NDTCell<PointT> *ptCell = new NDTCell<PointT>();
00213     index_->setCellType(ptCell);
00214     delete ptCell;
00215 
00216     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00217     if(lz == NULL)
00218     {
00219         fprintf(stderr,"Unfortunately This works only with Lazygrid!\n");
00220         exit(1);
00221     }
00222 
00223     Eigen::Vector3d diff = origin - old_centroid;  //-origin;
00224     double cx=0, cy=0, cz=0;
00225     lz->getCellSize(cx, cy, cz);
00226 
00228     Eigen::Vector3d centroid;
00229     centroid(0) = old_centroid(0) + floor(diff(0) / cx) * cx;
00230     centroid(1) = old_centroid(1) + floor(diff(1) / cy) * cy;
00231     centroid(2) = old_centroid(2) + floor(diff(2) / cz) * cz;
00232 
00233     index_->setCenter(centroid(0),centroid(1),centroid(2));
00234     //index_->setCenter(origin(0),origin(1),origin(2));
00235     index_->setSize(map_size(0),map_size(1),map_size(2));
00236     //lz->initializeAll();
00237 
00238     //fprintf(stderr,"centroid is %lf,%lf,%lf (origin: %lf %lf %lf) (map_size %lf %lf %lf) N=%d", centroid(0),centroid(1),centroid(2), origin(0),origin(1),origin(2), map_size(0), map_size(1), map_size(2),pc.size());
00239     //ROS_INFO("centroid is %f,%f,%f", centroid(0),centroid(1),centroid(2));
00240     //ROS_INFO("maxDist is %lf", maxDist);
00241 
00242     typename pcl::PointCloud<PointT>::const_iterator it = pc.points.begin();
00243 
00244     while(it!=pc.points.end())
00245     {
00246         Eigen::Vector3d d;
00247         if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00248         {
00249             it++;
00250             continue;
00251         }
00252         
00253         if(range_limit>0)
00254         {
00255             d << it->x, it->y, it->z;
00256             d = d-origin;
00257             if(d.norm()>range_limit)
00258             {
00259                 it++;
00260                 continue;
00261             }
00262         }
00263         
00264         //fprintf(stderr,"HEP!");
00265         index_->addPoint(*it);
00266         NDTCell<PointT> *ptCell=NULL;
00267         lz->getNDTCellAt(*it,ptCell);
00268 #ifdef REFACTORED
00269         if(ptCell!=NULL) update_set.insert(ptCell);
00270 #endif
00271         it++;
00272     }
00273 
00274     isFirstLoad_ = false;
00275 }
00276 
00277 
00278 
00282 template<typename PointT>
00283 void NDTMap<PointT>::addPointCloudSimple(const pcl::PointCloud<PointT> &pc,double maxz)
00284 {
00285     if(isFirstLoad_)
00286     {
00287         loadPointCloud( pc);
00288         return;
00289     }
00290 
00291     typename pcl::PointCloud<PointT>::const_iterator it = pc.points.begin();
00292     it = pc.points.begin();
00293     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00294     if(lz == NULL)
00295     {
00296         fprintf(stderr,"Unfortunately This works only with Lazygrid!\n");
00297         exit(1);
00298     }
00299 
00300     while(it!=pc.points.end())
00301     {
00302         if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00303         {
00304             it++;
00305             continue;
00306         }
00307         if(it->z>maxz)
00308         {
00309             it++;
00310             continue;
00311         }
00312         index_->addPoint(*it);
00313         NDTCell<PointT> *ptCell;
00314         lz->getNDTCellAt(*it,ptCell);
00315 #ifdef REFACTORED
00316         if(ptCell!=NULL) update_set.insert(ptCell);
00317 #endif
00318         it++;
00319     }
00320 
00321 }
00322 
00326 template<typename PointT>
00327 void NDTMap<PointT>::addDistributionToCell(const Eigen::Matrix3d &ucov, const Eigen::Vector3d &umean, unsigned int numpointsindistribution, 
00328                                                                                                                                                                          float r, float g,float b,  unsigned int maxnumpoints, float max_occupancy)
00329 {
00330     PointT pt;
00331     pt.x = umean[0];
00332     pt.y = umean[1];
00333     pt.z = umean[2];
00334     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00335     if(lz==NULL)
00336     {
00337         fprintf(stderr,"NOT LAZY GRID!!!\n");
00338         exit(1);
00339     }
00340     NDTCell<PointT> *ptCell = NULL; //= dynamic_cast<NDTCell<PointT> *>(lz->getCellAt(pt));
00341     lz->getNDTCellAt(pt,ptCell);
00342     if(ptCell != NULL)
00343     {
00344         //std::cout<<"BEFORE\n";
00345         //std::cout<<"had G "<<ptCell->hasGaussian_<<" occ "<<ptCell->getOccupancy()<<std::endl;
00346 //      std::cout<<umean.transpose()<<" "<<numpointsindistribution <<std::endl;
00347 //      std::cout<<ucov<<std::endl;
00348 //      std::cout<<ptCell->getMean().transpose()<<std::endl;
00349 //      std::cout<<ptCell->getCov()<<std::endl;
00350         ptCell->updateSampleVariance(ucov, umean, numpointsindistribution, true, max_occupancy,maxnumpoints);
00351         ptCell->setRGB(r,g,b);
00352 //      std::cout<<"AFTER\n";
00353 //      std::cout<<ptCell->getMean().transpose()<<std::endl;
00354 //      std::cout<<ptCell->getCov()<<std::endl;
00355     }
00356 
00357 #if 0
00358     double centerX,centerY,centerZ;
00359     lz->getCenter(centerX, centerY, centerZ);
00360     double cellSizeX,cellSizeY,cellSizeZ;
00361     lz->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
00362     int sizeX,sizeY,sizeZ;
00363     lz->getGridSize(sizeX, sizeY, sizeZ);
00364 
00365     Cell<PointT> ****dataArray = lz->getDataArrayPtr();
00366 
00367     NDTCell<PointT> *ptCell=NULL;
00368     int idx,idy,idz;
00369     idx = (int)(((pt.x - centerX)/cellSizeX+0.5) + sizeX/2);
00370     idy = (int)(((pt.y - centerY)/cellSizeY+0.5) + sizeY/2);
00371     idz = (int)(((pt.z - centerZ)/cellSizeZ+0.5) + sizeZ/2);
00372 
00373     if(idx < sizeX && idy < sizeY && idz < sizeZ && idx >=0 && idy >=0 && idz >=0)
00374     {
00375         ptCell = dynamic_cast<NDTCell<PointT> *>  (dataArray[idx][idy][idz]);
00376         if(ptCell != NULL)
00377         {
00378             ptCell->updateSampleVariance(ucov, umean, numpointsindistribution);
00379                                                 ptCell->setRGB(r,g,b);
00380             //fprintf(stderr,"I AM UPDATING (%d %d %d)!! ",idx,idy,idz);
00381         }
00382     }
00383 #endif
00384 }
00385 
00387 template<typename PointT>
00388 bool NDTMap<PointT>::getCellAtPoint(const PointT &refPoint, NDTCell<PointT> *&cell)
00389 {
00390 
00391     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00392     if(lz==NULL)
00393     {
00394         fprintf(stderr,"NOT LAZY GRID!!!\n");
00395         exit(1);
00396     }
00397     //cell = dynamic_cast<NDTCell<PointT> *>(lz->getCellAt(refPoint));
00398     lz->getNDTCellAt(refPoint,cell);
00399     return (cell != NULL);
00400 
00401 #if 0
00402     double centerX,centerY,centerZ;
00403     lz->getCenter(centerX, centerY, centerZ);
00404     double cellSizeX,cellSizeY,cellSizeZ;
00405     lz->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
00406     int sizeX,sizeY,sizeZ;
00407     lz->getGridSize(sizeX, sizeY, sizeZ);
00408 
00409     Cell<PointT> ****dataArray = lz->getDataArrayPtr();
00410 
00411     int idx,idy,idz;
00412     idx = (int)(((refPoint.x - centerX)/cellSizeX+0.5) + sizeX/2);
00413     idy = (int)(((refPoint.y - centerY)/cellSizeY+0.5) + sizeY/2);
00414     idz = (int)(((refPoint.z - centerZ)/cellSizeZ+0.5) + sizeZ/2);
00415 
00416     if(idx < sizeX && idy < sizeY && idz < sizeZ && idx >=0 && idy >=0 && idz >=0)
00417     {
00418         cell = dynamic_cast<NDTCell<PointT> *>  (dataArray[idx][idy][idz]);
00419         if(cell != NULL)
00420         {
00421             return true;
00422         }
00423         else
00424         {
00425             return false;
00426         }
00427     }
00428     return false;
00429 #endif
00430 }
00431 
00435 template<typename PointT>
00436 void NDTMap<PointT>::addPointCloud(const Eigen::Vector3d &origin, const pcl::PointCloud<PointT> &pc, double classifierTh, double maxz, 
00437                                                                                                                                         double sensor_noise, double occupancy_limit)
00438 {
00439     if(isFirstLoad_)
00440     {
00441                         loadPointCloud( pc);
00442                         return;
00443     }
00444     if(index_ == NULL)
00445     {
00446                         //ERR("Problem creating index, unimplemented method\n");
00447                         return;
00448     }
00449     typename pcl::PointCloud<PointT>::const_iterator it = pc.points.begin();
00450 
00451     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00452     if(lz==NULL)
00453     {
00454                         fprintf(stderr,"NOT LAZY GRID!!!\n");
00455                         exit(1);
00456     }
00457     PointT po, pt;
00458     po.x = origin(0); po.y = origin(1); po.z = origin(2);
00459     NDTCell<PointT>* ptCell = NULL; 
00460 
00461 #ifdef REFACTORED
00462     std::vector< NDTCell<PointT>*> cells; 
00463     bool updatePositive = true;
00464     double max_range = 200.;
00465 
00466     while(it!=pc.points.end())
00467     {
00468                         if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00469                         {
00470                                         it++;
00471                                         continue;
00472                         }
00473 
00474                         Eigen::Vector3d diff;
00475                         diff << it->x-origin(0), it->y-origin(1), it->z-origin(2);
00476                         double l = diff.norm();
00477 
00478                         if(l>max_range)
00479                         {
00480                                         fprintf(stderr,"Very long distance (%lf) :( \n",l);
00481                                         it++;
00482                                         continue;
00483                         }
00484 
00485                         cells.clear();
00486                         if(!lz->traceLine(origin,*it,diff,maxz,cells)) {
00487                                         it++;
00488                                         continue;
00489                         }
00490 
00491                         for(unsigned int i=0; i<cells.size(); i++)
00492                         {
00493                                         ptCell = cells[i];
00494                                         if(ptCell != NULL)
00495                                         {
00496                                 double l2target = 0;
00497                                 if(ptCell->hasGaussian_)
00498                                 {
00499                                                 Eigen::Vector3d out, pend,vpt;
00500                                                 pend << it->x,it->y,it->z;
00501                                                 double lik = ptCell->computeMaximumLikelihoodAlongLine(po, *it, out);
00502                                                 l2target = (out-pend).norm();
00503 
00504                                                 double dist = (origin-out).norm();
00505                                                 if(dist > l) continue; 
00506 
00507                                                 l2target = (out-pend).norm(); 
00508 
00509                                                 double sigma_dist = 0.5 * (dist/30.0); 
00510                                                 double snoise = sigma_dist + sensor_noise;
00511                                                 double thr =exp(-0.5*(l2target*l2target)/(snoise*snoise)); 
00512                                                 lik *= (1.0-thr);
00513                                                 if(lik<0.3) continue;
00514                                                 lik = 0.1*lik+0.5; 
00515                                                 double logoddlik = log( (1.0-lik)/(lik) );
00516                                                 //ptCell->updateEmpty(logoddlik,l2target);
00517                                                 //fprintf(stderr,"[E=%.2lf] ", logoddlik);
00518                                                 ptCell->updateOccupancy(logoddlik, occupancy_limit);
00519                                                 if(ptCell->getOccupancy()<=0) ptCell->hasGaussian_ = false; 
00520                                 }
00521                                 else
00522                                 {
00523                                          // ptCell->updateEmpty(-0.2,l2target); ///The cell does not have gaussian, so we mark that we saw it empty...
00524                                          ptCell->updateOccupancy(-0.2, occupancy_limit);
00525                                          if(ptCell->getOccupancy()<=0) ptCell->hasGaussian_ = false; 
00526                                 }
00527                                         }
00528                                         //update_set.insert(ptCell);
00529                         }
00530         if(updatePositive) {
00531             ptCell = dynamic_cast<NDTCell<PointT>*>(index_->addPoint(*it));
00532             if(ptCell!=NULL) {
00533                                 update_set.insert(ptCell);
00534             }
00535         }
00536         it++;
00537     }
00538     isFirstLoad_ = false;
00539 
00540 #else
00541     double centerX,centerY,centerZ;
00542     lz->getCenter(centerX, centerY, centerZ);
00543     double cellSizeX,cellSizeY,cellSizeZ;
00544     lz->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
00545     int sizeX,sizeY,sizeZ;
00546     lz->getGridSize(sizeX, sizeY, sizeZ);
00547 
00548     Cell<PointT> ****dataArray = lz->getDataArrayPtr();
00549 
00550     double min1 = std::min(cellSizeX,cellSizeY);
00551     double min2 = std::min(cellSizeZ,cellSizeY);
00552 
00553     double resolution = std::min(min1,min2); 
00554 
00555     while(it!=pc.points.end())
00556     {
00557         if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
00558         {
00559             it++;
00560             continue;
00561         }
00562         Eigen::Vector3d diff;
00563         diff << it->x-origin(0), it->y-origin(1), it->z-origin(2);
00564 
00565         double l = diff.norm();
00566         int N = l / (resolution);
00567 
00568         if(l>200)
00569         {
00570             fprintf(stderr,"Very long distance (%lf) :( \n",l);
00571             it++;
00572             continue;
00573         }
00574         if(resolution<0.01)
00575         {
00576             fprintf(stderr,"Resolution very very small (%lf) :( \n",resolution);
00577             it++;
00578             continue;
00579         }
00580 
00581 
00582         if(N <= 0)
00583         {
00584             fprintf(stderr,"N=%d (r=%lf l=%lf) :( ",N,resolution,l);
00585             it++;
00586             continue;
00587         }
00588 
00589         diff = diff/(float)N;
00590 
00591         bool updatePositive = true;
00592         if(it->z>maxz)
00593         {
00594             it++;
00595             continue;
00596         }
00597 
00598         int idxo=0, idyo=0,idzo=0;
00599         for(int i=0; i<N-1; i++)
00600         {
00601             pt.x = origin(0) + ((float)(i+1)) *diff(0);
00602             pt.y = origin(1) + ((float)(i+1)) *diff(1);
00603             pt.z = origin(2) + ((float)(i+1)) *diff(2);
00604             int idx,idy,idz;
00605 
00606             idx = (int)(((pt.x - centerX)/cellSizeX+0.5) + sizeX/2);
00607             idy = (int)(((pt.y - centerY)/cellSizeY+0.5) + sizeY/2);
00608             idz = (int)(((pt.z - centerZ)/cellSizeZ+0.5) + sizeZ/2);
00609 
00610 
00613             if(idx == idxo && idy==idyo && idz ==idzo)
00614             {
00615                 continue;
00616             }
00617             else
00618             {
00619                 idxo = idx;
00620                 idyo=idy,idzo=idz;
00621             }
00623             if(idx < sizeX && idy < sizeY && idz < sizeZ && idx >=0 && idy >=0 && idz >=0)
00624             {
00625                 //fprintf(stderr,"(in)");
00626                 ptCell = dynamic_cast<NDTCell<PointT> *>  (dataArray[idx][idy][idz]);
00627             }
00628             else
00629             {
00630                 //fprintf(stderr,"(out)");
00631                 continue;
00632             }
00633 
00634             if(ptCell != NULL)
00635             {
00636                 double l2target = 0;
00637                 if(ptCell->hasGaussian_)
00638                 {
00639                     Eigen::Vector3d out, pend,vpt;
00640                     pend << it->x,it->y,it->z;
00641                     double lik = ptCell->computeMaximumLikelihoodAlongLine(po, pt, out);
00642                     l2target = (out-pend).norm();
00643 
00644                     double dist = (origin-out).norm();
00645                     if(dist > l) continue; 
00646 
00647                     l2target = (out-pend).norm(); 
00648 
00649                     double sigma_dist = 0.5 * (dist/30.0); 
00650                     double snoise = sigma_dist + sensor_noise;
00651                     double thr =exp(-0.5*(l2target*l2target)/(snoise*snoise)); 
00652                     lik *= (1.0-thr);
00653                     lik = 0.2*lik+0.5; 
00654                     double logoddlik = log( (1.0-lik)/(lik) );
00655                     ptCell->updateEmpty(logoddlik,l2target);
00656                 }
00657                 else
00658                 {
00659                     ptCell->updateEmpty(-0.2,l2target); 
00660                 }
00661             }
00662             else
00663             {
00664                 index_->addPoint(pt); 
00665             }
00666         }
00667 
00668         if(updatePositive) index_->addPoint(*it);
00669         it++;
00670     }
00671     isFirstLoad_ = false;
00672 #endif
00673 }
00674 
00678 
00693 template<typename PointT>
00694 void  NDTMap<PointT>::addPointCloudMeanUpdate(const Eigen::Vector3d &origin, 
00695         const pcl::PointCloud<PointT> &pc, 
00696         const Eigen::Vector3d &localmapsize,
00697         unsigned int maxnumpoints, float occupancy_limit,double maxz, double sensor_noise){
00698 
00699     if(isFirstLoad_){
00700         //fprintf(stderr,"First load... ");
00701         loadPointCloud(pc);
00702         computeNDTCells();
00703         //fprintf(stderr,"DONE!");
00704         return;
00705     }
00706     if(index_ == NULL){
00707         return;
00708     }
00709     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00710     if(lz==NULL){
00711         fprintf(stderr,"NOT LAZY GRID!!!\n");
00712         exit(1);
00713     }
00715     double centerX,centerY,centerZ;
00716     lz->getCenter(centerX, centerY, centerZ);
00717     double cellSizeX,cellSizeY,cellSizeZ;
00718     lz->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
00719     int sizeX,sizeY,sizeZ;
00720     lz->getGridSize(sizeX, sizeY, sizeZ);
00721 
00722     //Cell<PointT> ****dataArray = lz->getDataArrayPtr();
00723 
00724     Eigen::Vector3d old_centroid;
00725     old_centroid(0) = centerX;
00726     old_centroid(1) = centerY;
00727     old_centroid(2) = centerZ;
00728 
00729     double min1 = std::min(cellSizeX,cellSizeY);
00730     double min2 = std::min(cellSizeZ,cellSizeY);
00731     double resolution = std::min(min1,min2); 
00732                 //fprintf(stderr,"1:");
00734     lslgeneric::NDTMap<PointT> ndlocal(new lslgeneric::LazyGrid<PointT>(resolution));
00735     ndlocal.loadPointCloudCentroid(pc,origin, old_centroid, localmapsize, 70.0); 
00736     
00738     //ndlocal.computeNDTCells(CELL_UPDATE_MODE_STUDENT_T);
00739     
00741     ndlocal.computeNDTCells();
00742                 
00744     std::vector<lslgeneric::NDTCell<PointT>*> ndts;
00745     ndts = ndlocal.getAllCells();
00746                 //fprintf(stderr,"2(%u):",ndts.size());
00747     NDTCell<PointT> *ptCell=NULL;
00748 
00749     PointT pt;
00750     PointT po;
00751     po.x = origin(0); po.y = origin(1); po.z = origin(2);
00752     //fprintf(stderr,"NUM = %d\n",ndts.size());
00753     int num_high = 0;
00754     for(unsigned int it=0;it<ndts.size();it++)
00755     {
00756         if(ndts[it] == NULL){
00757             fprintf(stderr,"NDTMap<PointT>::addPointCloudMeanUpdate::GOT NULL FROM MAP -- SHOULD NEVER HAPPEN!!!\n");
00758             continue;
00759         }
00760 
00761         if(!ndts[it]->hasGaussian_){
00762             fprintf(stderr,"NDTMap<PointT>::addPointCloudMeanUpdate::NO GAUSSIAN!!!! -- SHOULD NEVER HAPPEN!!!\n");
00763             continue;
00764         }
00765 
00766         int numpoints = ndts[it]->getN();
00767 
00768         if(numpoints<=0){
00769             fprintf(stderr,"addPointCloudMeanUpdate::Number of points in distribution<=0!!");
00770             continue;
00771         }
00772         Eigen::Vector3d diff;
00773         Eigen::Vector3d m = ndts[it]->getMean();
00774         diff = m-origin;
00775 
00776         double l = diff.norm();
00777         int NN = l / (resolution);
00778 
00779         if(l>200){
00780             fprintf(stderr,"addPointCloudMeanUpdate::Very long distance (%lf) :( \n",l);
00781             continue;
00782         }
00783         if(resolution<0.01){
00784             fprintf(stderr,"addPointCloudMeanUpdate::Resolution very very small (%lf) :( \n",resolution);
00785             continue;
00786         }
00787         if(NN < 0){ 
00788             fprintf(stderr,"addPointCloudMeanUpdate::N=%d (r=%lf l=%lf) :( ",NN,resolution,l);
00789             continue;
00790         }
00791 
00792         bool updatePositive = true;
00793         if(m(2)>maxz){
00794             num_high++;
00795             updatePositive = false; 
00796             //fprintf(stderr,"NDTMap<PointT>::addPointCloudMeanUpdate::HIGH POINT!!!\n");
00797 
00798         }
00799         //std::cout<<"c: "<<ndts[it]->getCov()<<std::endl;
00800 
00801         diff = diff/(float)NN;
00802 
00803         //fprintf(stderr,"3(%d):",NN);
00804         int idxo=0, idyo=0,idzo=0;
00805         for(int i=0; i<NN-2; i++)  
00806         {
00807             pt.x = origin(0) + ((float)(i+1)) *diff(0);
00808             pt.y = origin(1) + ((float)(i+1)) *diff(1);
00809             pt.z = origin(2) + ((float)(i+1)) *diff(2);
00810             int idx,idy,idz;
00811 
00812             idx = (int)(((pt.x - centerX)/cellSizeX+0.5) + sizeX/2.0);
00813             idy = (int)(((pt.y - centerY)/cellSizeY+0.5) + sizeY/2.0);
00814             idz = (int)(((pt.z - centerZ)/cellSizeZ+0.5) + sizeZ/2.0);
00815 
00816 
00819             if(idx == idxo && idy==idyo && idz ==idzo){
00820                 continue;
00821             }else{
00822                 idxo = idx;idyo=idy;idzo=idz;
00823             }
00824             ptCell = NULL;
00826             lz->getNDTCellAt(idx,idy,idz,ptCell);
00827             /*
00828                if(ptCell != NULL){
00829                if(!ptCell->hasGaussian_){
00830                ptCell->updateOccupancy(-0.85*numpoints,occupancy_limit);
00831                }else{
00832                ptCell->updateOccupancy(-0.2*numpoints,occupancy_limit);
00833                ptCell = lz->getClosestNDTCell(pt);
00834                }
00835                }*/
00836 
00837             if(ptCell != NULL){
00838                 double l2target = 0;
00839                 if(ptCell->hasGaussian_)
00840                 {
00841                     Eigen::Vector3d out, pend,vpt;
00842                     pend = m;
00843 
00844                     double lik = ptCell->computeMaximumLikelihoodAlongLine(po, pt, out);
00845                     l2target = (out-pend).norm();
00846 
00847                     double dist = (origin-out).norm();
00848                     if(dist > l) continue; 
00849 
00850                     l2target = (out-pend).norm(); 
00851 
00852                     double sigma_dist = 0.5 * (dist/30.0); 
00853                     //double sigma_dist = 0;
00854                     double snoise = sigma_dist + sensor_noise;
00855                     double thr =exp(-0.5*(l2target*l2target)/(snoise*snoise)); 
00856                     lik *= (1.0-thr);
00857                     //lik = 0.4*lik+0.5+0.05; ///Evidence value for empty - alpha * p(x);
00858                     lik = 0.2*lik+0.5; 
00859                     double logoddlik = log( (1.0-lik)/(lik) );
00860 
00861                     //fprintf(stderr,"l=%lf ",numpoints*logoddlik);
00862                     ptCell->updateOccupancy(numpoints*logoddlik,occupancy_limit);
00863                     if(ptCell->getOccupancy()<0) ptCell->hasGaussian_ = false;
00864                 }
00865                 else
00866                 {
00867                     ptCell->updateOccupancy(-0.85*numpoints,occupancy_limit); 
00868                     //ptCell->updateEmpty(-0.2*numpoints,l2target); ///The cell does not have gaussian, so we mark that we saw it empty...
00869                 }
00870             }else{
00871                 ptCell = dynamic_cast<NDTCell<PointT>*>(index_->addPoint(pt)); 
00872             }
00873         }
00874         if(updatePositive){
00875             Eigen::Matrix3d ucov = ndts[it]->getCov();
00876             float r,g,b;
00877             ndts[it]->getRGB(r,g,b);
00878             addDistributionToCell(ucov, m, numpoints, r, g,b,maxnumpoints,occupancy_limit); 
00879         }
00880     }
00881     //fprintf(stderr,"| Gaussians=%d Invalid=%d |", ndts.size(), num_high);
00882     for(unsigned int i=0;i<ndts.size();i++) delete ndts[i];
00883     isFirstLoad_ = false;
00884 }
00885 
00886 
00890 
00895     template<typename PointT>
00896 bool NDTMap<PointT>::addMeasurement(const Eigen::Vector3d &origin, PointT endpoint, double classifierTh, double maxz, double sensor_noise)
00897 {
00898 
00899     if(index_ == NULL)
00900     {
00901         return false;
00902     }
00903 
00904     bool retval = false;
00905 
00906     LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
00907     double centerX,centerY,centerZ;
00908     lz->getCenter(centerX, centerY, centerZ);
00909     double cellSizeX,cellSizeY,cellSizeZ;
00910     lz->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
00911     int sizeX,sizeY,sizeZ;
00912     lz->getGridSize(sizeX, sizeY, sizeZ);
00913 
00914     //Cell<PointT> ****dataArray = lz->getDataArrayPtr();
00915 
00916     double min1 = std::min(cellSizeX,cellSizeY);
00917     double min2 = std::min(cellSizeZ,cellSizeY);
00918 
00919     double resolution = std::min(min1,min2); 
00920 
00921     if(lz==NULL)
00922     {
00923         fprintf(stderr,"NOT LAZY GRID!!!\n");
00924         exit(1);
00925     }
00926     NDTCell<PointT> *ptCell=NULL;
00927 
00928     PointT pt;
00929     PointT po;
00930     po.x = origin(0),origin(1),origin(2);
00931 
00932     Eigen::Vector3d diff;
00933     diff << endpoint.x-origin(0), endpoint.y-origin(1), endpoint.z-origin(2);
00934 
00935 
00936     double l = diff.norm();
00937     if(l>200)
00938     {
00939         fprintf(stderr,"Very long distance (%lf) :( \n",l);
00940         return false;
00941     }
00942     if(resolution<0.01)
00943     {
00944         fprintf(stderr,"Resolution very very small (%lf) :( \n",resolution);
00945         return false;
00946     }
00947 
00948     int NN = l / (resolution);
00949     if(NN <= 0) return false;
00950     diff = diff/(float)NN;
00951     //fprintf(stderr," (N=%d) ",NN);
00952     bool updatePositive = true;
00953     if(endpoint.z>maxz)
00954     {
00955         return false;
00956     }
00957 
00958     int idxo=0, idyo=0,idzo=0;
00959     for(int i=0; i<NN-2; i++)
00960     {
00961         pt.x = origin(0) + ((float)(i+1)) *diff(0);
00962         pt.y = origin(1) + ((float)(i+1)) *diff(1);
00963         pt.z = origin(2) + ((float)(i+1)) *diff(2);
00964         int idx,idy,idz;
00965 
00966         idx = (int)(((pt.x - centerX)/cellSizeX+0.5) + sizeX/2);
00967         idy = (int)(((pt.y - centerY)/cellSizeY+0.5) + sizeY/2);
00968         idz = (int)(((pt.z - centerZ)/cellSizeZ+0.5) + sizeZ/2);
00969 
00970 
00973         if(idx == idxo && idy==idyo && idz ==idzo)
00974         {
00975             continue;
00976         }
00977         else
00978         {
00979             idxo = idx;
00980             idyo=idy,idzo=idz;
00981         }
00983         //if(idx < sizeX && idy < sizeY && idz < sizeZ && idx >=0 && idy >=0 && idz >=0)
00984         //{
00985         //    ptCell = dynamic_cast<NDTCell<PointT> *>  (lz->getCellAt(idx,idy,idz)); //dataArray[idx][idy][idz]);
00986         lz->getNDTCellAt(idx,idy,idz,ptCell);
00987         //}
00988         //else
00989         //{
00990         //    continue;
00991         //}
00992 
00993         if(ptCell != NULL)
00994         {
00995             double l2target = 0;
00996 
00997             if(ptCell->hasGaussian_)
00998             {
00999                 Eigen::Vector3d out, pend,vpt;
01000 
01001                 pend << endpoint.x,endpoint.y,endpoint.z; 
01002 
01003                 double lik = ptCell->computeMaximumLikelihoodAlongLine(po, pt, out);
01004                 double dist = (origin-out).norm();
01005                 if(dist > l) continue; 
01006 
01007                 l2target = (out-pend).norm(); 
01008                 //double thr =exp(-0.5*(l2target*l2target)/(sensor_noise*sensor_noise)); ///This is the probability of max lik point being endpoint
01009                 //ptCell->updateEmpty(lik*(1-thr),l2target);
01010 
01011                 double sigma_dist = 0.5 * (dist/30.0); 
01012                 double snoise = sigma_dist + sensor_noise;
01013                 double thr =exp(-0.5*(l2target*l2target)/(snoise*snoise)); 
01014                 lik *= (1.0-thr);
01015                 lik = 0.2*lik+0.5; 
01016                 double logoddlik = log( (1.0-lik)/(lik) );
01017                 ptCell->updateEmpty(logoddlik,l2target);
01018 
01019 
01020                 /*
01021                 if(lik>thr){
01022                         retval = true;
01023                         ptCell->updateEmpty(lik,l2target);
01024                 }*/
01025             }
01026             else
01027             {
01028                 ptCell->updateEmpty(-0.1,l2target); 
01029             }
01030         }
01031         else
01032         {
01033             index_->addPoint(pt); 
01034         }
01035     }
01036 
01037     if(updatePositive) index_->addPoint(endpoint);
01038 
01039     isFirstLoad_ = false;
01040 
01041     return retval;
01042 }
01049 
01050 template<typename PointT>
01051 double NDTMap<PointT>::getDepth(Eigen::Vector3d origin, Eigen::Vector3d dir, double maxDepth){
01052         Eigen::Vector3d ray_endpos=origin + dir * maxDepth;
01053         std::vector< NDTCell<PointT>*> cells; 
01054         
01055         Eigen::Vector3d diff = ray_endpos - origin;
01056         PointT endP;
01057         endP.x = ray_endpos(0);
01058         endP.y = ray_endpos(1);
01059         endP.z = ray_endpos(2);
01060         
01061         LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
01062         if(lz==NULL){
01063                 fprintf(stderr,"NOT LAZY GRID!!!\n");
01064                 exit(1);
01065         }
01066         
01067         if(!lz->traceLine(origin, endP,diff,1000.0, cells)){
01068                 return maxDepth+1.0;
01069         }
01070         //fprintf(stderr,"Got trace with %d Cells (%lf)\n",cells.size(),(ray_endpos-origin).norm());
01071         PointT po;
01072         po.x = origin(0);
01073         po.y = origin(1);
01074         po.z = origin(2);
01075         
01076         Eigen::Vector3d out;
01077         bool hasML = false;
01078         
01079         for(unsigned int i=0;i<cells.size();i++){
01080                  if(cells[i]->hasGaussian_){
01081                         double lik = cells[i]->computeMaximumLikelihoodAlongLine(po, endP, out);
01082                         if(lik>0.1){
01083                                 //fprintf(stderr,"Got ML %lf (%lf)\n",lik,(out-origin).norm());
01084                                 hasML = true;
01085                                 break;
01086                         }
01087                 } 
01088         }
01089         
01090         if(hasML) return (out - origin).norm();
01091         
01092         return (maxDepth+1.0);
01093 }
01094 
01095 
01096 template<typename PointT>
01097 double NDTMap<PointT>::getDepthSmooth(Eigen::Vector3d origin,
01098                                       Eigen::Vector3d dir,
01099                                       double maxDepth,
01100                                       int n_neigh,
01101                                       double weight,
01102                                       double threshold,
01103                                       Eigen::Vector3d *hit)
01104 {
01105         Eigen::Vector3d ray_endpos=origin + dir * maxDepth;
01106         std::vector< NDTCell<PointT>*> cells, surr; 
01107         
01108         Eigen::Vector3d diff = ray_endpos - origin;
01109         PointT endP;
01110         endP.x = ray_endpos(0);
01111         endP.y = ray_endpos(1);
01112         endP.z = ray_endpos(2);
01113         
01114         LazyGrid<PointT> *lz = dynamic_cast<LazyGrid<PointT>*>(index_);
01115         if(lz==NULL){
01116                 fprintf(stderr,"NOT LAZY GRID!!!\n");
01117                 exit(1);
01118         }
01119         
01120         if(!lz->traceLine(origin, endP,diff,1000.0, cells)){
01121                 return maxDepth+1.0;
01122         }
01123         
01124         PointT startP, p;
01125         startP.x = origin(0);
01126         startP.y = origin(1);
01127         startP.z = origin(2);
01128         
01129         Eigen::Vector3d out;
01130         bool hasML = false;
01131 
01132         for(unsigned int i = 0; i < cells.size(); i++)
01133         {
01134                 if(cells[i]->hasGaussian_)
01135                 {
01136                     surr = lz->getClosestNDTCells(cells[i]->getCenter(), n_neigh, true);
01137                         double like = cells[i]->computeMaximumLikelihoodAlongLine(startP, endP, out);
01138                         p.x = out(0);
01139             p.y = out(1);
01140             p.z = out(2);
01141             for (unsigned int k = 1u; k < surr.size(); ++k)
01142                         {
01143                             like += weight * surr[k]->getLikelihood(p);
01144                         }                       
01145                         if(like > threshold)
01146                         {
01147                                 hasML = true;
01148                                 break;
01149                         }
01150                 } 
01151         }
01152         
01153         if (hasML)
01154         {
01155             if (hit != NULL)
01156             {
01157                 *hit = out;
01158             }
01159             return (out - origin).norm();
01160         }
01161         
01162         return (maxDepth+1.0);
01163 }
01164 
01168 
01169 
01170 template<typename PointT>
01171 void NDTMap<PointT>::loadPointCloud(const pcl::PointCloud<PointT> &pc, const std::vector<std::vector<size_t> > &indices)
01172 {
01173 
01174     loadPointCloud(pc);
01175     // Specific function related to CellVector
01176     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
01177     if (cl != NULL)
01178     {
01179         for (size_t i = 0; i < indices.size(); i++)
01180         {
01181             cl->addCellPoints(pc, indices[i]);
01182         }
01183 
01184     }
01185     else
01186     {
01187         //ERR("loading point clouds using indices are currently supported in CellVector index_.");
01188     }
01189 }
01190 
01191 template<typename PointT>
01192 void NDTMap<PointT>::loadDepthImage(const cv::Mat& depthImage, DepthCamera<PointT> &cameraParams)
01193 {
01194     pcl::PointCloud<PointT> pc;
01195     cameraParams.convertDepthImageToPointCloud(depthImage, pc);
01196     this->loadPointCloud(pc);
01197 }
01198 
01199 template<typename PointT>
01200 pcl::PointCloud<PointT> NDTMap<PointT>::loadDepthImageFeatures(const cv::Mat& depthImage, std::vector<cv::KeyPoint> &keypoints,
01201         size_t &supportSize, double maxVar, DepthCamera<PointT> &cameraParams, bool estimateParamsDI, bool nonMean)
01202 {
01203     std::vector<cv::KeyPoint> good_keypoints;
01204     Eigen::Vector3d mean;
01205     PointT mn;
01206     pcl::PointCloud<PointT> cloudOut;
01207     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
01208     if(cl==NULL)
01209     {
01210         std::cerr<<"wrong index type!\n";
01211         return cloudOut;
01212     }
01213     for (size_t i=0; i<keypoints.size(); i++)
01214     {
01215         if(!estimateParamsDI)
01216         {
01217             pcl::PointCloud<PointT> points;
01218             PointT center;
01219             cameraParams.computePointsAtIndex(depthImage,keypoints[i],supportSize,points,center);
01220             NDTCell<PointT> *ndcell = new NDTCell<PointT>();
01221             typename pcl::PointCloud<PointT>::iterator it = points.points.begin();
01222             while (it!= points.points.end() )
01223             {
01224                 if(std::isnan(it->x) ||std::isnan(it->y) ||std::isnan(it->z))
01225                 {
01226                     it++;
01227                     continue;
01228                 }
01229                 ndcell->addPoint(*it);
01230                 it++;
01231             }
01232             ndcell->computeGaussian();
01233             if(ndcell->hasGaussian_)
01234             {
01235                 Eigen::Vector3d evals = ndcell->getEvals();
01236                 if(sqrt(evals(2)) < maxVar)
01237                 {
01238                     if (nonMean)
01239                     {
01240                         if(std::isnan(center.x) ||std::isnan(center.y) ||std::isnan(center.z))
01241                         {
01242                             continue;
01243                         }
01244                         mn = center;
01245                     }
01246                     else
01247                     {
01248                         mean = ndcell->getMean();
01249                         mn.x = mean(0);
01250                         mn.y = mean(1);
01251                         mn.z = mean(2);
01252                     }
01253                     cloudOut.points.push_back(mn);
01254                     ndcell->setCenter(mn);
01255                     cl->addCell(ndcell);
01256                     good_keypoints.push_back(keypoints[i]);
01257                 }
01258             }
01259         }
01260         else
01261         {
01262             assert(nonMean = false); // Not implemented / used.
01263             Eigen::Vector3d mean;
01264             Eigen::Matrix3d cov;
01265             cameraParams.computeParamsAtIndex(depthImage,keypoints[i],supportSize,mean,cov);
01266             NDTCell<PointT> *ndcell = new NDTCell<PointT>();
01267             ndcell->setMean(mean);
01268             ndcell->setCov(cov);
01269 
01270             if(ndcell->hasGaussian_)
01271             {
01272                 Eigen::Vector3d evals = ndcell->getEvals();
01273                 //std::cout<<evals.transpose()<<std::endl;
01274                 if(sqrt(evals(2)) < maxVar)
01275                 {
01276                     mean = ndcell->getMean();
01277                     mn.x = mean(0);
01278                     mn.y = mean(1);
01279                     mn.z = mean(2);
01280                     cloudOut.points.push_back(mn);
01281                     ndcell->setCenter(mn);
01282                     cl->addCell(ndcell);
01283                     good_keypoints.push_back(keypoints[i]);
01284                 }
01285             }
01286 
01287         }
01288     }
01289 
01290     //TODO
01291     keypoints = good_keypoints;
01292     return cloudOut;
01293 }
01294 
01297 template<typename PointT>
01298 void NDTMap<PointT>::computeNDTCells(int cellupdatemode, unsigned int maxnumpoints, float occupancy_limit, Eigen::Vector3d origin, double sensor_noise)
01299 {
01300     CellVector<PointT> *cv = dynamic_cast<CellVector<PointT>*>(index_);
01301 
01302     conflictPoints.clear();
01303 #ifdef REFACTORED
01304     //typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01305     typename std::set<NDTCell<PointT>*>::iterator it = update_set.begin();
01306     //while (it != index_->end())
01307     while (it != update_set.end())
01308     {
01309         //NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01310         NDTCell<PointT> *cell = *it;
01311         if(cell!=NULL)
01312         {
01313             cell->computeGaussian(cellupdatemode,maxnumpoints, occupancy_limit, origin,sensor_noise);
01315             if(cell->points_.size()>0)
01316             {
01317                 for(unsigned int i=0; i<cell->points_.size(); i++) conflictPoints.push_back(cell->points_[i]);
01318                 cell->points_.clear();
01319             }
01320             if (cv!=NULL)
01321             {
01322                 // Set the mean to the cell's centre.
01323                 Eigen::Vector3d mean = cell->getMean();
01324                 PointT pt;
01325                 pt.x = mean[0];
01326                 pt.y = mean[1];
01327                 pt.z = mean[2];
01328 
01329                 cell->setCenter(pt);
01330             }
01331         }
01332         else
01333         {
01334 
01335         }
01336         it++;
01337     }
01338     update_set.clear();
01339 
01340     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
01341     if(cl!=NULL)
01342     {
01343         cl->initKDTree();
01344     }
01345 #else
01346 typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01347     //typename std::set<NDTCell<PointT>*>::iterator it = update_set.begin();
01348     while (it != index_->end())
01349     //while (it != update_set.end())
01350     {
01351         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01352         //NDTCell<PointT> *cell = *it;
01353         if(cell!=NULL)
01354         {
01355             cell->computeGaussian(cellupdatemode,maxnumpoints, occupancy_limit, origin,sensor_noise);
01357             if(cell->points_.size()>0)
01358             {
01359                 for(unsigned int i=0; i<cell->points_.size(); i++) conflictPoints.push_back(cell->points_[i]);
01360                 cell->points_.clear();
01361             }
01362             if (cv!=NULL)
01363             {
01364                 // Set the mean to the cell's centre.
01365                 Eigen::Vector3d mean = cell->getMean();
01366                 PointT pt;
01367                 pt.x = mean[0];
01368                 pt.y = mean[1];
01369                 pt.z = mean[2];
01370 
01371                 cell->setCenter(pt);
01372             }
01373         }
01374         else
01375         {
01376 
01377         }
01378         it++;
01379     }
01380     //update_set.clear();
01381 
01382     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
01383     if(cl!=NULL)
01384     {
01385         cl->initKDTree();
01386     }
01387 #endif
01388     
01389     
01390 }
01391 
01392 
01393 
01397 template<typename PointT>
01398 void NDTMap<PointT>::computeNDTCellsSimple()
01399 {
01400     CellVector<PointT> *cv = dynamic_cast<CellVector<PointT>*>(index_);
01401 
01402     conflictPoints.clear();
01403 
01404     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01405 
01406     while (it != index_->end())
01407     {
01408         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01409         if(cell!=NULL)
01410         {
01411             cell->computeGaussianSimple();
01412           
01413             if (cv!=NULL)
01414             {
01415                 // Set the mean to the cell's centre.
01416                 Eigen::Vector3d mean = cell->getMean();
01417                 PointT pt;
01418                 pt.x = mean[0];
01419                 pt.y = mean[1];
01420                 pt.z = mean[2];
01421 
01422                 cell->setCenter(pt);
01423             }
01424         }
01425         else
01426         {
01427 
01428         }
01429         it++;
01430     }
01431 
01432     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
01433     if(cl!=NULL)
01434     {
01435         cl->initKDTree();
01436     }
01437 }
01438 
01441 template<typename PointT>
01442 void NDTMap<PointT>::writeToVRML(const char* filename)
01443 {
01444 
01445     if(filename == NULL)
01446     {
01447         //ERR("problem outputing to vrml\n");
01448         return;
01449     }
01450     /*
01451        std::string fn(filename);
01452        fn = "oct_"+fn;
01453 
01454        FILE *fo = fopen(fn.c_str(),"w");
01455        if(fo == NULL) {
01456        ERR("problem outputing to vrml\n");
01457        return;
01458        }
01459        fprintf(fo,"#VRML V2.0 utf8\n");
01460        writeToVRML(fo,true);
01461        fclose(fo);
01462      */
01463 
01464     FILE *fout = fopen(filename,"w");
01465     if(fout == NULL)
01466     {
01467         //ERR("problem outputing to vrml\n");
01468         return;
01469     }
01470     fprintf(fout,"#VRML V2.0 utf8\n");
01471     writeToVRML(fout);
01472     fclose(fout);
01473 }
01474 
01477 template<typename PointT>
01478 void NDTMap<PointT>::writeToVRML(FILE* fout)
01479 {
01480     if(fout == NULL)
01481     {
01482         //ERR("problem outputing to vrml\n");
01483         return;
01484     }
01485 
01486     //move the ellipsoid stuff to NDTCell
01487     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01488     while (it != index_->end())
01489     {
01490         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01491         //      double xs,ys,zs;
01492         if(cell!=NULL)
01493         {
01494             cell->writeToVRML(fout);
01495         }
01496         else
01497         {
01498             //      ERR("problem casting cell to NDT!\n");
01499         }
01500         it++;
01501     }
01502 
01503 }
01504 
01505 template<typename PointT>
01506 void NDTMap<PointT>::writeToVRML(FILE* fout, Eigen::Vector3d col)
01507 {
01508     if(fout == NULL)
01509     {
01510         //ERR("problem outputing to vrml\n");
01511         return;
01512     }
01513 
01514     //move the ellipsoid stuff to NDTCell
01515     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01516     while (it != index_->end())
01517     {
01518         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01519         if(cell!=NULL)
01520         {
01521             cell->writeToVRML(fout,col);
01522         }
01523         else
01524         {
01525         }
01526         it++;
01527     }
01528 }
01529 
01530 
01533 template<typename PointT>
01534 int NDTMap<PointT>::writeToJFF(const char* filename)
01535 {
01536 
01537     if(filename == NULL)
01538     {
01539         //ERR("problem outputing to jff\n");
01540         return -1;
01541     }
01542 
01543     FILE * jffout = fopen(filename, "w+b");
01544 
01545     fwrite(_JFFVERSION_, sizeof(char), strlen(_JFFVERSION_), jffout);
01546 
01547     switch(this->getMyIndexInt())
01548     {
01549     case 1:
01550         writeCellVectorJFF(jffout);
01551         break;
01552     case 2:
01553         //writeOctTreeJFF(jffout);
01554         break;
01555     case 3:
01556         writeLazyGridJFF(jffout);
01557         break;
01558     default:
01559         //ERR("unknown index type\n");
01560         return -1;
01561     }
01562 
01563     fclose(jffout);
01564 
01565     return 0;
01566 }
01567 
01568 
01569 template<typename PointT>
01570 int NDTMap<PointT>::writeCellVectorJFF(FILE * jffout)
01571 {
01572     int indexType[1] = {1};
01573     fwrite(indexType, sizeof(int), 1, jffout);
01574 
01575     // TODO: add CellVector specific stuff
01576 
01577     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01578     while (it != index_->end())
01579     {
01580         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01581         if(cell!=NULL)
01582         {
01583             if(cell->hasGaussian_)
01584             {
01585                 // TODO: add index specific content smartly
01586                 if(cell->writeToJFF(jffout) < 0)
01587                     return -1;
01588             }
01589         }
01590         else
01591         {
01592             // do nothing
01593         }
01594         it++;
01595     }
01596 
01597     return 0;
01598 
01599 }
01600 
01601 
01602 template<typename PointT>
01603 int NDTMap<PointT>::writeOctTreeJFF(FILE * jffout)
01604 {
01605     int indexType[1] = {2};
01606     fwrite(indexType, sizeof(int), 1, jffout);
01607 
01608     // TODO: add OctTree specific stuff
01609 
01610     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01611     while (it != index_->end())
01612     {
01613         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01614         if(cell!=NULL)
01615         {
01616             if(cell->hasGaussian_)
01617             {
01618                 // TODO: add index specific content smartly
01619                 if(cell->writeToJFF(jffout) < 0)
01620                     return -1;
01621             }
01622         }
01623         else
01624         {
01625             // do nothing
01626         }
01627         it++;
01628     }
01629 
01630     return 0;
01631 
01632 }
01633 
01634 template<typename PointT>
01635 int NDTMap<PointT>::writeLazyGridJFF(FILE * jffout)
01636 {
01637     int indexType[1] = {3};
01638     fwrite(indexType, sizeof(int), 1, jffout);
01639 
01640     // add LazyGrid specific stuff
01641     double sizeXmeters, sizeYmeters, sizeZmeters;
01642     double cellSizeX, cellSizeY, cellSizeZ;
01643     double centerX, centerY, centerZ;
01644     LazyGrid<PointT> *ind = dynamic_cast<LazyGrid<PointT>*>(index_);
01645 
01646     ind->getGridSizeInMeters(sizeXmeters, sizeYmeters, sizeZmeters);
01647     ind->getCellSize(cellSizeX, cellSizeY, cellSizeZ);
01648     ind->getCenter(centerX, centerY, centerZ);
01649 
01650     double lazyGridData[9] = { sizeXmeters, sizeYmeters, sizeZmeters,
01651                                cellSizeX,   cellSizeY,   cellSizeZ,
01652                                centerX,     centerY,     centerZ
01653                              };
01654 
01655     fwrite(lazyGridData, sizeof(double), 9, jffout);
01656 
01657     fwrite(ind->getProtoType(), sizeof(Cell<PointT>), 1, jffout);
01658 
01659     // loop through all active cells
01660     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01661     while (it != index_->end())
01662     {
01663         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01664         if(cell!=NULL)
01665         {
01666             //if(cell->hasGaussian_) {
01667             if(cell->writeToJFF(jffout) < 0)    return -1;
01668             // }
01669         }
01670         else
01671         {
01672             // do nothing
01673         }
01674         it++;
01675     }
01676 
01677     return 0;
01678 
01679 }
01680 
01695 template<typename PointT>
01696 int NDTMap<PointT>::loadFromJFF(const char* filename)
01697 {
01698 
01699     FILE * jffin;
01700 
01701     if(filename == NULL)
01702     {
01703         JFFERR("problem outputing to jff");
01704     }
01705 
01706     jffin = fopen(filename,"r+b");
01707 
01708     char versionBuf[16];
01709     if(fread(&versionBuf, sizeof(char), strlen(_JFFVERSION_), jffin) <= 0)
01710     {
01711         JFFERR("reading version failed");
01712     }
01713     versionBuf[strlen(_JFFVERSION_)] = '\0';
01714 
01715     int indexType;
01716     if(fread(&indexType, sizeof(int), 1, jffin) <= 0)
01717     {
01718         JFFERR("reading version failed");
01719     }
01720 
01721     if(indexType != this->getMyIndexInt())
01722     {
01723         switch(indexType)
01724         {
01725         case 1:
01726             std::cerr << "Map uses CellVector\n";
01727             return -1;
01728             break;
01729         case 2:
01730             std::cerr << "Map uses OctTree\n";
01731             return -2;
01732             break;
01733         case 3:
01734             std::cerr << "Map uses LazyGrid\n";
01735             return -3;
01736             break;
01737         }
01738     }
01739 
01740     switch(indexType)
01741     {
01742     case 1:
01743     {
01744         CellVector<PointT>* cv = dynamic_cast<CellVector<PointT> * >(index_);
01745         if(cv->loadFromJFF(jffin) < 0)
01746         {
01747             JFFERR("Error loading CellVector");
01748         }
01749         break;
01750     }
01751     case 2:
01752     {
01753         OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
01754         if(tr->loadFromJFF(jffin) < 0)
01755         {
01756             JFFERR("Error loading OctTree");
01757         }
01758         break;
01759     }
01760     case 3:
01761     {
01762         LazyGrid<PointT>* gr = dynamic_cast<LazyGrid<PointT>*>(index_);
01763         if(gr->loadFromJFF(jffin) < 0)
01764         {
01765             JFFERR("Error loading LazyGrid");
01766         }
01767         break;
01768     }
01769     default:
01770         JFFERR("error casting index");
01771     }
01772 
01773     NDTCell<PointT> *ptCell = new NDTCell<PointT>();
01774     index_->setCellType(ptCell);
01775     delete ptCell;
01776 
01777     fclose(jffin);
01778 
01779    // std::cout << "map loaded successfully " << versionBuf << std::endl;
01780 
01781     isFirstLoad_ = false;
01782 
01783     return 0;
01784 
01785 }
01786 
01787 
01789 template<typename PointT>
01790 std::string NDTMap<PointT>::getMyIndexStr() const
01791 {
01792     CellVector<PointT>* cl = dynamic_cast<CellVector<PointT> * >(index_);
01793     if(cl!=NULL)
01794     {
01795         return std::string("CellVector");
01796     }
01797     OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
01798     if(tr!=NULL)
01799     {
01800         return std::string("OctTree");
01801     }
01802     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
01803     if(gr!=NULL)
01804     {
01805         return std::string("LazyGrid<PointT>");
01806     }
01807 
01808     return std::string("Unknown index type");
01809 }
01810 
01812 template<typename PointT>
01813 int NDTMap<PointT>::getMyIndexInt() const
01814 {
01815     CellVector<PointT>* cl = dynamic_cast<CellVector<PointT> * >(index_);
01816     if(cl!=NULL)
01817     {
01818         return 1;
01819     }
01820     OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
01821     if(tr!=NULL)
01822     {
01823         return 2;
01824     }
01825     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
01826     if(gr!=NULL)
01827     {
01828         return 3;
01829     }
01830 
01831     return -1;
01832 }
01833 
01834 //computes the *negative log likelihood* of a single observation
01835 template<typename PointT>
01836 double NDTMap<PointT>::getLikelihoodForPoint(PointT pt)
01837 {
01838     //assert(false);
01839     double uniform=0.00100;
01840     NDTCell<PointT>* ndCell = NULL;
01841     OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
01842 
01843     if(tr==NULL)
01844     {
01845         LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
01846         if(gr==NULL)
01847         {
01848             //cout<<"bad index - getLikelihoodForPoint\n";
01849             return uniform;
01850         }
01851         ndCell = gr->getClosestNDTCell(pt);
01852     }
01853     else
01854     {
01855         ndCell = tr->getClosestNDTCell(pt);
01856     }
01857     if(ndCell == NULL) return uniform;
01858 
01859     double prob = ndCell->getLikelihood(pt);
01860     prob = (prob<0) ? 0 : prob; //uniform!! TSV
01861     return prob;
01862 }
01863 
01864 /*
01865 //use trilinear interpolation from available immediate neighbors
01866 template<typename PointT>
01867 double NDTMap<PointT>::getLikelihoodForPointWithInterpolation(PointT pt) {
01868 
01869     //ATM only for grid map
01870     //     tll------tlr
01871     //     /|       /|
01872     //    / |      / |
01873     //  tul------tur |    z
01874     //   | bll----|-blr   ^  y
01875     //   | /      | /     | /
01876     //   |/       |/      |/
01877     //  bul------bur      ---> x
01878     double uniform=0;//0.00100;
01879     Cell* cell = NULL;
01880     NDTCell<PointT>* ndCell = NULL;
01881     double cumProb = 0;
01882     double weight = 0;
01883     int evals = 1;
01884 
01885     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
01886     if(gr==NULL) {
01887         //cout<<"bad index - getLikelihoodForPointWithInterpolation\n";
01888         return uniform;
01889     }
01890     cell = gr->getCellForPoint(pt);
01891     if(cell == NULL) return uniform;
01892 
01893 
01894     //get coordinates of cell
01895     int indXn, indYn, indZn;
01896     PointT centerGrid, sizeCell, centerCell;
01897     int sizeGridX, sizeGridY,sizeGridZ;
01898     centerCell = cell->getCenter();
01899     gr->getCenter(centerGrid.x,centerGrid.y,centerGrid.z);
01900     gr->getGridSize(sizeGridX,sizeGridY,sizeGridZ);
01901     gr->getCellSize(sizeCell.x,sizeCell.y,sizeCell.z);
01902     gr->getIndexForPoint(pt,indXn,indYn,indZn);
01903 
01904     double x,y,z;
01905     x = (pt.x - centerCell.x)/sizeCell.x;
01906     y = (pt.y - centerCell.y)/sizeCell.y;
01907     z = (pt.z - centerCell.z)/sizeCell.z;
01908     if(x <0 ) x = 0;
01909     if(y <0 ) y = 0;
01910     if(z <0 ) z = 0;
01911     if(x >1 ) x = 1;
01912     if(y >1 ) y = 1;
01913     if(z >1 ) z = 1;
01914 
01915     //bul
01916     double prob = 0;
01917     ndCell = dynamic_cast<NDTCell<PointT>*> (cell);
01918     if(ndCell != NULL) {
01919         prob = ndCell->getLikelihood(pt);
01920         prob = (prob<0) ? uniform : prob;
01921         weight = (1 - x + 1 - y + 1 - z)/(3.0);
01922         if(weight < 0) cerr<<weight<<endl;
01923         cumProb += prob*weight;
01924         //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01925         evals++;
01926     }
01927 
01928     //tul
01929     Cell* c = gr->getCellAt(indXn,indYn,indZn+1);
01930     if(c != NULL) {
01931         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
01932         if(ndCell != NULL) {
01933             prob = ndCell->getLikelihood(pt);
01934             prob = (prob<0) ? uniform : prob;
01935             weight = (1 - x + 1 - y + z)/(3.0);
01936             if(weight < 0) cerr<<weight<<endl;
01937             cumProb += prob*weight;
01938             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01939             evals++;
01940         }
01941     }
01942     //tur
01943     c = gr->getCellAt(indXn+1,indYn,indZn+1);
01944     if(c != NULL) {
01945         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
01946         if(ndCell != NULL) {
01947             prob = ndCell->getLikelihood(pt);
01948             prob = (prob<0) ? uniform : prob;
01949             weight = (x + 1-y + z )/(3.0);
01950             if(weight < 0) cerr<<weight<<endl;
01951             cumProb += prob*weight;
01952             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01953             evals++;
01954         }
01955     }
01956     //tll
01957     c = gr->getCellAt(indXn,indYn+1,indZn+1);
01958     if(c != NULL) {
01959         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
01960         if(ndCell != NULL) {
01961             prob = ndCell->getLikelihood(pt);
01962             prob = (prob<0) ? uniform : prob;
01963             weight = (1-x + y + z )/(3.0);
01964             if(weight < 0) cerr<<weight<<endl;
01965             cumProb += prob*weight;
01966             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01967             evals++;
01968         }
01969     }
01970     //tlr
01971     c = gr->getCellAt(indXn+1,indYn+1,indZn+1);
01972     if(c != NULL) {
01973         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
01974         if(ndCell != NULL) {
01975             prob = ndCell->getLikelihood(pt);
01976             prob = (prob<0) ? uniform : prob;
01977             weight = (x + y + z )/(3.0);
01978             if(weight < 0) cerr<<weight<<endl;
01979             cumProb += prob*weight;
01980             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01981             evals++;
01982         }
01983     }
01984     //bur
01985     c = gr->getCellAt(indXn+1,indYn,indZn);
01986     if(c != NULL) {
01987         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
01988         if(ndCell != NULL) {
01989             prob = ndCell->getLikelihood(pt);
01990             prob = (prob<0) ? uniform : prob;
01991             weight = (x + 1-y + 1-z )/(3.0);
01992             if(weight < 0) cerr<<weight<<endl;
01993             cumProb += prob*weight;
01994             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
01995             evals++;
01996         }
01997     }
01998     //bll
01999     c = gr->getCellAt(indXn,indYn+1,indZn);
02000     if(c != NULL) {
02001         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
02002         if(ndCell != NULL) {
02003             prob = ndCell->getLikelihood(pt);
02004             prob = (prob<0) ? uniform : prob;
02005             weight = (1-x + y + 1-z )/(3.0);
02006             if(weight < 0) cerr<<weight<<endl;
02007             cumProb += prob*weight;
02008             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
02009             evals++;
02010         }
02011     }
02012     //blr
02013     c = gr->getCellAt(indXn+1,indYn+1,indZn);
02014     if(c != NULL) {
02015         ndCell = dynamic_cast<NDTCell<PointT>*> (c);
02016         if(ndCell != NULL) {
02017             prob = ndCell->getLikelihood(pt);
02018             prob = (prob<0) ? uniform : prob;
02019             weight = (x + y + 1-z )/(3.0);
02020             if(weight < 0) cerr<<weight<<endl;
02021             cumProb += prob*weight;
02022             //cout<<"\t"<<weight<<" "<<prob<<" --> "<<cumProb<<endl;
02023             evals++;
02024         }
02025     }
02026 
02027     //cout<<"== "<<cumProb<<endl;
02028     return cumProb;
02029 }
02030 */
02031 
02032 template<typename PointT>
02033 std::vector<NDTCell<PointT>*> NDTMap<PointT>::getInitializedCellsForPoint(const PointT pt) const
02034 {
02035     std::vector<NDTCell<PointT>*> cells;
02036     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
02037     if(gr==NULL)
02038     {
02039         //cout<<"bad index - getCellsForPoint\n";
02040         return cells;
02041     }
02042     cells = gr->getClosestCells(pt);
02043     return cells;
02044 
02045 }
02046 
02047 template<typename PointT>
02048 std::vector<NDTCell<PointT>*> NDTMap<PointT>::getCellsForPoint(const PointT pt, int n_neigh, bool checkForGaussian) const
02049 {
02050     //assert(false);
02051     std::vector<NDTCell<PointT>*> cells;
02052     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
02053     if(gr==NULL)
02054     {
02055         //cout<<"bad index - getCellsForPoint\n";
02056         return cells;
02057     }
02058     cells = gr->getClosestNDTCells(pt,n_neigh,checkForGaussian);
02059     return cells;
02060 
02061     //OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
02062     //if(tr==NULL) {
02063     //}
02064 }
02065 
02066 template<typename PointT>
02067 bool NDTMap<PointT>::getCellForPoint(const PointT &pt, NDTCell<PointT>* &out_cell, bool checkForGaussian) const
02068 {
02069 
02070     out_cell = NULL;
02071     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
02072     if(cl!=NULL)
02073     {
02074         out_cell = cl->getClosestNDTCell(pt);
02075         return true;
02076     }
02077     OctTree<PointT>* tr = dynamic_cast<OctTree<PointT>*>(index_);
02078     if(tr!=NULL)
02079     {
02080         out_cell = tr->getClosestNDTCell(pt);
02081         return true;
02082     }
02083     LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
02084     if(gr!=NULL)
02085     {
02086         out_cell = gr->getClosestNDTCell(pt,checkForGaussian);
02087         return true;
02088     }
02089     //cout<<"bad index - getCellForPoint\n";
02090     return false;
02091 }
02092 
02093 template<typename PointT>
02094 void NDTMap<PointT>::debugToVRML(const char* fname, pcl::PointCloud<PointT> &pc)
02095 {
02096 
02097     FILE* fout = fopen(fname, "w");
02098 
02099     fprintf(fout,"#VRML V2.0 utf8\n");
02100     this->writeToVRML(fout);
02101     lslgeneric::writeToVRML(fout,pc,Eigen::Vector3d(1,0,0));
02102 
02103     fprintf(fout,"Shape {\n\tgeometry IndexedLineSet {\n\tcoord Coordinate {\n\t point [\n\t");
02104 
02105     int n_lines = 0;
02106     PointT centerCell;
02107     for(size_t i=0; i<pc.points.size(); i++)
02108     {
02109         NDTCell<PointT>* link;
02110         if(this->getCellForPoint(pc.points[i], link))
02111         {
02112             if(link == NULL) continue;
02113             centerCell = link->getCenter();
02114             if(link->hasGaussian_)
02115             {
02116                 centerCell.x = link->getMean()(0);
02117                 centerCell.y = link->getMean()(1);
02118                 centerCell.z = link->getMean()(2);
02119             }
02120             fprintf(fout,"%lf %lf %lf\n\t%lf %lf %lf\n\t",
02121                     pc.points[i].x, pc.points[i].y,pc.points[i].z,
02122                     centerCell.x, centerCell.y, centerCell.z);
02123             n_lines++;
02124         }
02125     }
02126 
02127     fprintf(fout, "]\n\t}\n\tcoordIndex [\n\t");
02128     for(int i = 0; i<n_lines; i++)
02129     {
02130         fprintf(fout,"%d, %d, -1\n\t",2*i, 2*i+1);
02131     }
02132     fprintf(fout, "]\n}\n}\n");
02133 
02134 
02135     fclose(fout);
02136 }
02137 
02138 template<typename PointT>
02139 NDTMap<PointT>* NDTMap<PointT>::pseudoTransformNDTMap(Eigen::Transform<double,3,Eigen::Affine,Eigen::ColMajor> T)
02140 {
02141     NDTMap<PointT>* map = new NDTMap<PointT>(new CellVector<PointT>());
02142     CellVector<PointT>* idx = dynamic_cast<CellVector<PointT>*> (map->getMyIndex());
02143     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
02144 
02145     while (it != index_->end())
02146     {
02147         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
02148         if(cell!=NULL)
02149         {
02150             if(cell->hasGaussian_)
02151             {
02152                 Eigen::Vector3d mean = cell->getMean();
02153                 Eigen::Matrix3d cov = cell->getCov();
02154                 mean = T*mean;
02156                 cov = T.rotation()*cov*T.rotation().transpose();
02157                 NDTCell<PointT>* nd = (NDTCell<PointT>*)cell->clone();
02158                 nd->setMean(mean);
02159                 nd->setCov(cov);
02160                 idx->addNDTCell(nd);
02161             }
02162         }
02163         else
02164         {
02165             //ERR("problem casting cell to NDT!\n");
02166         }
02167         it++;
02168     }
02169     return map;
02170 }
02171 
02172 template<typename PointT>
02173 std::vector<NDTCell<PointT>*> NDTMap<PointT>::pseudoTransformNDT(Eigen::Transform<double,3,Eigen::Affine,Eigen::ColMajor> T)
02174 {
02175 
02176     std::vector<NDTCell<PointT>*> ret;
02177     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
02178     while (it != index_->end())
02179     {
02180         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
02181         if(cell!=NULL)
02182         {
02183             if(cell->hasGaussian_)
02184             {
02185                 Eigen::Vector3d mean = cell->getMean();
02186                 Eigen::Matrix3d cov = cell->getCov();
02187                 mean = T*mean;
02189                 cov = T.rotation()*cov*T.rotation().transpose();
02190                 NDTCell<PointT>* nd = (NDTCell<PointT>*)cell->clone();
02191                 nd->setMean(mean);
02192                 nd->setCov(cov);
02193                 ret.push_back(nd);
02194             }
02195         }
02196         else
02197         {
02198             //ERR("problem casting cell to NDT!\n");
02199         }
02200         it++;
02201     }
02202     return ret;
02203 }
02204 
02205 template<typename PointT>
02206 NDTCell<PointT>*
02207 NDTMap<PointT>::getCellIdx(unsigned int idx) const
02208 {
02209     CellVector<PointT> *cl = dynamic_cast<CellVector<PointT>*>(index_);
02210     if (cl != NULL)
02211     {
02212         return cl->getCellIdx(idx);
02213     }
02214     return NULL;
02215 }
02216 
02217 template<typename PointT>
02218 std::vector<lslgeneric::NDTCell<PointT>*> NDTMap<PointT>::getAllCells() const
02219 {
02220 
02221     std::vector<NDTCell<PointT>*> ret;
02222     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
02223     while (it != index_->end())
02224     {
02225         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
02226         if(cell!=NULL)
02227         {
02228             if(cell->hasGaussian_)
02229             {
02230                 NDTCell<PointT>* nd = (NDTCell<PointT>*)cell->copy();
02231                 ret.push_back(nd);
02232             }
02233         }
02234         else
02235         {
02236         }
02237         it++;
02238     }
02239     return ret;
02240 }
02241 
02242 template<typename PointT>
02243 std::vector<lslgeneric::NDTCell<PointT>*> NDTMap<PointT>::getAllInitializedCells()
02244 {
02245 
02246     std::vector<NDTCell<PointT>*> ret;
02247     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
02248     while (it != index_->end())
02249     {
02250         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
02251         if(cell!=NULL)
02252         {
02253             NDTCell<PointT>* nd = (NDTCell<PointT>*)cell->copy();
02254             ret.push_back(nd);
02255         }
02256         else
02257         {
02258         }
02259         it++;
02260     }
02261     return ret;
02262 }
02263 
02264 
02265 
02266 template<typename PointT>
02267 int NDTMap<PointT>::numberOfActiveCells()
02268 {
02269     int ret = 0;
02270     if(index_ == NULL) return ret;
02271     typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
02272     while (it != index_->end())
02273     {
02274         NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
02275         if(cell!=NULL)
02276         {
02277             if(cell->hasGaussian_)
02278             {
02279                 ret++;
02280             }
02281         }
02282         it++;
02283     }
02284     return ret;
02285 }
02286 
02287 }


ndt_map
Author(s): Todor Stoyanov, Jari Saarinen, Henrik Andreasson
autogenerated on Mon Jan 6 2014 11:31:57