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
00036 SpatialIndex<PointT> *si = index_->clone();
00037
00038 if(!isFirstLoad_)
00039 {
00040
00041 delete index_;
00042 }
00043 isFirstLoad_ = false;
00044 index_ = si;
00045 }
00046 else
00047 {
00048
00049
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
00063 return;
00064 }
00065
00066 typename pcl::PointCloud<PointT>::const_iterator it = pc.points.begin();
00067 if(guess_size_)
00068 {
00069 double maxDist = 0;
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
00098
00099
00100
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
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
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
00155
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
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;
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
00235 index_->setSize(map_size(0),map_size(1),map_size(2));
00236
00237
00238
00239
00240
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
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;
00341 lz->getNDTCellAt(pt,ptCell);
00342 if(ptCell != NULL)
00343 {
00344
00345
00346
00347
00348
00349
00350 ptCell->updateSampleVariance(ucov, umean, numpointsindistribution, true, max_occupancy,maxnumpoints);
00351 ptCell->setRGB(r,g,b);
00352
00353
00354
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
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
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
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
00517
00518 ptCell->updateOccupancy(logoddlik, occupancy_limit);
00519 if(ptCell->getOccupancy()<=0) ptCell->hasGaussian_ = false;
00520 }
00521 else
00522 {
00523
00524 ptCell->updateOccupancy(-0.2, occupancy_limit);
00525 if(ptCell->getOccupancy()<=0) ptCell->hasGaussian_ = false;
00526 }
00527 }
00528
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
00626 ptCell = dynamic_cast<NDTCell<PointT> *> (dataArray[idx][idy][idz]);
00627 }
00628 else
00629 {
00630
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
00701 loadPointCloud(pc);
00702 computeNDTCells();
00703
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
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
00734 lslgeneric::NDTMap<PointT> ndlocal(new lslgeneric::LazyGrid<PointT>(resolution));
00735 ndlocal.loadPointCloudCentroid(pc,origin, old_centroid, localmapsize, 70.0);
00736
00738
00739
00741 ndlocal.computeNDTCells();
00742
00744 std::vector<lslgeneric::NDTCell<PointT>*> ndts;
00745 ndts = ndlocal.getAllCells();
00746
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
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
00797
00798 }
00799
00800
00801 diff = diff/(float)NN;
00802
00803
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
00829
00830
00831
00832
00833
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
00854 double snoise = sigma_dist + sensor_noise;
00855 double thr =exp(-0.5*(l2target*l2target)/(snoise*snoise));
00856 lik *= (1.0-thr);
00857
00858 lik = 0.2*lik+0.5;
00859 double logoddlik = log( (1.0-lik)/(lik) );
00860
00861
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
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
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
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
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
00984
00985
00986 lz->getNDTCellAt(idx,idy,idz,ptCell);
00987
00988
00989
00990
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
01009
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
01022
01023
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
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
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
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
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);
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
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
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
01305 typename std::set<NDTCell<PointT>*>::iterator it = update_set.begin();
01306
01307 while (it != update_set.end())
01308 {
01309
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
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
01348 while (it != index_->end())
01349
01350 {
01351 NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01352
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
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
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
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
01448 return;
01449 }
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 FILE *fout = fopen(filename,"w");
01465 if(fout == NULL)
01466 {
01467
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
01483 return;
01484 }
01485
01486
01487 typename SpatialIndex<PointT>::CellVectorItr it = index_->begin();
01488 while (it != index_->end())
01489 {
01490 NDTCell<PointT> *cell = dynamic_cast<NDTCell<PointT>*> (*it);
01491
01492 if(cell!=NULL)
01493 {
01494 cell->writeToVRML(fout);
01495 }
01496 else
01497 {
01498
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
01511 return;
01512 }
01513
01514
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
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
01554 break;
01555 case 3:
01556 writeLazyGridJFF(jffout);
01557 break;
01558 default:
01559
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
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
01586 if(cell->writeToJFF(jffout) < 0)
01587 return -1;
01588 }
01589 }
01590 else
01591 {
01592
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
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
01619 if(cell->writeToJFF(jffout) < 0)
01620 return -1;
01621 }
01622 }
01623 else
01624 {
01625
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
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
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
01667 if(cell->writeToJFF(jffout) < 0) return -1;
01668
01669 }
01670 else
01671 {
01672
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
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
01835 template<typename PointT>
01836 double NDTMap<PointT>::getLikelihoodForPoint(PointT pt)
01837 {
01838
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
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;
01861 return prob;
01862 }
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
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
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
02051 std::vector<NDTCell<PointT>*> cells;
02052 LazyGrid<PointT> *gr = dynamic_cast<LazyGrid<PointT>*>(index_);
02053 if(gr==NULL)
02054 {
02055
02056 return cells;
02057 }
02058 cells = gr->getClosestNDTCells(pt,n_neigh,checkForGaussian);
02059 return cells;
02060
02061
02062
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
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
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
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 }