16 #include <mrpt/core/optional_ref.h>
17 #include <mrpt/math/TPoint3D.h>
30 template <
class LAMBDA,
class LAMBDA2>
33 const mrpt::math::TPoint3D& ct_local,
const mrpt::math::TPoint3D& ct_global,
35 LAMBDA2 lambda_final,
bool normalize_relative_point_vectors,
36 const mrpt::optional_ref<VisitCorrespondencesStats>& outStats =
39 using mrpt::math::TPoint3D;
40 using mrpt::math::TVector3D;
49 nPt2Ln == 0,
"This solver cannot handle point-to-line pairings.");
51 nPt2Pl == 0,
"This solver cannot handle point-to-plane pairings yet.");
53 const auto nAllMatches = nPt2Pt + nLn2Ln + nPl2Pl;
59 if (point_weights.empty())
62 point_weights.emplace_back(nPt2Pt, 1.0);
65 auto cur_point_block_weights = point_weights.begin();
66 std::size_t cur_point_block_start = 0;
69 double waPoints, waLines, waPlanes;
76 "All, point, line, plane attidude weights, are <=0 (!)");
78 const auto k = 1.0 / (wPt * nPt2Pt + wLi * nLn2Ln + wPl * nPl2Pl);
95 auto it_next_outlier = in_out_outliers.
point2point.begin();
99 for (std::size_t i = 0; i < nAllMatches; i++)
102 if (it_next_outlier != in_out_outliers.
point2point.end() &&
103 i == *it_next_outlier)
122 if (i >= cur_point_block_start + cur_point_block_weights->first)
124 ASSERT_(cur_point_block_weights != point_weights.end());
125 ++cur_point_block_weights;
126 cur_point_block_start = i;
128 wi *= cur_point_block_weights->second;
131 bi = p.global - ct_global;
132 ri = p.local - ct_local;
134 const auto bi_n = bi.norm(), ri_n = ri.norm();
136 if (bi_n < 1e-4 || ri_n < 1e-4)
145 if (normalize_relative_point_vectors)
155 const double scale_mismatch =
156 std::max(bi_n, ri_n) / std::min(bi_n, ri_n);
167 else if (i < nPt2Pt + nLn2Ln)
172 const auto idxLine = i - nPt2Pt;
174 bi = in.
paired_ln2ln[idxLine].ln_global.getDirectorVector();
175 ri = in.
paired_ln2ln[idxLine].ln_local.getDirectorVector();
177 ASSERTDEB_LT_(std::abs(bi.norm() - 1.0), 0.01);
178 ASSERTDEB_LT_(std::abs(ri.norm() - 1.0), 0.01);
185 const auto idxPlane = i - (nPt2Pt + nLn2Ln);
186 bi = in.
paired_pl2pl[idxPlane].p_global.plane.getNormalVector();
187 ri = in.
paired_pl2pl[idxPlane].p_local.plane.getNormalVector();
189 ASSERTDEB_LT_(std::abs(bi.norm() - 1.0), 0.01);
190 ASSERTDEB_LT_(std::abs(ri.norm() - 1.0), 0.01);
196 if (robustSqrtWeightFunc)
202 const double errorSqr = mrpt::square(ri2.x - bi.x) +
203 mrpt::square(ri2.y - bi.y) +
204 mrpt::square(ri2.z - bi.z);
205 wi *= robustSqrtWeightFunc(errorSqr);
212 lambda_each_pair(bi, ri, wi);
216 in_out_outliers = std::move(new_outliers);
221 if (outStats.has_value()) outStats.value().get() = stats;