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);
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
Declares a class that represents a Probability Density function (PDF) of a 2D pose .
CPose2D mean
The mean value.
mrpt::math::CMatrixDouble33 cov
The 3x3 covariance matrix.
const Scalar * const_iterator
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.
This base provides a set of functions for maths stuff.
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...
Functions for estimating the optimal transformation between two frames of references given measuremen...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double phi
Orientation (rads)