14 #include <mrpt/math/CMatrixFixed.h>
15 #include <mrpt/math/CQuaternion.h>
16 #include <mrpt/math/CVectorFixed.h>
71 const mrpt::math::TPoint3D& ct_local,
const mrpt::math::TPoint3D& ct_global,
72 mrpt::math::CQuaternionDouble& out_attitude,
85 nPt2Ln == 0,
"This solver cannot handle point-to-line pairings.");
87 nPt2Pl == 0,
"This solver cannot handle point-to-plane pairings yet.");
88 const auto nAllMatches = nPt2Pt + nLn2Ln + nPl2Pl;
91 if (nAllMatches < 3)
return false;
93 auto S = mrpt::math::CMatrixDouble33::Zero();
96 auto lambda_each_pair = [&](
const mrpt::math::TVector3D& bi,
97 const mrpt::math::TVector3D& ri,
102 S(0, 0) += wi * ri.x * bi.x;
103 S(0, 1) += wi * ri.x * bi.y;
104 S(0, 2) += wi * ri.x * bi.z;
106 S(1, 0) += wi * ri.y * bi.x;
107 S(1, 1) += wi * ri.y * bi.y;
108 S(1, 2) += wi * ri.y * bi.z;
110 S(2, 0) += wi * ri.z * bi.x;
111 S(2, 1) += wi * ri.z * bi.y;
112 S(2, 2) += wi * ri.z * bi.z;
115 auto lambda_final = [&](
const double w_sum) {
117 if (w_sum > .0) S *= (1.0 / w_sum);
121 in, wp, ct_local, ct_global, in_out_outliers ,
123 lambda_each_pair, lambda_final,
127 auto N = mrpt::math::CMatrixDouble44::Zero();
129 N(0, 0) = S(0, 0) + S(1, 1) + S(2, 2);
130 N(0, 1) = S(1, 2) - S(2, 1);
131 N(0, 2) = S(2, 0) - S(0, 2);
132 N(0, 3) = S(0, 1) - S(1, 0);
135 N(1, 1) = S(0, 0) - S(1, 1) - S(2, 2);
136 N(1, 2) = S(0, 1) + S(1, 0);
137 N(1, 3) = S(2, 0) + S(0, 2);
141 N(2, 2) = -S(0, 0) + S(1, 1) - S(2, 2);
142 N(2, 3) = S(1, 2) + S(2, 1);
147 N(3, 3) = -S(0, 0) - S(1, 1) + S(2, 2);
151 auto Z = mrpt::math::CMatrixDouble44::Zero();
152 std::vector<double> eigvals;
153 N.eig_symmetric(
Z, eigvals,
true );
155 auto v =
Z.blockCopy<4, 1>(0, 3);
159 sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]) - 1.0) <
172 for (
unsigned int i = 0; i < 4; i++) out_attitude[i] = v[i];
177 if (forceScaleToUnity)
185 for (
size_t i = 0; i < nMatches; i++)
187 num += ri[i].sqrNorm();
188 den += bi[i].sqrNorm();
191 s = std::sqrt(num / den);
214 auto [ct_local, ct_global] =
217 mrpt::math::CQuaternionDouble optimal_q;
221 in, wp, ct_local, ct_global, optimal_q,
229 const auto [new_ct_local, new_ct_global] =
232 ct_local = new_ct_local;
233 ct_global = new_ct_global;
237 in, wp, ct_local, ct_global, optimal_q,
243 result.optimalPose = mrpt::poses::CPose3D(optimal_q, 0, 0, 0);
246 mrpt::math::TPoint3D pp;
247 result.optimalPose.composePoint(
248 ct_local.x, ct_local.y, ct_local.z, pp.x, pp.y, pp.z);
251 result.optimalPose.x(ct_global.x - pp.x);
252 result.optimalPose.y(ct_global.y - pp.y);
253 result.optimalPose.z(ct_global.z - pp.z);