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;
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;
684 w3= *other_x_trans+Axy;
689 float x1,y1, x2,y2, d1,d2;
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;
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;
#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...
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
Declares a virtual base class for all metric maps storage classes.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
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.
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:
virtual bool isEmpty() const =0
Returns true if the map is empty/no observation has been inserted.
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans or other sensors.
virtual float squareDistanceToClosestCorrespondence(float x0, float y0) const MRPT_OVERRIDE
Returns the square distance from the 2D point (x0,y0) to the closest correspondence in the map.
virtual bool isEmpty() const MRPT_OVERRIDE
Returns true if the map is empty/no observation has been inserted.
virtual void determineMatching2D(const mrpt::maps::CMetricMap *otherMap, const mrpt::poses::CPose2D &otherMapPose, mrpt::utils::TMatchingPairList &correspondences, const TMatchingParams ¶ms, TMatchingExtraResults &extraResults) const MRPT_OVERRIDE
Computes the matching between this and another 2D point map, which includes finding:
A matrix of dynamic size.
void kdTreeTwoClosestPoint2D(float x0, float y0, float &out_x1, float &out_y1, float &out_x2, float &out_y2, float &out_dist_sqr1, float &out_dist_sqr2) const
KD Tree-based search for the TWO closest point to some given 2D coordinates.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
const double & phi() const
Get the phi angle of the 2D pose (in radians)
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
double pitch() const
Get the PITCH angle (in radians)
double roll() const
Get the ROLL angle (in radians)
double yaw() const
Get the YAW angle (in radians)
Declares a class that represents a Probability Density function (PDF) of a 3D pose .
CPose3D mean
The mean value.
A class used to store a 3D pose as a translation (x,y,z) and a quaternion (qr,qx,qy,...
double x() const
Common members of all points & poses classes.
void y_incr(const double v)
void x_incr(const double v)
Declares a class that represents a Probability Density function (PDF) of a 2D pose .
CPose2D mean
The mean value.
unsigned int maxIterations
Maximum number of iterations to run.
bool skip_quality_calculation
Skip the (sometimes) expensive evaluation of the term 'quality' at ICP output (Default=true)
float Axy_aprox_derivatives
[LM method only] The size of the perturbance in x & y used to estimate the Jacobians of the square er...
float ransac_fuseMaxDiffXY
TICPAlgorithm ICP_algorithm
The algorithm to use (default: icpClassic). See http://www.mrpt.org/tutorials/programming/scan-matchi...
uint32_t corresponding_points_decimation
Decimation of the point cloud being registered against the reference one (default=5) - set to 1 to ha...
float ransac_fuseMaxDiffPhi
float smallestThresholdDist
The size for threshold such that iterations will stop, since it is considered precise enough.
float normalizationStd
RANSAC-step option: The standard deviation in X,Y of landmarks/points which are being matched (used t...
bool onlyClosestCorrespondences
The usual approach: to consider only the closest correspondence for each local point (Default to true...
float thresholdAng
Initial threshold distance for two points to become a correspondence.
bool skip_cov_calculation
Skip the computation of the covariance (saves some time) (default=false)
float minAbsStep_trans
If the correction in all translation coordinates (X,Y,Z) is below this threshold (in meters),...
TICPCovarianceMethod ICP_covariance_method
The method to use for covariance estimation (Default: icpCovFiniteDifferences)
TConfigParams()
Initializer for default values:
float ALFA
The scale factor for threshold everytime convergence is achieved.
bool doRANSAC
Perform a RANSAC step, mrpt::tfest::se2_l2_robust(), after the ICP convergence, to obtain a better es...
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.
bool ransac_fuseByCorrsMatch
float kernel_rho
Cauchy kernel rho, for estimating the optimal transformation covariance, in meters (default = 0....
float covariance_varPoints
This is the normalization constant that is used to scale the whole 3x3 covariance.
bool use_kernel
Whether to use kernel_rho to smooth distances, or use distances directly (default=true)
unsigned int ransac_minSetSize
float LM_initial_lambda
[LM method only] The initial value of the lambda parameter in the LM method (default=1e-4)
float ransac_mahalanobisDistanceThreshold
unsigned int ransac_maxSetSize
float minAbsStep_rot
If the correction in all rotation coordinates (yaw,pitch,roll) is below this threshold (in radians),...
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form,...
unsigned int ransac_nSimulations
mrpt::poses::CPosePDFPtr ICP_Method_LM(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPosePDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
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(const float &x2, const float &rho2)
Computes:
mrpt::poses::CPosePDFPtr ICP_Method_Classic(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPosePDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
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/...
TConfigParams options
The options employed by the ICP align.
mrpt::poses::CPose3DPDFPtr ICP3D_Method_Classic(const mrpt::maps::CMetricMap *m1, const mrpt::maps::CMetricMap *m2, const mrpt::poses::CPose3DPDFGaussian &initialEstimationPDF, TReturnInfo &outInfo)
This class allows loading and storing values and vectors of different types from a configuration text...
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...
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
This class implements a high-performance stopwatch.
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,...
const Scalar * const_iterator
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
GLenum const GLfloat * params
GLsizei const GLchar ** string
GLdouble GLdouble GLdouble GLdouble q
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
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.
TICPCovarianceMethod
ICP covariance estimation methods, used in mrpt::slam::CICP::options <>
TICPAlgorithm
The ICP algorithm selection, used in mrpt::slam::CICP::options <>
@ icpCovLinealMSE
Use the covariance of the optimal registration, disregarding uncertainty in data association.
@ icpCovFiniteDifferences
Covariance of a least-squares optimizer (includes data association uncertainty)
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...
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 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 ...
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.
#define THROW_EXCEPTION(msg)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
This base provides a set of functions for maths stuff.
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream &s, const char *a)
This file implements several operations that operate element-wise on individual or pairs of container...
const float normalizationStd
const float ransac_mahalanobisDistanceThreshold
Parameters for the determination of matchings between point clouds, etc.
float maxDistForCorrespondence
Maximum linear distance between two points to be paired (meters)
size_t decimation_other_map_points
(Default=1) Only consider 1 out of this number of points from the "other" map.
bool onlyKeepTheClosest
If set to true (default), only the closest correspondence will be returned. If false all are returned...
bool onlyUniqueRobust
Additional consistency filter: "onlyKeepTheClosest" allows one correspondence for each "local map" po...
size_t offset_other_map_points
Index of the first point in the "other" map to start checking for correspondences (Default=0)
float maxAngularDistForCorrespondence
Allowed "angular error" (in radians): this permits larger pairing threshold distances to more distant...
mrpt::math::TPoint3D angularDistPivotPoint
The point used to calculate angular distances: e.g. the coordinates of the sensor for a 2D laser scan...
double phi
Orientation (rads)
The ICP algorithm return information.
float quality
A measure of the 'quality' of the local minimum of the sqr. error found by the method....
unsigned short nIterations
The number of executed iterations until convergence.
float goodness
A goodness measure for the alignment, it is a [0,1] range indicator of percentage of correspondences.
Parameters for se2_l2_robust().
Output placeholder for se2_l2_robust()
mrpt::poses::CPosePDFSOG transformation
The output as a set of transformations (sum of Gaussians)
A helper class that can convert an enum value into its textual representation, and viceversa.
bool derivedFrom(const TRuntimeClassId *pBaseClass) const