51 const size_t N = in_correspondences.size();
53 if (N < 2)
return false;
55 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();
88 corrIt != in_correspondences.end(); corrIt++)
97 const __m128 a_xyz = _mm_loadu_ps(&corrIt->this_x);
99 _mm_loadu_ps(&corrIt->other_x);
101 const __m128 a_xyxy =
102 _mm_shuffle_ps(a_xyz, a_xyz, _MM_SHUFFLE(1, 0, 1, 0));
103 const __m128 b_xyyx =
104 _mm_shuffle_ps(b_xyz, b_xyz, _MM_SHUFFLE(0, 1, 1, 0));
107 sum_a_xyz = _mm_add_ps(sum_a_xyz, a_xyz);
108 sum_b_xyz = _mm_add_ps(sum_b_xyz, b_xyz);
112 sum_ab_xyz = _mm_add_ps(sum_ab_xyz, _mm_mul_ps(a_xyxy, b_xyyx));
116 _mm_store_ps(sums_a, sum_a_xyz);
117 _mm_store_ps(sums_b, sum_b_xyz);
119 const float& SumXa = sums_a[0];
120 const float& SumYa = sums_a[1];
121 const float& SumXb = sums_b[0];
122 const float& SumYb = sums_b[1];
125 const __m128 Ninv_4val =
127 sum_a_xyz = _mm_mul_ps(sum_a_xyz, Ninv_4val);
128 sum_b_xyz = _mm_mul_ps(sum_b_xyz, Ninv_4val);
135 _mm_store_ps(means_a, sum_a_xyz);
136 _mm_store_ps(means_b, sum_b_xyz);
138 const float& mean_x_a = means_a[0];
139 const float& mean_y_a = means_a[1];
140 const float& mean_x_b = means_b[0];
141 const float& mean_y_b = means_b[1];
146 _mm_store_ps(cross_sums, sum_ab_xyz);
148 const float& Sxx = cross_sums[0];
149 const float& Syy = cross_sums[1];
150 const float& Sxy = cross_sums[2];
151 const float& Syx = cross_sums[3];
154 const float Ax = N * (Sxx + Syy) - SumXa * SumXb - SumYa * SumYb;
155 const float Ay = SumXa * SumYb + N * (Syx - Sxy) - SumXb * SumYa;
159 float SumXa = 0, SumXb = 0, SumYa = 0, SumYb = 0;
160 float Sxx = 0, Sxy = 0, Syx = 0, Syy = 0;
163 corrIt != in_correspondences.end(); corrIt++)
166 const float xa = corrIt->this_x;
167 const float ya = corrIt->this_y;
168 const float xb = corrIt->other_x;
169 const float yb = corrIt->other_y;
184 const float mean_x_a = SumXa * N_inv;
185 const float mean_y_a = SumYa * N_inv;
186 const float mean_x_b = SumXb * N_inv;
187 const float mean_y_b = SumYb * N_inv;
190 const float Ax = N * (Sxx + Syy) - SumXa * SumXb - SumYa * SumYb;
191 const float Ay = SumXa * SumYb + N * (Syx - Sxy) - SumXb * SumYa;
195 out_transformation.
phi =
197 ? atan2(
static_cast<double>(Ay),
static_cast<double>(Ax))
200 const double ccos = cos(out_transformation.
phi);
201 const double csin = sin(out_transformation.
phi);
203 out_transformation.
x = mean_x_a - mean_x_b * ccos + mean_y_b * csin;
204 out_transformation.
y = mean_y_a - mean_x_b * csin - mean_y_b * ccos;
206 if (out_estimateCovariance)
212 double var_x_a = 0, var_y_a = 0, var_x_b = 0, var_y_b = 0;
213 const double N_1_inv = 1.0 / (N - 1);
218 in_correspondences.begin();
219 corrIt != in_correspondences.end(); corrIt++)
221 var_x_a +=
square(corrIt->this_x - mean_x_a);
222 var_y_a +=
square(corrIt->this_y - mean_y_a);
223 var_x_b +=
square(corrIt->other_x - mean_x_b);
224 var_y_b +=
square(corrIt->other_y - mean_y_b);
233 const double BETA = (var_x_a + var_y_a + var_x_b + var_y_b) *
234 pow(
static_cast<double>(N), 2.0) *
235 static_cast<double>(N - 1);
243 C->get_unsafe(0, 0) =
244 2.0 * N_inv + BETA *
square((mean_x_b * Ay + mean_y_b * Ax) / D);
245 C->get_unsafe(1, 1) =
246 2.0 * N_inv + BETA *
square((mean_x_b * Ax - mean_y_b * Ay) / D);
247 C->get_unsafe(2, 2) = BETA / D;
249 C->get_unsafe(0, 1) = C->get_unsafe(1, 0) =
250 -BETA * (mean_x_b * Ay + mean_y_b * Ax) *
251 (mean_x_b * Ax - mean_y_b * Ay) /
square(D);
253 C->get_unsafe(0, 2) = C->get_unsafe(2, 0) =
254 BETA * (mean_x_b * Ay + mean_y_b * Ax) / pow(D, 1.5);
256 C->get_unsafe(1, 2) = C->get_unsafe(2, 1) =
257 BETA * (mean_y_b * Ay - mean_x_b * Ax) / pow(D, 1.5);
#define MRPT_MAX_ALIGN_BYTES
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 se2_l2(const mrpt::tfest::TMatchingPairList &in_correspondences, mrpt::math::TPose2D &out_transformation, mrpt::math::CMatrixDouble33 *out_estimateCovariance=nullptr)
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.
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...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
T square(const T x)
Inline function for the square of a number.
double phi
Orientation (rads)