49 #include <yaml-cpp/yaml.h>
55 InvalidModuleType::InvalidModuleType(
const std::string& reason):
62 prefilteredReadingPtsCount(0),
63 prefilteredReferencePtsCount(0),
64 maxNumIterationsReached(false)
78 readingDataPointsFilters.clear();
79 readingStepDataPointsFilters.clear();
80 referenceDataPointsFilters.clear();
82 outlierFilters.clear();
84 transformationCheckers.clear();
104 this->
matcher = std::make_shared<typename MatchersImpl<T>::KDTreeMatcher>();
105 this->
errorMinimizer = std::make_shared<PointToPlaneErrorMinimizer<T> >();
108 this->
inspector = std::make_shared<typename InspectorsImpl<T>::NullInspector>();
117 typedef set<string> StringSet;
118 StringSet usedModuleTypes;
127 usedModuleTypes.insert(createModuleFromRegistrar(
"logger", doc, pm.REG(
Logger),
logger));
129 usedModuleTypes.insert(createModulesFromRegistrar(
"readingDataPointsFilters", doc, pm.REG(
DataPointsFilter), readingDataPointsFilters));
130 usedModuleTypes.insert(createModulesFromRegistrar(
"readingStepDataPointsFilters", doc, pm.REG(
DataPointsFilter), readingStepDataPointsFilters));
131 usedModuleTypes.insert(createModulesFromRegistrar(
"referenceDataPointsFilters", doc, pm.REG(
DataPointsFilter), referenceDataPointsFilters));
133 usedModuleTypes.insert(createModuleFromRegistrar(
"matcher", doc, pm.REG(
Matcher),
matcher));
134 usedModuleTypes.insert(createModulesFromRegistrar(
"outlierFilters", doc, pm.REG(
OutlierFilter), outlierFilters));
138 if (nodeVal(
"errorMinimizer", doc) !=
"PointToPointSimilarityErrorMinimizer")
143 usedModuleTypes.insert(createModulesFromRegistrar(
"transformationCheckers", doc, pm.REG(
TransformationChecker), transformationCheckers));
144 usedModuleTypes.insert(createModuleFromRegistrar(
"inspector", doc, pm.REG(
Inspector),
inspector));
151 for(YAML::const_iterator moduleTypeIt = doc.begin(); moduleTypeIt != doc.end(); ++moduleTypeIt)
155 if (usedModuleTypes.find(moduleType) == usedModuleTypes.end())
157 (boost::format(
"Module type %1% does not exist") % moduleType).str()
167 YAML::Node doc = YAML::Load(in);
168 loadFromYamlNode(doc);
175 return prefilteredReadingPtsCount;
182 return prefilteredReferencePtsCount;
189 return maxNumIterationsReached;
197 const YAML::Node reg = doc[regName];
202 for(YAML::const_iterator moduleIt = reg.begin(); moduleIt != reg.end(); ++moduleIt)
204 const YAML::Node& module(*moduleIt);
205 modules.push_back(registrar.createFromYAML(module));
217 const YAML::Node reg = doc[regName];
222 module = registrar.createFromYAML(reg);
233 const YAML::Node reg = doc[regName];
259 return this->compute(readingIn, referenceIn, identity);
269 return this->compute(readingIn, referenceIn, initialTransformationParameters);
281 throw runtime_error(
"You must setup a matcher before running ICP");
283 throw runtime_error(
"You must setup an error minimizer before running ICP");
285 throw runtime_error(
"You must setup an inspector before running ICP");
295 this->referenceDataPointsFilters.init();
296 this->referenceDataPointsFilters.apply(
reference);
300 const int nbPtsReference =
reference.features.cols();
301 const Vector meanReference =
reference.features.rowwise().sum() / nbPtsReference;
303 T_refIn_refMean.block(0,
dim-1,
dim-1, 1) = meanReference.head(
dim-1);
308 reference.features.topRows(
dim-1).colwise() -= meanReference.head(
dim-1);
311 this->
matcher->init(reference);
318 this->prefilteredReferencePtsCount =
reference.features.cols();
320 return computeWithTransformedReference(readingIn,
reference, T_refIn_refMean, T_refIn_dataIn);
334 if (T_refIn_dataIn.cols() != T_refIn_dataIn.rows()) {
335 throw runtime_error(
"The initial transformation matrix must be squared.");
337 if (
dim != T_refIn_dataIn.cols()) {
338 throw runtime_error(
"The shape of initial transformation matrix must be NxN. "
339 "Where N is the number of rows in the read/reference scans.");
348 this->readingDataPointsFilters.init();
349 this->readingDataPointsFilters.apply(
reading);
355 T_refMean_dataIn = T_refIn_refMean.inverse() * T_refIn_dataIn;
359 this->readingStepDataPointsFilters.init();
366 this->maxNumIterationsReached =
false;
367 this->transformationCheckers.init(T_iter, iterate);
369 size_t iterationCount(0);
376 this->prefilteredReadingPtsCount =
reading.features.cols();
386 this->readingStepDataPointsFilters.apply(stepReading);
395 this->
matcher->findClosests(stepReading)
404 assert(outlierWeights.rows() ==
matches.ids.rows());
405 assert(outlierWeights.cols() ==
matches.ids.cols());
413 iterationCount, T_iter,
reference, stepReading,
matches, outlierWeights, this->transformationCheckers
430 this->transformationCheckers.check(T_iter, iterate);
435 this->maxNumIterationsReached =
true;
441 this->
inspector->addStat(
"IterationsCount", iterationCount);
442 this->
inspector->addStat(
"PointCountTouched", this->
matcher->getVisitCount());
443 this->
matcher->resetVisitCount();
448 LOG_INFO_STREAM(
"PointMatcher::icp - " << iterationCount <<
" iterations took " << t.
elapsed() <<
" [s]");
457 return (T_refIn_refMean * T_iter * T_refMean_dataIn);
468 return (mapPointCloud.features.cols() != 0);
477 throw runtime_error(
"You must setup a matcher before running ICP");
479 throw runtime_error(
"You must setup an inspector before running ICP");
483 const int ptCount(inputCloud.
features.cols());
495 mapPointCloud = inputCloud;
499 const Vector meanMap = mapPointCloud.
features.rowwise().sum() / ptCount;
500 T_refIn_refMean = Matrix::Identity(
dim,
dim);
501 T_refIn_refMean.block(0,
dim-1,
dim-1, 1) = meanMap.head(
dim-1);
506 mapPointCloud.features.topRows(
dim-1).colwise() -= meanMap.head(
dim-1);
509 this->referenceDataPointsFilters.init();
510 this->referenceDataPointsFilters.apply(mapPointCloud);
512 this->
matcher->init(mapPointCloud);
523 const int dim(mapPointCloud.features.rows());
524 T_refIn_refMean = Matrix::Identity(
dim,
dim);
533 if(mapPointCloud.getNbPoints() > 0)
535 this->
matcher->init(mapPointCloud);
550 if(mapPointCloud.getNbPoints() > 0)
552 this->
matcher->init(mapPointCloud);
563 const int dim(mapPointCloud.features.rows());
564 const Vector meanMapNonHomo(T_refIn_refMean.block(0,
dim-1,
dim-1, 1));
565 globalMap.
features.topRows(
dim-1).colwise() += meanMapNonHomo;
581 return mapPointCloud;
597 return this->compute(cloudIn, identity);
605 return this->compute(cloudIn, T_dataInOld_dataInNew);
618 return Matrix::Identity(
dim,
dim);
623 return this->computeWithTransformedReference(cloudIn, mapPointCloud, T_refIn_refMean, T_refIn_dataIn);