covariance.cpp
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  * A repertory of multi primitive-to-primitive (MP2P) ICP algorithms in C++
3  * Copyright (C) 2018-2024 Jose Luis Blanco, University of Almeria
4  * See LICENSE for license information.
5  * ------------------------------------------------------------------------- */
13 #include <mp2p_icp/covariance.h>
14 #include <mp2p_icp/errorTerms.h>
15 #include <mrpt/math/CVectorDynamic.h>
16 #include <mrpt/math/num_jacobian.h>
17 
18 #include <Eigen/Dense>
19 
20 using namespace mp2p_icp;
21 
22 mrpt::math::CMatrixDouble66 mp2p_icp::covariance(
23  const Pairings& in, const mrpt::poses::CPose3D& finalAlignSolution,
24  const CovarianceParameters& param)
25 {
26  // If we don't have pairings, we can't provide an estimation:
27  if (in.empty())
28  {
29  mrpt::math::CMatrixDouble66 cov;
30  cov.setDiagonal(1e6);
31  return cov;
32  }
33 
34  mrpt::math::CMatrixDouble61 xInitial;
35  xInitial[0] = finalAlignSolution.x();
36  xInitial[1] = finalAlignSolution.y();
37  xInitial[0] = finalAlignSolution.x();
38  xInitial[3] = finalAlignSolution.yaw();
39  xInitial[4] = finalAlignSolution.pitch();
40  xInitial[5] = finalAlignSolution.roll();
41 
42  mrpt::math::CMatrixDouble61 xIncrs;
43  for (int i = 0; i < 3; i++) xIncrs[i] = param.finDif_xyz;
44  for (int i = 0; i < 3; i++) xIncrs[3 + i] = param.finDif_angles;
45 
46  struct LambdaParams
47  {
48  };
49 
50  LambdaParams lmbParams;
51 
52  auto errorLambda = [&](const mrpt::math::CMatrixDouble61& x, const LambdaParams&,
53  mrpt::math::CVectorDouble& err)
54  {
55  mrpt::poses::CPose3D pose;
56  pose.setFromValues(x[0], x[1], x[2], x[3], x[4], x[5]);
57 
58  const auto nPt2Pt = in.paired_pt2pt.size();
59  const auto nPt2Ln = in.paired_pt2ln.size();
60  const auto nPt2Pl = in.paired_pt2pl.size();
61  const auto nPl2Pl = in.paired_pl2pl.size();
62  const auto nLn2Ln = in.paired_ln2ln.size();
63 
64  const auto nErrorTerms = (nPt2Pt + nPl2Pl + nPt2Ln + nPt2Pl) * 3 + nLn2Ln * 4;
65  ASSERT_(nErrorTerms > 0);
66  err.resize(nErrorTerms);
67 
68  // Point-to-point:
69  for (size_t idx_pt = 0; idx_pt < nPt2Pt; idx_pt++)
70  {
71  // Error:
72  const auto& p = in.paired_pt2pt[idx_pt];
73  mrpt::math::CVectorFixedDouble<3> ret = mp2p_icp::error_point2point(p, pose);
74  err.block<3, 1>(idx_pt * 3, 0) = ret.asEigen();
75  }
76  auto base_idx = nPt2Pt * 3;
77 
78  // Point-to-line
79  for (size_t idx_pt = 0; idx_pt < nPt2Ln; idx_pt++)
80  {
81  // Error
82  const auto& p = in.paired_pt2ln[idx_pt];
83  mrpt::math::CVectorFixedDouble<3> ret = mp2p_icp::error_point2line(p, pose);
84  err.block<3, 1>(base_idx + idx_pt * 3, 0) = ret.asEigen();
85  }
86  base_idx += nPt2Ln * 3;
87 
88  // Line-to-Line
89  // Minimum angle to approach zero
90  for (size_t idx_ln = 0; idx_ln < nLn2Ln; idx_ln++)
91  {
92  const auto& p = in.paired_ln2ln[idx_ln];
93  mrpt::math::CVectorFixedDouble<4> ret = mp2p_icp::error_line2line(p, pose);
94  err.block<4, 1>(base_idx + idx_ln * 4, 0) = ret.asEigen();
95  }
96  base_idx += nLn2Ln;
97 
98  // Point-to-plane:
99  for (size_t idx_pl = 0; idx_pl < nPt2Pl; idx_pl++)
100  {
101  // Error:
102  const auto& p = in.paired_pt2pl[idx_pl];
103  mrpt::math::CVectorFixedDouble<3> ret = mp2p_icp::error_point2plane(p, pose);
104  err.block<3, 1>(idx_pl * 3 + base_idx, 0) = ret.asEigen();
105  }
106  base_idx += nPt2Pl * 3;
107 
108  // Plane-to-plane (only direction of normal vectors):
109  for (size_t idx_pl = 0; idx_pl < nPl2Pl; idx_pl++)
110  {
111  // Error term:
112  const auto& p = in.paired_pl2pl[idx_pl];
113  mrpt::math::CVectorFixedDouble<3> ret = mp2p_icp::error_plane2plane(p, pose);
114  err.block<3, 1>(idx_pl * 3 + base_idx, 0) = ret.asEigen();
115  }
116  };
117 
118  // Do NOT use "Eigen::MatrixXd", it may have different alignment
119  // requirements than MRPT matrices:
120  mrpt::math::CMatrixDouble jacob;
121  mrpt::math::estimateJacobian(
122  xInitial,
123  std::function<void(
124  const mrpt::math::CMatrixDouble61&, const LambdaParams&, mrpt::math::CVectorDouble&)>(
125  errorLambda),
126  xIncrs, lmbParams, jacob);
127 
128  const mrpt::math::CMatrixDouble66 hessian(jacob.asEigen().transpose() * jacob.asEigen());
129 
130  const mrpt::math::CMatrixDouble66 cov = hessian.inverse_LLt();
131 
132  return cov;
133 }
134 
135 // other ideas?
136 // See: http://censi.mit.edu/pub/research/2007-icra-icpcov-slides.pdf
mp2p_icp
Definition: covariance.h:17
mp2p_icp::CovarianceParameters
Definition: covariance.h:19
mp2p_icp::Pairings
Definition: Pairings.h:76
mp2p_icp::Pairings::empty
virtual bool empty() const
Definition: Pairings.h:109
test.x
x
Definition: test.py:4
errorTerms.h
mp2p_icp::covariance
mrpt::math::CMatrixDouble66 covariance(const Pairings &finalPairings, const mrpt::poses::CPose3D &finalAlignSolution, const CovarianceParameters &p)
Definition: covariance.cpp:22
mp2p_icp::error_plane2plane
mrpt::math::CVectorFixedDouble< 3 > error_plane2plane(const mp2p_icp::matched_plane_t &pairing, const mrpt::poses::CPose3D &relativePose, mrpt::optional_ref< mrpt::math::CMatrixFixed< double, 3, 12 >> jacobian=std::nullopt)
Definition: errorTerms.cpp:320
mp2p_icp::error_point2plane
mrpt::math::CVectorFixedDouble< 3 > error_point2plane(const mp2p_icp::point_plane_pair_t &pairing, const mrpt::poses::CPose3D &relativePose, mrpt::optional_ref< mrpt::math::CMatrixFixed< double, 3, 12 >> jacobian=std::nullopt)
Definition: errorTerms.cpp:107
covariance.h
Covariance estimation methods for ICP results.
mp2p_icp::error_point2point
mrpt::math::CVectorFixedDouble< 3 > error_point2point(const mrpt::tfest::TMatchingPair &pairing, const mrpt::poses::CPose3D &relativePose, mrpt::optional_ref< mrpt::math::CMatrixFixed< double, 3, 12 >> jacobian=std::nullopt)
Definition: errorTerms.cpp:28
param
T param(const std::string &param_name, const T &default_val)
mp2p_icp::error_point2line
mrpt::math::CVectorFixedDouble< 3 > error_point2line(const mp2p_icp::point_line_pair_t &pairing, const mrpt::poses::CPose3D &relativePose, mrpt::optional_ref< mrpt::math::CMatrixFixed< double, 3, 12 >> jacobian=std::nullopt)
Definition: errorTerms.cpp:60
mp2p_icp::error_line2line
mrpt::math::CVectorFixedDouble< 4 > error_line2line(const mp2p_icp::matched_line_t &pairing, const mrpt::poses::CPose3D &relativePose, mrpt::optional_ref< mrpt::math::CMatrixFixed< double, 4, 12 >> jacobian=std::nullopt)
Definition: errorTerms.cpp:155


mp2p_icp
Author(s):
autogenerated on Mon May 26 2025 02:45:48