52 const size_t N = in_correspondences.size();
54 if (N<2)
return false;
56 const float N_inv = 1.0f/N;
80 __m128 sum_a_xyz = _mm_setzero_ps();
81 __m128 sum_b_xyz = _mm_setzero_ps();
85 __m128 sum_ab_xyz = _mm_setzero_ps();
96 const __m128 a_xyz = _mm_loadu_ps( &corrIt->this_x );
97 const __m128 b_xyz = _mm_loadu_ps( &corrIt->other_x );
99 const __m128 a_xyxy = _mm_shuffle_ps(a_xyz,a_xyz, _MM_SHUFFLE(1,0,1,0) );
100 const __m128 b_xyyx = _mm_shuffle_ps(b_xyz,b_xyz, _MM_SHUFFLE(0,1,1,0) );
103 sum_a_xyz = _mm_add_ps(sum_a_xyz,a_xyz);
104 sum_b_xyz = _mm_add_ps(sum_b_xyz,b_xyz);
108 sum_ab_xyz = _mm_add_ps(sum_ab_xyz, _mm_mul_ps(a_xyxy,b_xyyx));
113 _mm_store_ps(sums_a,sum_a_xyz);
114 _mm_store_ps(sums_b,sum_b_xyz);
116 const float &SumXa=sums_a[0];
117 const float &SumYa=sums_a[1];
118 const float &SumXb=sums_b[0];
119 const float &SumYb=sums_b[1];
122 const __m128 Ninv_4val = _mm_set1_ps(N_inv);
123 sum_a_xyz = _mm_mul_ps(sum_a_xyz,Ninv_4val);
124 sum_b_xyz = _mm_mul_ps(sum_b_xyz,Ninv_4val);
132 _mm_store_ps(means_a,sum_a_xyz);
133 _mm_store_ps(means_b,sum_b_xyz);
135 const float &mean_x_a = means_a[0];
136 const float &mean_y_a = means_a[1];
137 const float &mean_x_b = means_b[0];
138 const float &mean_y_b = means_b[1];
143 _mm_store_ps(cross_sums,sum_ab_xyz);
145 const float &Sxx = cross_sums[0];
146 const float &Syy = cross_sums[1];
147 const float &Sxy = cross_sums[2];
148 const float &Syx = cross_sums[3];
151 const float Ax = N*(Sxx + Syy) - SumXa*SumXb - SumYa*SumYb;
152 const float Ay = SumXa * SumYb + N*(Syx-Sxy)- SumXb * SumYa;
156 float SumXa=0, SumXb=0, SumYa=0, SumYb=0;
157 float Sxx=0, Sxy=0, Syx=0, Syy=0;
162 const float xa = corrIt->this_x;
163 const float ya = corrIt->this_y;
164 const float xb = corrIt->other_x;
165 const float yb = corrIt->other_y;
180 const float mean_x_a = SumXa * N_inv;
181 const float mean_y_a = SumYa * N_inv;
182 const float mean_x_b = SumXb * N_inv;
183 const float mean_y_b = SumYb * N_inv;
186 const float Ax = N*(Sxx + Syy) - SumXa*SumXb - SumYa*SumYb;
187 const float Ay = SumXa * SumYb + N*(Syx-Sxy)- SumXb * SumYa;
192 out_transformation.
phi = (Ax!=0 || Ay!=0) ? atan2( static_cast<double>(Ay),
static_cast<double>(Ax)) : 0.0;
194 const double ccos = cos( out_transformation.
phi );
195 const double csin = sin( out_transformation.
phi );
197 out_transformation.
x = mean_x_a - mean_x_b * ccos + mean_y_b * csin;
198 out_transformation.
y = mean_y_a - mean_x_b * csin - mean_y_b * ccos;
200 if ( out_estimateCovariance )
206 double var_x_a = 0,var_y_a = 0,var_x_b = 0,var_y_b = 0;
207 const double N_1_inv = 1.0/(N-1);
213 var_x_a +=
square( corrIt->this_x - mean_x_a );
214 var_y_a +=
square( corrIt->this_y - mean_y_a );
215 var_x_b +=
square( corrIt->other_x - mean_x_b );
216 var_y_b +=
square( corrIt->other_y - mean_y_b );
225 const double BETA = (var_x_a+var_y_a+var_x_b+var_y_b)*pow(static_cast<double>(N),2.0)*
static_cast<double>(N-1);
233 C->get_unsafe(0,0) = 2.0*N_inv + BETA *
square((mean_x_b*Ay+mean_y_b*Ax)/D);
234 C->get_unsafe(1,1) = 2.0*N_inv + BETA *
square((mean_x_b*Ax-mean_y_b*Ay)/D);
235 C->get_unsafe(2,2) = BETA / D;
238 C->get_unsafe(1,0) = -BETA*(mean_x_b*Ay+mean_y_b*Ax)*(mean_x_b*Ax-mean_y_b*Ay)/
square(D);
241 C->get_unsafe(2,0) = BETA*(mean_x_b*Ay+mean_y_b*Ax)/pow(D,1.5);
244 C->get_unsafe(2,1) = BETA*(mean_y_b*Ay-mean_x_b*Ax)/pow(D,1.5);
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose2D mean
The mean value.
const Scalar * const_iterator
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
T square(const T x)
Inline function for the square of a number.
This base provides a set of functions for maths stuff.
Declares a class that represents a Probability Density function (PDF) of a 2D pose ...
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
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...
Functions for estimating the optimal transformation between two frames of references given measuremen...
double phi
Orientation (rads)