39 #include <pcl/conversions.h> 41 #ifdef RTABMAP_POINTMATCHER 43 #include "pointmatcher/PointMatcher.h" 44 typedef PointMatcher<float> PM;
45 typedef PM::DataPoints DP;
47 DP pclToDP(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & pclCloud,
bool is2D)
50 typedef DP::Label Label;
51 typedef DP::Labels Labels;
52 typedef DP::View View;
54 if (pclCloud->empty())
62 std::vector<bool> isFeature;
63 featLabels.push_back(Label(
"x", 1));
64 isFeature.push_back(
true);
65 featLabels.push_back(Label(
"y", 1));
66 isFeature.push_back(
true);
69 featLabels.push_back(Label(
"z", 1));
70 isFeature.push_back(
true);
72 featLabels.push_back(Label(
"pad", 1));
75 DP cloud(featLabels, descLabels, pclCloud->size());
76 cloud.getFeatureViewByName(
"pad").setConstant(1);
79 View view(cloud.getFeatureViewByName(
"x"));
80 for(
unsigned int i=0; i<pclCloud->size(); ++i)
82 view(0, i) = pclCloud->at(i).x;
83 view(1, i) = pclCloud->at(i).y;
86 view(2, i) = pclCloud->at(i).z;
93 DP pclToDP(
const pcl::PointCloud<pcl::PointNormal>::Ptr & pclCloud,
bool is2D)
96 typedef DP::Label Label;
97 typedef DP::Labels Labels;
98 typedef DP::View View;
100 if (pclCloud->empty())
108 std::vector<bool> isFeature;
109 featLabels.push_back(Label(
"x", 1));
110 isFeature.push_back(
true);
111 featLabels.push_back(Label(
"y", 1));
112 isFeature.push_back(
true);
115 featLabels.push_back(Label(
"z", 1));
116 isFeature.push_back(
true);
119 descLabels.push_back(Label(
"normals", 3));
120 isFeature.push_back(
false);
121 isFeature.push_back(
false);
122 isFeature.push_back(
false);
124 featLabels.push_back(Label(
"pad", 1));
127 DP cloud(featLabels, descLabels, pclCloud->size());
128 cloud.getFeatureViewByName(
"pad").setConstant(1);
131 View view(cloud.getFeatureViewByName(
"x"));
132 View viewNormalX(cloud.getDescriptorRowViewByName(
"normals",0));
133 View viewNormalY(cloud.getDescriptorRowViewByName(
"normals",1));
134 View viewNormalZ(cloud.getDescriptorRowViewByName(
"normals",2));
135 for(
unsigned int i=0; i<pclCloud->size(); ++i)
137 view(0, i) = pclCloud->at(i).x;
138 view(1, i) = pclCloud->at(i).y;
141 view(2, i) = pclCloud->at(i).z;
143 viewNormalX(0, i) = pclCloud->at(i).normal_x;
144 viewNormalY(0, i) = pclCloud->at(i).normal_y;
145 viewNormalZ(0, i) = pclCloud->at(i).normal_z;
154 typedef DP::Label Label;
155 typedef DP::Labels Labels;
156 typedef DP::View View;
166 featLabels.push_back(Label(
"x", 1));
167 featLabels.push_back(Label(
"y", 1));
170 featLabels.push_back(Label(
"z", 1));
172 featLabels.push_back(Label(
"pad", 1));
176 descLabels.push_back(Label(
"normals", 3));
180 descLabels.push_back(Label(
"intensity", 1));
184 DP cloud(featLabels, descLabels, scan.
size());
185 cloud.getFeatureViewByName(
"pad").setConstant(1);
193 View view(cloud.getFeatureViewByName(
"x"));
194 View viewNormalX(nx!=-1?cloud.getDescriptorRowViewByName(
"normals",0):view);
195 View viewNormalY(nx!=-1?cloud.getDescriptorRowViewByName(
"normals",1):view);
196 View viewNormalZ(nx!=-1?cloud.getDescriptorRowViewByName(
"normals",2):view);
197 View viewIntensity(offsetI!=-1?cloud.getDescriptorRowViewByName(
"intensity",0):view);
199 for(
int i=0; i<scan.
size(); ++i)
201 const float * ptr = scan.
data().ptr<
float>(0, i);
205 if(hasLocalTransform)
209 cv::Point3f pt(ptr[0], ptr[1], scan.
is2d()?0:ptr[2]);
219 viewIntensity(0, oi) = ptr[offsetI];
228 pt.z=scan.
is2d()?0:ptr[2];
239 viewNormalX(0, oi) = pt.normal_x;
240 viewNormalY(0, oi) = pt.normal_y;
241 viewNormalZ(0, oi) = pt.normal_z;
245 viewIntensity(0, oi) = ptr[offsetI];
252 UWARN(
"Ignoring point %d with invalid data: pos=%f %f %f, normal=%f %f %f", i, ptr[0], ptr[1], scan.
is2d()?0:ptr[3], ptr[nx], ptr[ny], ptr[nz]);
257 view(0, oi) = ptr[0];
258 view(1, oi) = ptr[1];
261 view(2, oi) = ptr[2];
265 viewNormalX(0, oi) = ptr[nx];
266 viewNormalY(0, oi) = ptr[ny];
267 viewNormalZ(0, oi) = ptr[nz];
271 viewIntensity(0, oi) = ptr[offsetI];
277 UWARN(
"Ignoring point %d with invalid data: pos=%f %f %f, normal=%f %f %f", i, ptr[0], ptr[1], scan.
is2d()?0:ptr[3], ptr[nx], ptr[ny], ptr[nz]);
282 UWARN(
"Ignoring point %d with invalid data: pos=%f %f %f", i, ptr[0], ptr[1], scan.
is2d()?0:ptr[3]);
286 if(oi != scan.
size())
288 cloud.conservativeResize(oi);
294 void pclFromDP(
const DP & cloud, pcl::PointCloud<pcl::PointXYZ> & pclCloud)
297 typedef DP::ConstView ConstView;
299 if (cloud.features.cols() == 0)
302 pclCloud.resize(cloud.features.cols());
303 pclCloud.is_dense =
true;
306 ConstView view(cloud.getFeatureViewByName(
"x"));
307 bool is3D = cloud.featureExists(
"z");
308 for(
unsigned int i=0; i<pclCloud.size(); ++i)
310 pclCloud.at(i).x = view(0, i);
311 pclCloud.at(i).y = view(1, i);
312 pclCloud.at(i).z = is3D?view(2, i):0;
316 void pclFromDP(
const DP & cloud, pcl::PointCloud<pcl::PointNormal> & pclCloud)
319 typedef DP::ConstView ConstView;
321 if (cloud.features.cols() == 0)
324 pclCloud.resize(cloud.features.cols());
325 pclCloud.is_dense =
true;
328 ConstView view(cloud.getFeatureViewByName(
"x"));
329 bool is3D = cloud.featureExists(
"z");
330 ConstView viewNormalX(cloud.getDescriptorRowViewByName(
"normals",0));
331 ConstView viewNormalY(cloud.getDescriptorRowViewByName(
"normals",1));
332 ConstView viewNormalZ(cloud.getDescriptorRowViewByName(
"normals",2));
333 for(
unsigned int i=0; i<pclCloud.size(); ++i)
335 pclCloud.at(i).x = view(0, i);
336 pclCloud.at(i).y = view(1, i);
337 pclCloud.at(i).z = is3D?view(2, i):0;
338 pclCloud.at(i).normal_x = viewNormalX(0, i);
339 pclCloud.at(i).normal_y = viewNormalY(0, i);
340 pclCloud.at(i).normal_z = viewNormalZ(0, i);
345 typename PointMatcher<T>::TransformationParameters eigenMatrixToDim(
const typename PointMatcher<T>::TransformationParameters& matrix,
int dimp1)
347 typedef typename PointMatcher<T>::TransformationParameters M;
348 assert(matrix.rows() == matrix.cols());
349 assert((matrix.rows() == 3) || (matrix.rows() == 4));
350 assert((dimp1 == 3) || (dimp1 == 4));
352 if (matrix.rows() == dimp1)
355 M out(M::Identity(dimp1,dimp1));
356 out.topLeftCorner(2,2) = matrix.topLeftCorner(2,2);
357 out.topRightCorner(2,1) = matrix.topRightCorner(2,1);
367 _maxTranslation(
Parameters::defaultIcpMaxTranslation()),
368 _maxRotation(
Parameters::defaultIcpMaxRotation()),
369 _voxelSize(
Parameters::defaultIcpVoxelSize()),
370 _downsamplingStep(
Parameters::defaultIcpDownsamplingStep()),
371 _maxCorrespondenceDistance(
Parameters::defaultIcpMaxCorrespondenceDistance()),
372 _maxIterations(
Parameters::defaultIcpIterations()),
374 _correspondenceRatio(
Parameters::defaultIcpCorrespondenceRatio()),
375 _pointToPlane(
Parameters::defaultIcpPointToPlane()),
376 _pointToPlaneK(
Parameters::defaultIcpPointToPlaneK()),
377 _pointToPlaneRadius(
Parameters::defaultIcpPointToPlaneRadius()),
378 _pointToPlaneMinComplexity(
Parameters::defaultIcpPointToPlaneMinComplexity()),
380 _libpointmatcherConfig(
Parameters::defaultIcpPMConfig()),
381 _libpointmatcherKnn(
Parameters::defaultIcpPMMatcherKnn()),
382 _libpointmatcherEpsilon(
Parameters::defaultIcpPMMatcherEpsilon()),
383 _libpointmatcherOutlierRatio(
Parameters::defaultIcpPMOutlierRatio()),
384 _libpointmatcherICP(0)
391 #ifdef RTABMAP_POINTMATCHER 420 #ifndef RTABMAP_POINTMATCHER 423 UWARN(
"Parameter %s is set to true but RTAB-Map has not been built with libpointmatcher support. Setting to false.", Parameters::kIcpPM().c_str());
440 bool useDefaults =
true;
447 icp->loadFromYaml(ifs);
461 icp->readingDataPointsFilters.clear();
462 icp->readingDataPointsFilters.push_back(PM::get().DataPointsFilterRegistrar.create(
"IdentityDataPointsFilter"));
464 icp->referenceDataPointsFilters.clear();
465 icp->referenceDataPointsFilters.push_back(PM::get().DataPointsFilterRegistrar.create(
"IdentityDataPointsFilter"));
467 PM::Parameters params;
471 icp->matcher.reset(PM::get().MatcherRegistrar.create(
"KDTreeMatcher", params));
475 icp->outlierFilters.clear();
476 icp->outlierFilters.push_back(PM::get().OutlierFilterRegistrar.create(
"TrimmedDistOutlierFilter", params));
481 icp->outlierFilters.push_back(PM::get().OutlierFilterRegistrar.create(
"SurfaceNormalOutlierFilter", params));
485 icp->errorMinimizer.reset(PM::get().ErrorMinimizerRegistrar.create(
"PointToPlaneErrorMinimizer", params));
490 icp->errorMinimizer.reset(PM::get().ErrorMinimizerRegistrar.create(
"PointToPointErrorMinimizer"));
493 icp->transformationCheckers.clear();
495 icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create(
"CounterTransformationChecker", params));
501 icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create(
"DifferentialTransformationChecker", params));
506 icp->transformationCheckers.push_back(PM::get().TransformationCheckerRegistrar.create(
"BoundTransformationChecker", params));
547 UDEBUG(
"size from=%d (format=%d, max pts=%d) to=%d (format=%d, max pts=%d)",
567 if(fromScan.
size() && toScan.
size())
570 bool hasConverged =
false;
571 float correspondencesRatio = 0.0f;
572 int correspondences = 0;
573 double variance = 1.0;
574 bool transformComputed =
false;
575 bool tooLowComplexityForPlaneToPlane =
false;
576 cv::Mat complexityVectors;
586 cv::Mat complexityVectorsFrom, complexityVectorsTo;
589 float complexity = fromComplexity<toComplexity?fromComplexity:toComplexity;
593 tooLowComplexityForPlaneToPlane =
true;
594 complexityVectors = fromComplexity<toComplexity?complexityVectorsFrom:complexityVectorsTo;
595 UWARN(
"ICP PointToPlane ignored as structural complexity is too low (corridor-like environment): %f < %f (%s). PointToPoint is done instead.", complexity,
_pointToPlaneMinComplexity, Parameters::kIcpPointToPlaneMinComplexity().c_str());
607 pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormalsRegistered(
new pcl::PointCloud<pcl::PointNormal>());
608 #ifdef RTABMAP_POINTMATCHER 612 DP data = laserScanToDP(fromScan);
616 PM::TransformationParameters T;
621 UDEBUG(
"libpointmatcher icp... (if there is a seg fault here, make sure all third party libraries are built with same Eigen version.)");
623 icpT =
Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
626 float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
627 UDEBUG(
"match ratio: %f", matchRatio);
635 catch(
const std::exception &
e)
637 msg =
uFormat(
"libpointmatcher has failed: %s", e.what());
649 *fromCloudNormalsRegistered,
654 if(!icpT.
isNull() && hasConverged)
657 fromCloudNormalsRegistered,
664 transformComputed =
true;
668 int maxLaserScansFrom = fromScan.
maxPoints();
669 int maxLaserScansTo = toScan.
maxPoints();
670 if(!transformComputed)
676 pcl::PointCloud<pcl::PointXYZ>::Ptr fromCloudFiltered = fromCloud;
677 pcl::PointCloud<pcl::PointXYZ>::Ptr toCloudFiltered = toCloud;
680 float pointsBeforeFiltering = (float)fromCloudFiltered->size();
682 float ratioFrom = float(fromCloudFiltered->size()) / pointsBeforeFiltering;
683 maxLaserScansFrom = int(
float(maxLaserScansFrom) * ratioFrom);
685 pointsBeforeFiltering = (float)toCloudFiltered->size();
687 float ratioTo = float(toCloudFiltered->size()) / pointsBeforeFiltering;
688 maxLaserScansTo = int(
float(maxLaserScansTo) * ratioTo);
690 UDEBUG(
"Voxel filtering time (voxel=%f m, ratioFrom=%f->%d/%d ratioTo=%f->%d/%d) = %f s",
693 (
int)fromCloudFiltered->size(),
696 (int)toCloudFiltered->size(),
701 pcl::PointCloud<pcl::PointXYZ>::Ptr fromCloudRegistered(
new pcl::PointCloud<pcl::PointXYZ>());
703 !tooLowComplexityForPlaneToPlane &&
707 pcl::PointCloud<pcl::Normal>::Ptr normalsFrom;
733 Eigen::Vector3f viewpointTo(toT.
x(), toT.
y(), toT.
z());
734 pcl::PointCloud<pcl::Normal>::Ptr normalsTo;
759 cv::Mat complexityVectorsFrom, complexityVectorsTo;
762 float complexity = fromComplexity<toComplexity?fromComplexity:toComplexity;
766 tooLowComplexityForPlaneToPlane =
true;
767 complexityVectors = fromComplexity<toComplexity?complexityVectorsFrom:complexityVectorsTo;
768 UWARN(
"ICP PointToPlane ignored as structural complexity is too low (corridor-like environment): %f < %f (%s). PointToPoint is done instead.", complexity,
_pointToPlaneMinComplexity, Parameters::kIcpPointToPlaneMinComplexity().c_str());
772 pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormals(
new pcl::PointCloud<pcl::PointNormal>);
773 pcl::concatenateFields(*fromCloudFiltered, *normalsFrom, *fromCloudNormals);
775 pcl::PointCloud<pcl::PointNormal>::Ptr toCloudNormals(
new pcl::PointCloud<pcl::PointNormal>);
776 pcl::concatenateFields(*toCloudFiltered, *normalsTo, *toCloudNormals);
778 std::vector<int> indices;
823 UDEBUG(
"Compute normals (%d,%d) time = %f s", (
int)fromCloudNormals->size(), (int)toCloudNormals->size(), timer.
ticks());
827 if(toCloudNormals->size() && fromCloudNormals->size())
829 pcl::PointCloud<pcl::PointNormal>::Ptr fromCloudNormalsRegistered(
new pcl::PointCloud<pcl::PointNormal>());
831 #ifdef RTABMAP_POINTMATCHER 835 DP data = laserScanToDP(fromScan);
839 PM::TransformationParameters T;
844 UDEBUG(
"libpointmatcher icp... (if there is a seg fault here, make sure all third party libraries are built with same Eigen version.)");
846 UDEBUG(
"libpointmatcher icp...done!");
847 icpT =
Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
849 float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
850 UDEBUG(
"match ratio: %f", matchRatio);
858 catch(
const std::exception &
e)
860 msg =
uFormat(
"libpointmatcher has failed: %s", e.what());
872 *fromCloudNormalsRegistered,
877 if(!icpT.
isNull() && hasConverged)
880 fromCloudNormalsRegistered,
888 transformComputed =
true;
892 if(!transformComputed)
896 UWARN(
"ICP PointToPlane ignored for 2d scans with PCL registration (some crash issues). Use libpointmatcher (%s) or disable %s to avoid this warning.", Parameters::kIcpPM().c_str(), Parameters::kIcpPointToPlane().c_str());
899 if(
_voxelSize > 0.0
f || !tooLowComplexityForPlaneToPlane)
946 #ifdef RTABMAP_POINTMATCHER 950 DP data = laserScanToDP(fromScan);
954 PM::TransformationParameters T;
959 UDEBUG(
"libpointmatcher icp... (if there is a seg fault here, make sure all third party libraries are built with same Eigen version.)");
963 PM::ICP & icpTmp =
icp;
964 icpTmp.errorMinimizer.reset(PM::get().ErrorMinimizerRegistrar.create(
"PointToPointErrorMinimizer"));
966 for(PM::OutlierFilters::iterator iter=icpTmp.outlierFilters.begin(); iter!=icpTmp.outlierFilters.end();)
968 if((*iter)->className.compare(
"SurfaceNormalOutlierFilter") == 0)
970 iter = icpTmp.outlierFilters.erase(iter);
978 T = icpTmp(data, ref);
984 UDEBUG(
"libpointmatcher icp...done!");
985 icpT =
Transform::fromEigen3d(Eigen::Affine3d(Eigen::Matrix4d(eigenMatrixToDim<double>(T.template cast<double>(), 4))));
987 float matchRatio = icp.errorMinimizer->getWeightedPointUsedRatio();
988 UDEBUG(
"match ratio: %f", matchRatio);
996 catch(
const std::exception &
e)
998 msg =
uFormat(
"libpointmatcher has failed: %s", e.what());
1010 *fromCloudRegistered,
1015 if(!icpT.
isNull() && hasConverged)
1017 if(tooLowComplexityForPlaneToPlane)
1021 Eigen::Vector3f v(t.
x(), t.
y(), t.
z());
1022 if(complexityVectors.cols == 2)
1025 Eigen::Vector3f n(complexityVectors.at<
float>(0,0), complexityVectors.at<
float>(0,1), 0.0f);
1029 else if(complexityVectors.rows == 3)
1032 Eigen::Vector3f n1(complexityVectors.at<
float>(0,0), complexityVectors.at<
float>(0,1), complexityVectors.at<
float>(0,2));
1033 Eigen::Vector3f n2(complexityVectors.at<
float>(1,0), complexityVectors.at<
float>(1,1), complexityVectors.at<
float>(1,2));
1034 float a = v.dot(n1);
1035 float b = v.dot(n2);
1041 UWARN(
"not supposed to be here!");
1042 v = Eigen::Vector3f(0,0,0);
1046 t =
Transform(v[0], v[1], v[2], roll, pitch, yaw);
1047 icpT = guess * t.
inverse() * guessInv;
1056 fromCloudNormalsRegistered,
1066 fromCloudRegistered,
1076 fromCloudRegistered,
1087 if(!icpT.
isNull() && hasConverged)
1089 float ix,iy,iz, iroll,ipitch,iyaw;
1100 msg =
uFormat(
"Cannot compute transform (ICP correction too large -> %f m %f rad, limits=%f m, %f rad)",
1110 int maxLaserScans = maxLaserScansTo?maxLaserScansTo:maxLaserScansFrom;
1111 UDEBUG(
"Max scans=%d (from=%d, to=%d)", maxLaserScans, maxLaserScansFrom, maxLaserScansTo);
1115 correspondencesRatio = float(correspondences)/float(maxLaserScans);
1119 static bool warningShown =
false;
1122 UWARN(
"Maximum laser scans points not set for signature %d, correspondences ratio set relative instead of absolute! This message will only appear once.",
1124 warningShown =
true;
1126 correspondencesRatio = float(correspondences)/float(toScan.
size()>fromScan.
size()?toScan.
size():fromScan.
size());
1131 UDEBUG(
"%d->%d hasConverged=%s, variance=%f, correspondences=%d/%d (%f%%), from guess: trans=%f rot=%f",
1132 dataTo.
id(), dataFrom.
id(),
1133 hasConverged?
"true":
"false",
1136 maxLaserScans>0?maxLaserScans:(int)(toScan.
size()>fromScan.
size()?toScan.
size():fromScan.
size()),
1137 correspondencesRatio*100.0
f,
1141 if(correspondences == 0)
1143 UERROR(
"Transform is found but no correspondences has been found!? Variance is unknown!");
1147 info.
covariance = cv::Mat::eye(6,6,CV_64FC1)*variance;
1153 msg =
uFormat(
"Cannot compute transform (cor=%d corrRatio=%f/%f maxLaserScans=%d)",
1159 transform = icpT.
inverse()*guess;
1167 msg =
uFormat(
"Cannot compute transform (converged=%s var=%f)",
1168 hasConverged?
"true":
"false", variance);
1175 msg =
"Laser scans empty ?!?";
1183 msg =
"RegistrationIcp cannot do registration with a null guess.";
1187 msg =
uFormat(
"Laser scans empty?!? (new[%d]=%d old[%d]=%d)",
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 &cloud, bool filterNaNs=true)
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
const cv::Mat & data() const
pcl::PointCloud< pcl::Normal >::Ptr RTABMAP_EXP computeNormals2D(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, int searchK=5, float searchRadius=0.0f, const Eigen::Vector3f &viewPoint=Eigen::Vector3f(0, 0, 0))
RegistrationIcp(const ParametersMap ¶meters=ParametersMap(), Registration *child=0)
void * _libpointmatcherICP
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
Transform RTABMAP_EXP icpPointToPlane(const pcl::PointCloud< pcl::PointNormal >::ConstPtr &cloud_source, const pcl::PointCloud< pcl::PointNormal >::ConstPtr &cloud_target, double maxCorrespondenceDistance, int maximumIterations, bool &hasConverged, pcl::PointCloud< pcl::PointNormal > &cloud_source_registered, float epsilon=0.0f, bool icp2D=false)
GLM_FUNC_DECL genType e()
std::map< std::string, std::string > ParametersMap
void RTABMAP_EXP computeVarianceAndCorrespondences(const pcl::PointCloud< pcl::PointNormal >::ConstPtr &cloudA, const pcl::PointCloud< pcl::PointNormal >::ConstPtr &cloudB, double maxCorrespondenceDistance, double maxCorrespondenceAngle, double &variance, int &correspondencesOut)
int getNormalsOffset() const
Basic mathematics functions.
Some conversion functions.
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
pcl::PointCloud< pcl::Normal >::Ptr RTABMAP_EXP computeFastOrganizedNormals2D(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, int searchK=5, float searchRadius=0.0f, const Eigen::Vector3f &viewPoint=Eigen::Vector3f(0, 0, 0))
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP laserScanToPointCloud(const LaserScan &laserScan, const Transform &transform=Transform())
LaserScan RTABMAP_EXP downsample(const LaserScan &cloud, int step)
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud< pcl::PointXYZ > &cloud, const Transform &transform=Transform(), bool filterNaNs=true)
bool uIsFinite(const T &value)
#define UASSERT(condition)
float _maxCorrespondenceDistance
float _correspondenceRatio
T uMax3(const T &a, const T &b, const T &c)
virtual ~RegistrationIcp()
#define UASSERT_MSG(condition, msg_str)
Transform RTABMAP_EXP icp(const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &cloud_source, const pcl::PointCloud< pcl::PointXYZ >::ConstPtr &cloud_target, double maxCorrespondenceDistance, int maximumIterations, bool &hasConverged, pcl::PointCloud< pcl::PointXYZ > &cloud_source_registered, float epsilon=0.0f, bool icp2D=false)
float _pointToPlaneRadius
virtual void parseParameters(const ParametersMap ¶meters)
cv::Mat RTABMAP_EXP computeNormals(const cv::Mat &laserScan, int searchK, float searchRadius)
Transform localTransform() const
float _libpointmatcherOutlierRatio
int getIntensityOffset() const
float RTABMAP_EXP computeNormalsComplexity(const LaserScan &scan, cv::Mat *pcaEigenVectors=0, cv::Mat *pcaEigenValues=0)
float _pointToPlaneMinComplexity
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
SensorData & sensorData()
float icpStructuralComplexity
pcl::PointCloud< pcl::PointNormal >::Ptr RTABMAP_EXP laserScanToPointCloudNormal(const LaserScan &laserScan, const Transform &transform=Transform())
ULogger class and convenient macros.
float _libpointmatcherEpsilon
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
pcl::PointCloud< pcl::PointNormal >::Ptr RTABMAP_EXP removeNaNNormalsFromPointCloud(const pcl::PointCloud< pcl::PointNormal >::Ptr &cloud)
virtual Transform computeTransformationImpl(Signature &from, Signature &to, Transform guess, RegistrationInfo &info) const
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
virtual void parseParameters(const ParametersMap ¶meters)
std::string _libpointmatcherConfig
bool hasIntensity() const
void setLaserScanRaw(const LaserScan &laserScanRaw)
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)