63 CPosePDFPtr resultPDF;
65 if (runningTime) tictac.Tic();
67 switch( options.ICP_algorithm )
70 resultPDF = ICP_Method_Classic( m1, mm2, initialEstimationPDF, outInfo );
73 resultPDF = ICP_Method_LM( m1, mm2, initialEstimationPDF, outInfo );
76 THROW_EXCEPTION_FMT(
"Invalid value for ICP_algorithm: %i", static_cast<int>(options.ICP_algorithm));
79 if (runningTime) *runningTime = tictac.Tac();
96 onlyClosestCorrespondences ( true ),
97 onlyUniqueRobust ( false ),
99 minAbsStep_trans ( 1e-6f ),
100 minAbsStep_rot ( 1e-6f ),
101 thresholdDist ( 0.75f ),
102 thresholdAng (
DEG2RAD(0.15f) ),
104 smallestThresholdDist ( 0.10f ),
105 covariance_varPoints (
square(0.02f) ),
108 ransac_minSetSize ( 3 ),
109 ransac_maxSetSize ( 20 ),
110 ransac_nSimulations ( 100 ),
113 ransac_fuseByCorrsMatch ( true ),
114 ransac_fuseMaxDiffXY ( 0.01f ),
115 ransac_fuseMaxDiffPhi (
DEG2RAD(0.1f) ),
117 kernel_rho ( 0.07f ),
119 Axy_aprox_derivatives ( 0.05f ),
121 LM_initial_lambda ( 1e-4f ),
123 skip_cov_calculation (false),
124 skip_quality_calculation (true),
126 corresponding_points_decimation ( 5 )
161 ransac_fuseMaxDiffPhi =
DEG2RAD( iniFile.
read_float(section.c_str(),
"ransac_fuseMaxDiffPhi_DEG",
RAD2DEG(ransac_fuseMaxDiffPhi)) );
180 out.
printf(
"\n----------- [CICP::TConfigParams] ------------ \n\n");
184 out.
printf(
"maxIterations = %i\n",maxIterations);
185 out.
printf(
"minAbsStep_trans = %f\n",minAbsStep_trans);
186 out.
printf(
"minAbsStep_rot = %f\n",minAbsStep_rot);
188 out.
printf(
"thresholdDist = %f\n",thresholdDist);
190 out.
printf(
"ALFA = %f\n",ALFA);
191 out.
printf(
"smallestThresholdDist = %f\n",smallestThresholdDist);
192 out.
printf(
"onlyClosestCorrespondences = %c\n",onlyClosestCorrespondences ?
'Y':
'N');
193 out.
printf(
"onlyUniqueRobust = %c\n",onlyUniqueRobust ?
'Y':
'N');
194 out.
printf(
"covariance_varPoints = %f\n",covariance_varPoints);
195 out.
printf(
"doRANSAC = %c\n",doRANSAC ?
'Y':
'N');
196 out.
printf(
"ransac_minSetSize = %i\n",ransac_minSetSize);
197 out.
printf(
"ransac_maxSetSize = %i\n",ransac_maxSetSize);
199 out.
printf(
"ransac_nSimulations = %i\n",ransac_nSimulations);
200 out.
printf(
"ransac_fuseByCorrsMatch = %c\n",ransac_fuseByCorrsMatch ?
'Y':
'N');
201 out.
printf(
"ransac_fuseMaxDiffXY = %f\n",ransac_fuseMaxDiffXY);
202 out.
printf(
"ransac_fuseMaxDiffPhi = %f deg\n",
RAD2DEG( ransac_fuseMaxDiffPhi ));
204 out.
printf(
"kernel_rho = %f\n",kernel_rho);
205 out.
printf(
"use_kernel = %c\n",use_kernel ?
'Y':
'N');
206 out.
printf(
"Axy_aprox_derivatives = %f\n",Axy_aprox_derivatives );
207 out.
printf(
"LM_initial_lambda = %f\n",LM_initial_lambda);
208 out.
printf(
"skip_cov_calculation = %c\n",skip_cov_calculation ?
'Y':
'N');
209 out.
printf(
"skip_quality_calculation = %c\n",skip_quality_calculation ?
'Y':
'N');
210 out.
printf(
"corresponding_points_decimation = %u\n",(
unsigned int)corresponding_points_decimation);
236 CPosePDFPtr resultPDF;
237 CPosePDFGaussianPtr gaussPdf;
240 size_t nCorrespondences=0;
241 bool keepApproaching;
261 gaussPdf = CPosePDFGaussian::Create();
264 gaussPdf->mean = grossEst;
297 matchParams, matchExtraResults);
299 nCorrespondences = correspondences.size();
305 if ( !nCorrespondences )
308 keepApproaching =
false;
322 keepApproaching =
true;
330 keepApproaching =
false;
337 lastMeanPose = gaussPdf->mean;
377 Eigen::Matrix<double,3,Eigen::Dynamic> D(3,nCorrespondences);
379 const TPose2D transf( gaussPdf->mean );
381 double ccos = cos(transf.
phi);
382 double csin = sin(transf.
phi);
393 for (i=0, it=correspondences.begin();i<nCorrespondences; ++i, ++it)
395 float other_x_trans = transf.
x + ccos * it->other_x - csin * it->other_y;
396 float other_y_trans = transf.
y + csin * it->other_x + ccos * it->other_y;
400 w1= other_x_trans-Axy;
406 w3= other_x_trans+Axy;
410 A=( (q3-q2)/((w3-
w2)*(w3-
w1)) ) - ( (q1-q2)/((
w1-
w2)*(w3-
w1)) );
413 D(0,i) = (2*A*other_x_trans)+B;
417 w1= other_y_trans-Axy;
423 w3= other_y_trans+Axy;
427 A=( (q3-q2)/((w3-
w2)*(w3-
w1)) ) - ( (q1-q2)/((
w1-
w2)*(w3-
w1)) );
430 D(1,i) = (2*A*other_y_trans)+B;
434 D(2,i) = D(0,i) * ( -csin * it->other_x - ccos * it->other_y ) +
435 D(1,i) * ( ccos * it->other_x - csin * it->other_y );
442 for (i=0;i<3;i++) DDt( i,i ) += 1e-6;
444 DDt.inv(gaussPdf->cov);
475 matchParams, matchExtraResults);
482 matchParams, matchExtraResults);
489 matchParams, matchExtraResults);
496 matchParams, matchExtraResults);
502 matchParams, matchExtraResults);
505 outInfo.
quality= -max(EX1-E0, max(EX2-E0, max(EY1-E0 , EY2-E0 ) ) )/(E0+1e-1);
524 params.ransac_algorithmForLandmarks =
false;
529 SOG = CPosePDFSOG::Create();
538 resultPDF = gaussPdf;
564 size_t nCorrespondences=0;
565 bool keepIteratingICP;
569 std::vector<float> other_xs_trans,other_ys_trans;
622 m1->determineMatching2D(
626 matchParams, matchExtraResults);
628 nCorrespondences = correspondences.size();
631 if ( !nCorrespondences )
634 keepIteratingICP =
false;
640 dJ_dq.setSize(3,nCorrespondences);
644 double ccos = cos(
q.phi());
645 double csin = sin(
q.phi());
653 std::vector<float> sq_errors;
655 double OSE_initial =
math::sum( sq_errors );
665 it=correspondences.begin(),
666 other_x_trans = other_xs_trans.begin(),
667 other_y_trans = other_ys_trans.begin();
669 ++i, ++it,++other_x_trans,++other_y_trans )
675 #ifndef ICP_DISTANCES_TO_LINE 676 w1= *other_x_trans-Axy;
677 q1 = m1->squareDistanceToClosestCorrespondence(
w1, *other_y_trans );
681 q2 = m1->squareDistanceToClosestCorrespondence(
w2, *other_y_trans );
684 w3= *other_x_trans+Axy;
685 q3 = m1->squareDistanceToClosestCorrespondence( w3, *other_y_trans );
689 float x1,y1, x2,y2, d1,d2;
690 m1->kdTreeTwoClosestPoint2D(
691 *other_x_trans, *other_y_trans,
696 w1= *other_x_trans-Axy;
704 w3= *other_x_trans+Axy;
709 A=( (q3-q2)/((w3-
w2)*(w3-
w1)) ) - ( (q1-q2)/((
w1-
w2)*(w3-
w1)) );
712 dJ_dq.get_unsafe(0,i) = (2*A* *other_x_trans)+B;
716 w1= *other_y_trans-Axy;
717 #ifdef ICP_DISTANCES_TO_LINE 729 w3= *other_y_trans+Axy;
730 #ifdef ICP_DISTANCES_TO_LINE 738 A=( (q3-q2)/((w3-
w2)*(w3-
w1)) ) - ( (q1-q2)/((
w1-
w2)*(w3-
w1)) );
741 dJ_dq.get_unsafe(1,i) = (2*A* *other_y_trans)+B;
745 dJ_dq.get_unsafe(2,i) = dJ_dq.get_unsafe(0,i) * ( -csin * it->other_x - ccos * it->other_y ) +
746 dJ_dq.get_unsafe(1,i) * ( ccos * it->other_x - csin * it->other_y );
754 H_.multiply_AAt(dJ_dq);
758 bool keepIteratingLM =
true;
765 std::vector<float> new_sq_errors, new_other_xs_trans, new_other_ys_trans;
767 const size_t maxLMiters = 100;
769 while ( keepIteratingLM && ++nLMiters<maxLMiters)
776 C(i,i) *= (1+lambda);
781 Eigen::VectorXf dJsq, LM_delta;
782 dJ_dq.multiply_Ab( Eigen::Map<Eigen::VectorXf>(&sq_errors[0],sq_errors.size()), dJsq );
783 C_inv.multiply_Ab(dJsq,LM_delta);
785 q_new.
x(
q.x() - LM_delta[0] );
786 q_new.
y(
q.y() - LM_delta[1] );
787 q_new.
phi(
q.phi() - LM_delta[2] );
797 float OSE_new =
math::sum( new_sq_errors );
799 bool improved = OSE_new < OSE_initial;
802 cout <<
"_____________" << endl;
803 cout <<
"q -> q_new : " <<
q <<
" -> " << q_new << endl;
804 printf(
"err: %f -> %f lambda: %e\n", OSE_initial ,OSE_new, lambda );
819 OSE_initial = OSE_new;
830 cout <<
"ICP loop: " << lastMeanPose <<
" -> " <<
q <<
" LM iters: " << nLMiters <<
" threshold: " << matchParams.
maxDistForCorrespondence << endl;
835 keepIteratingICP =
true;
843 keepIteratingICP =
false;
904 CPose3DPDFPtr resultPDF;
906 if (runningTime) tictac.Tic();
920 if (runningTime) *runningTime = tictac.Tac();
925 MRPT_TODO(
"Refactor `info` so it is polymorphic and can use dynamic_cast<> here");
945 CPose3DPDFPtr resultPDF;
946 CPose3DPDFGaussianPtr gaussPdf;
948 size_t nCorrespondences=0;
949 bool keepApproaching;
970 gaussPdf = CPose3DPDFGaussian::Create();
973 gaussPdf->mean = grossEst;
987 if ( !m2->isEmpty() )
1005 matchParams, matchExtraResults);
1007 nCorrespondences = correspondences.size();
1009 if ( !nCorrespondences )
1012 keepApproaching =
false;
1019 double transf_scale;
1025 keepApproaching =
true;
1036 keepApproaching =
false;
1042 lastMeanPose = gaussPdf->mean;
1073 resultPDF = gaussPdf;
Use the covariance of the optimal registration, disregarding uncertainty in data association.
mrpt::poses::CPosePDFPtr ICP_Method_Classic(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPosePDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
mrpt::math::TPoint3D angularDistPivotPoint
The point used to calculate angular distances: e.g. the coordinates of the sensor for a 2D laser scan...
float maxAngularDistForCorrespondence
Allowed "angular error" (in radians): this permits larger pairing threshold distances to more distant...
double x() const
Common members of all points & poses classes.
float ransac_fuseMaxDiffPhi
float quality
A measure of the 'quality' of the local minimum of the sqr. error found by the method. Higher values are better. Low values will be found in ill-conditioned situations (e.g. a corridor)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose2D mean
The mean value.
CPose3D mean
The mean value.
const float normalizationStd
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
float ransac_mahalanobisDistanceThreshold
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
float kernel(const float &x2, const float &rho2)
Computes: or just return the input if options.useKernel = false.
void y_incr(const double v)
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
size_t decimation_other_map_points
(Default=1) Only consider 1 out of this number of points from the "other" map.
double BASE_IMPEXP closestSquareDistanceFromPointToLine(const double &Px, const double &Py, const double &x1, const double &y1, const double &x2, const double &y2)
Returns the square distance from a point to a line.
TICPAlgorithm ICP_algorithm
The algorithm to use (default: icpClassic). See http://www.mrpt.org/tutorials/programming/scan-matchi...
Parameters for se2_l2_robust().
virtual void determineMatching2D(const mrpt::maps::CMetricMap *otherMap, const mrpt::poses::CPose2D &otherMapPose, mrpt::utils::TMatchingPairList &correspondences, const TMatchingParams ¶ms, TMatchingExtraResults &extraResults) const
Computes the matching between this and another 2D point map, which includes finding: ...
void BASE_IMPEXP pause(const std::string &msg=std::string("Press any key to continue...")) MRPT_NO_THROWS
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
#define THROW_EXCEPTION(msg)
GLdouble GLdouble GLdouble GLdouble q
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
bool derivedFrom(const TRuntimeClassId *pBaseClass) const
This file implements several operations that operate element-wise on individual or pairs of container...
const float ransac_mahalanobisDistanceThreshold
double pitch() const
Get the PITCH angle (in radians)
double yaw() const
Get the YAW angle (in radians)
bool skip_quality_calculation
Skip the (sometimes) expensive evaluation of the term 'quality' at ICP output (Default=true) ...
bool TFEST_IMPEXP se2_l2_robust(const mrpt::utils::TMatchingPairList &in_correspondences, const double in_normalizationStd, const TSE2RobustParams &in_ransac_params, TSE2RobustResult &out_results)
Robust least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference ...
const Scalar * const_iterator
unsigned int ransac_nSimulations
float thresholdAng
Initial threshold distance for two points to become a correspondence.
float ALFA
The scale factor for threshold everytime convergence is achieved.
TConfigParams options
The options employed by the ICP align.
mrpt::poses::CPose3DPDFPtr Align3DPDF(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose3DPDFGaussian &initialEstimationPDF, float *runningTime=NULL, void *info=NULL)
The virtual method for aligning a pair of metric maps, aligning the full 6D pose. ...
float kernel_rho
Cauchy kernel rho, for estimating the optimal transformation covariance, in meters (default = 0...
float minAbsStep_rot
If the correction in all rotation coordinates (yaw,pitch,roll) is below this threshold (in radians)...
uint32_t corresponding_points_decimation
Decimation of the point cloud being registered against the reference one (default=5) - set to 1 to ha...
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
virtual void determineMatching3D(const mrpt::maps::CMetricMap *otherMap, const mrpt::poses::CPose3D &otherMapPose, mrpt::utils::TMatchingPairList &correspondences, const TMatchingParams ¶ms, TMatchingExtraResults &extraResults) const
Computes the matchings between this and another 3D points map - method used in 3D-ICP.
float goodness
A goodness measure for the alignment, it is a [0,1] range indicator of percentage of correspondences...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans or other sensors...
bool ransac_fuseByCorrsMatch
This base provides a set of functions for maths stuff.
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
A helper class that can convert an enum value into its textual representation, and viceversa...
unsigned int maxIterations
Maximum number of iterations to run.
This class implements a high-performance stopwatch.
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
void x_incr(const double v)
float covariance_varPoints
This is the normalization constant that is used to scale the whole 3x3 covariance.
bool TFEST_IMPEXP se3_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::poses::CPose3DQuat &out_transform, double &out_scale, bool forceScaleToUnity=false)
Least-squares (L2 norm) solution to finding the optimal SE(3) transform between two reference frames ...
bool onlyUniqueRobust
Additional consistency filter: "onlyKeepTheClosest" allows one correspondence for each "local map" po...
float maxDistForCorrespondence
Maximum linear distance between two points to be paired (meters)
TICPCovarianceMethod ICP_covariance_method
The method to use for covariance estimation (Default: icpCovFiniteDifferences)
bool doRANSAC
Perform a RANSAC step, mrpt::tfest::se2_l2_robust(), after the ICP convergence, to obtain a better es...
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,qz).
TICPAlgorithm
The ICP algorithm selection, used in mrpt::slam::CICP::options.
bool onlyClosestCorrespondences
The usual approach: to consider only the closest correspondence for each local point (Default to true...
unsigned short nIterations
The number of executed iterations until convergence.
bool use_kernel
Whether to use kernel_rho to smooth distances, or use distances directly (default=true) ...
CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream &s, const char *a)
GLsizei const GLchar ** string
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
mrpt::poses::CPosePDFPtr ICP_Method_LM(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPosePDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
double roll() const
Get the ROLL angle (in radians)
ENUMTYPE read_enum(const std::string §ion, const std::string &name, const ENUMTYPE &defaultValue, bool failIfNotFound=false) const
Reads an "enum" value, where the value in the config file can be either a numerical value or the symb...
void squareErrorVector(const mrpt::poses::CPose2D &q, std::vector< float > &out_sqErrs) const
Returns a vector with the square error between each pair of correspondences in the list...
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
#define MRPT_LOAD_CONFIG_VAR(variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
bool onlyKeepTheClosest
If set to true (default), only the closest correspondence will be returned. If false all are returned...
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
size_t offset_other_map_points
Index of the first point in the "other" map to start checking for correspondences (Default=0) ...
bool skip_cov_calculation
Skip the computation of the covariance (saves some time) (default=false)
Declares a virtual base class for all metric maps storage classes.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
TConfigParams()
Initializer for default values:
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
float smallestThresholdDist
The size for threshold such that iterations will stop, since it is considered precise enough...
mrpt::poses::CPosePDFPtr AlignPDF(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPosePDFGaussian &initialEstimationPDF, float *runningTime=NULL, void *info=NULL)
An implementation of CMetricMapsAlignmentAlgorithm for the case of a point maps and a occupancy grid/...
const double & phi() const
Get the phi angle of the 2D pose (in radians)
The ICP algorithm return information.
float ransac_fuseMaxDiffXY
A matrix of dynamic size.
unsigned int ransac_minSetSize
mrpt::poses::CPosePDFSOG transformation
The output as a set of transformations (sum of Gaussians)
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
float LM_initial_lambda
[LM method only] The initial value of the lambda parameter in the LM method (default=1e-4) ...
float normalizationStd
RANSAC-step option: The standard deviation in X,Y of landmarks/points which are being matched (used t...
float minAbsStep_trans
If the correction in all translation coordinates (X,Y,Z) is below this threshold (in meters)...
unsigned int ransac_maxSetSize
TICPCovarianceMethod
ICP covariance estimation methods, used in mrpt::slam::CICP::options.
Parameters for the determination of matchings between point clouds, etc.
bool TFEST_IMPEXP se2_l2(const mrpt::utils::TMatchingPairList &in_correspondences, mrpt::math::TPose2D &out_transformation, mrpt::math::CMatrixDouble33 *out_estimateCovariance=NULL)
Least-squares (L2 norm) solution to finding the optimal SE(2) (x,y,yaw) between two reference frames...
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
float Axy_aprox_derivatives
[LM method only] The size of the perturbance in x & y used to estimate the Jacobians of the square er...
mrpt::poses::CPose3DPDFPtr ICP3D_Method_Classic(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose3DPDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
virtual bool isEmpty() const =0
Returns true if the map is empty/no observation has been inserted.
GLenum const GLfloat * params
Output placeholder for se2_l2_robust()
double phi
Orientation (rads)
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
Covariance of a least-squares optimizer (includes data association uncertainty)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1