cell_vector.cpp
Go to the documentation of this file.
00001 #include <climits>
00002 #include <pcl/common/distances.h>
00003 #include <ndt_map/cell_vector.h>
00004 
00005 namespace lslgeneric
00006 {
00007 
00008 CellVector::CellVector():mp(new pcl::PointCloud<pcl::PointXYZ>())
00009 {
00010     pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
00011     protoType= new NDTCell();
00012     treeUpdated = false;
00013 }
00014 
00015 CellVector::CellVector(NDTCell* cellPrototype):mp(new pcl::PointCloud<pcl::PointXYZ>())
00016 {
00017     protoType = cellPrototype->clone();
00018     treeUpdated = false;
00019 }
00020 
00021 CellVector::CellVector(const CellVector& other)
00022 {
00023     for(unsigned int i =0; i< other.activeCells.size(); i++)
00024     {
00025         NDTCell* r = (other.activeCells[i]->copy());
00026         if(r == NULL) continue;
00027         for(size_t i=0; i<r->points_.size(); i++)
00028         {
00029             this->activeCells.push_back(r->copy());
00030         }
00031     }
00032 }
00033 
00034 CellVector::~CellVector()
00035 {
00036     //go through all cells and delete the non-NULL ones
00037     for(unsigned int i=0; i<activeCells.size(); ++i)
00038     {
00039         if(activeCells[i]!=NULL)
00040         {
00041             delete activeCells[i];
00042         }
00043     }
00044 }
00045 
00046 NDTCell* CellVector::getCellForPoint(const pcl::PointXYZ &point)
00047 {
00048     NDTCell* ret = NULL;
00049     if (treeUpdated)
00050     {
00051         std::vector<int> id;
00052         std::vector<float> dist;
00053         int NCELLS = 1;
00054         id.reserve(NCELLS);
00055         dist.reserve(NCELLS);
00056         const pcl::PointXYZ pt(point);
00057         if(!meansTree.nearestKSearch(pt,NCELLS,id,dist)) return ret;
00058 
00059         ret  = activeCells[id[0]];
00060     }
00061     else
00062     {
00063         float min_dist = std::numeric_limits<float>::max( );
00064         typename SpatialIndex::CellVectorItr it = this->begin();
00065         while(it!=this->end())
00066         {
00067             float tmp=pcl::squaredEuclideanDistance((*it)->getCenter(), point);
00068             if (tmp < min_dist)
00069             {
00070                 min_dist = tmp;
00071                 ret = (*it);
00072             }
00073             it++;
00074         }
00075     }
00076     return ret;
00077 }
00078 
00079 NDTCell* CellVector::addPoint(const pcl::PointXYZ &point)
00080 {
00081     return NULL;
00082     // Do nothing...
00083 }
00084 
00085 void CellVector::addCellPoints(pcl::PointCloud<pcl::PointXYZ> pc, const std::vector<size_t> &indices)
00086 {
00087     activeCells.push_back(protoType->clone());
00088     for (size_t i = 0; i < indices.size(); i++) {
00089         (activeCells.back())->addPoint(pc[indices[i]]); // Add the point to the cell.
00090     }
00091     treeUpdated = false;
00092 }
00093 
00094 void CellVector::addCell(NDTCell* cell)
00095 {
00096     activeCells.push_back(cell);
00097 }
00098 
00099 void CellVector::addNDTCell(NDTCell* cell)
00100 {
00101     this->addCell(cell);
00102 }
00103 
00104 typename SpatialIndex::CellVectorItr CellVector::begin()
00105 {
00106     //cout<<"active cells "<<activeCells.size()<<endl;
00107     return activeCells.begin();
00108 }
00109 
00110 typename SpatialIndex::CellVectorItr CellVector::end()
00111 {
00112     return activeCells.end();
00113 }
00114 
00115 int CellVector::size()
00116 {
00117     return activeCells.size();
00118 }
00119 
00120 SpatialIndex* CellVector::clone() const
00121 {
00122     return new CellVector();
00123 }
00124 
00125 SpatialIndex* CellVector::copy() const
00126 {
00127     //std::cout<<"COPY CELL VECTOR\n";
00128     //assert(false); // This needs to be updated!
00129     CellVector *ret = new CellVector();
00130     for(unsigned int i =0; i< activeCells.size(); i++)
00131     {
00132         NDTCell* r = (activeCells[i]->copy());
00133         if(r == NULL) continue;
00134         for(size_t i=0; i<r->points_.size(); i++)
00135         {
00136             ret->activeCells.push_back(r->copy());
00137         }
00138     }
00139     return ret;
00140 }
00141 
00142 void CellVector::getNeighbors(const pcl::PointXYZ &point, const double &radius, std::vector<NDTCell*> &cells)
00143 {
00144 
00145     if (treeUpdated)
00146     {
00147         std::vector<int> id;
00148         std::vector<float> dist;
00149         int NCELLS = 4;
00150         id.reserve(NCELLS);
00151         dist.reserve(NCELLS);
00152         const pcl::PointXYZ pt(point);
00153 
00154         if(!meansTree.nearestKSearch(pt,NCELLS,id,dist)) return;
00155 
00156         for(int i=0; i<NCELLS; i++)
00157         {
00158             NDTCell* tmp = activeCells[id[i]];
00159             if (tmp != NULL)
00160                 cells.push_back(tmp);
00161         }
00162     }
00163     else
00164     {
00165         float radius_sqr = radius*radius;
00166         typename SpatialIndex::CellVectorItr it = this->begin();
00167         while(it!=this->end())
00168         {
00169             float tmp=pcl::squaredEuclideanDistance((*it)->getCenter(), point);
00170             if (tmp < radius_sqr)
00171             {
00172                 cells.push_back(*it);
00173             }
00174         }
00175     }
00176 }
00177 
00178 void CellVector::initKDTree()
00179 {
00180 
00181     NDTCell* ndcell = NULL;
00182     pcl::PointXYZ curr;
00183     Eigen::Vector3d m;
00184     pcl::PointCloud<pcl::PointXYZ> mc;
00185 
00186     for(size_t i=0; i<activeCells.size(); i++)
00187     {
00188         ndcell = (activeCells[i]);
00189         if(ndcell == NULL) continue;
00190         if(!ndcell->hasGaussian_) continue;
00191         m = ndcell->getMean();
00192         curr.x = m(0);
00193         curr.y = m(1);
00194         curr.z = m(2);
00195         mc.push_back(curr);
00196     }
00197 
00198     if(mc.points.size() > 0)
00199     {
00200         *mp = mc;
00201         meansTree.setInputCloud(mp);
00202     }
00203 
00204     //++++++++++++++++++treeUpdated = true;
00205 }
00206 
00207 void CellVector::setCellType(NDTCell *type)
00208 {
00209     if(type!=NULL)
00210     {
00211         protoType = type->clone();
00212     }
00213 }
00214 
00215 NDTCell* CellVector::getClosestNDTCell(const pcl::PointXYZ &point)
00216 {
00217     return getCellForPoint(point);
00218 }
00219 
00220 std::vector<NDTCell*> CellVector::getClosestNDTCells(const pcl::PointXYZ &point, double &radius)
00221 {
00222     std::vector<NDTCell*> ret;
00223     getNeighbors(point, radius, ret);
00224     return ret;
00225 }
00226 
00227 NDTCell* CellVector::getCellIdx(unsigned int idx) const
00228 {
00229     if (idx >= activeCells.size())
00230         return NULL;
00231     return activeCells[idx];
00232 }
00233 
00234 void CellVector::cleanCellsAboveSize(double size)
00235 {
00236     //clean cells with variance more then x meters in any direction
00237     Eigen::Vector3d evals;
00238     lslgeneric::SpatialIndex::CellVectorItr it = this->begin();
00239     lslgeneric::SpatialIndex::CellVectorItr it_tmp;
00240     while(it!=this->end())
00241     {
00242         lslgeneric::NDTCell *ndcell = (*it);
00243         if(ndcell != NULL)
00244         {
00245             if(ndcell->hasGaussian_)
00246             {
00247                 evals = ndcell->getEvals();
00248                 if(sqrt(evals(2)) < size)
00249                 {
00250                     it++;
00251                     continue;
00252                 }
00253                 //std::cout<<"rem cell at "<<ndcell->getMean().transpose()<<" evals are "<<evals.transpose()<<std::endl;
00254                 ndcell->hasGaussian_ = false;
00255             }
00256             delete ndcell;
00257             ndcell = NULL;
00258         }
00259         it_tmp = it;
00260         it_tmp--;
00261         this->activeCells.erase(it);
00262         it = it_tmp;
00263         it++;
00264     }
00265 
00266 }
00267 int CellVector::loadFromJFF(FILE * jffin)
00268 {
00269     NDTCell prototype_;
00270     if(fread(&prototype_, sizeof(NDTCell), 1, jffin) <= 0)
00271     {
00272         JFFERR("reading prototype_ failed");
00273     }
00274     protoType = prototype_.clone();
00275     // load all cells
00276     while (1)
00277     {
00278         if(prototype_.loadFromJFF(jffin) < 0)
00279         {
00280             if(feof(jffin))
00281             {
00282                 break;
00283             }
00284             else
00285             {
00286                 JFFERR("loading cell failed");
00287             }
00288         }
00289 
00290         if(!feof(jffin))
00291         {
00292             // std::cout << prototype_.getOccupancy() << std::endl; /* for debugging */
00293         }
00294         else
00295         {
00296             break;
00297         }
00298         //initialize cell
00299         this->addCell(prototype_.copy());
00300     }
00301 
00302     this->initKDTree();
00303 
00304     return 0;
00305 }
00306 
00307 }


ndt_map
Author(s): Todor Stoyanov, Jari Saarinen, Henrik Andreasson
autogenerated on Wed Aug 26 2015 15:24:40