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_global,
OutlierIndices& in_out_outliers, LAMBDA lambda_each_pair,
34 LAMBDA2 lambda_final,
bool normalize_relative_point_vectors,
35 const mrpt::optional_ref<VisitCorrespondencesStats>& outStats = std::nullopt)
37 using mrpt::math::TPoint3D;
38 using mrpt::math::TVector3D;
46 ASSERTMSG_(nPt2Ln == 0,
"This solver cannot handle point-to-line pairings.");
47 ASSERTMSG_(nPt2Pl == 0,
"This solver cannot handle point-to-plane pairings yet.");
49 const auto nAllMatches = nPt2Pt + nLn2Ln + nPl2Pl;
55 if (point_weights.empty())
58 point_weights.emplace_back(nPt2Pt, 1.0);
61 auto cur_point_block_weights = point_weights.begin();
62 std::size_t cur_point_block_start = 0;
65 double waPoints, waLines, waPlanes;
70 ASSERTMSG_(wPt + wLi + wPl > .0,
"All, point, line, plane attidude weights, are <=0 (!)");
72 const auto k = 1.0 / (wPt * nPt2Pt + wLi * nLn2Ln + wPl * nPl2Pl);
88 auto it_next_outlier = in_out_outliers.
point2point.begin();
92 for (std::size_t i = 0; i < nAllMatches; i++)
95 if (it_next_outlier != in_out_outliers.
point2point.end() && i == *it_next_outlier)
114 if (i >= cur_point_block_start + cur_point_block_weights->first)
116 ASSERT_(cur_point_block_weights != point_weights.end());
117 ++cur_point_block_weights;
118 cur_point_block_start = i;
120 wi *= cur_point_block_weights->second;
123 bi = p.global - ct_global;
124 ri = p.local - ct_local;
126 const auto bi_n = bi.norm(), ri_n = ri.norm();
128 if (bi_n < 1e-4 || ri_n < 1e-4)
137 if (normalize_relative_point_vectors)
147 const double scale_mismatch = std::max(bi_n, ri_n) / std::min(bi_n, ri_n);
158 else if (i < nPt2Pt + nLn2Ln)
163 const auto idxLine = i - nPt2Pt;
165 bi = in.
paired_ln2ln[idxLine].ln_global.getDirectorVector();
166 ri = in.
paired_ln2ln[idxLine].ln_local.getDirectorVector();
168 ASSERTDEB_LT_(std::abs(bi.norm() - 1.0), 0.01);
169 ASSERTDEB_LT_(std::abs(ri.norm() - 1.0), 0.01);
176 const auto idxPlane = i - (nPt2Pt + nLn2Ln);
177 bi = in.
paired_pl2pl[idxPlane].p_global.plane.getNormalVector();
178 ri = in.
paired_pl2pl[idxPlane].p_local.plane.getNormalVector();
180 ASSERTDEB_LT_(std::abs(bi.norm() - 1.0), 0.01);
181 ASSERTDEB_LT_(std::abs(ri.norm() - 1.0), 0.01);
187 if (robustSqrtWeightFunc)
193 const double errorSqr = mrpt::square(ri2.x - bi.x) + mrpt::square(ri2.y - bi.y) +
194 mrpt::square(ri2.z - bi.z);
195 wi *= robustSqrtWeightFunc(errorSqr);
202 lambda_each_pair(bi, ri, wi);
206 in_out_outliers = std::move(new_outliers);
211 if (outStats.has_value()) outStats.value().get() = stats;