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
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
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]]);
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
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
00128
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
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
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
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
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
00293 }
00294 else
00295 {
00296 break;
00297 }
00298
00299 this->addCell(prototype_.copy());
00300 }
00301
00302 this->initKDTree();
00303
00304 return 0;
00305 }
00306
00307 }