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, result.outliers ))
228 const auto [new_ct_local, new_ct_global] =
231 ct_local = new_ct_local;
232 ct_global = new_ct_global;
236 in, wp, ct_local, ct_global, optimal_q,
242 result.optimalPose = mrpt::poses::CPose3D(optimal_q, 0, 0, 0);
245 mrpt::math::TPoint3D pp;
246 result.optimalPose.composePoint(
247 ct_local.x, ct_local.y, ct_local.z, pp.x, pp.y, pp.z);
250 result.optimalPose.x(ct_global.x - pp.x);
251 result.optimalPose.y(ct_global.y - pp.y);
252 result.optimalPose.z(ct_global.z - pp.z);
PairWeights pair_weights
See docs for PairWeights.
double ln2ln
Weight of line-to-line pairs.
MatchedLineList paired_ln2ln
bool use_scale_outlier_detector
bool optimal_tf_horn(const mp2p_icp::Pairings &in, const WeightParameters &wp, OptimalTF_Result &result)
Template that applies lambdas to unified vector forms of pairings.
static bool se3_l2_internal(const mp2p_icp::Pairings &in, const WeightParameters &wp, const mrpt::math::TPoint3D &ct_local, const mrpt::math::TPoint3D &ct_global, mrpt::math::CQuaternionDouble &out_attitude, OutlierIndices &in_out_outliers)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
MatchedPointLineList paired_pt2ln
std::tuple< mrpt::math::TPoint3D, mrpt::math::TPoint3D > eval_centroids_robust(const Pairings &in, const OutlierIndices &outliers)
void visit_correspondences(const Pairings &in, const WeightParameters &wp, const mrpt::math::TPoint3D &ct_local, const mrpt::math::TPoint3D &ct_global, OutlierIndices &in_out_outliers, LAMBDA lambda_each_pair, LAMBDA2 lambda_final, bool normalize_relative_point_vectors, const mrpt::optional_ref< VisitCorrespondencesStats > &outStats=std::nullopt)
Classic Horn's solution for optimal SE(3) transformation.
MatchedPlaneList paired_pl2pl
double pl2pl
Weight of plane-to-plane pairs.
mrpt::tfest::TMatchingPairList paired_pt2pt
MatchedPointPlaneList paired_pt2pl