small_gicp
gicp_factor.hpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright 2024 Kenji Koide
2 // SPDX-License-Identifier: MIT
3 #pragma once
4 
5 #include <Eigen/Core>
6 #include <Eigen/Geometry>
10 
11 namespace small_gicp {
12 
14 struct GICPFactor {
15  struct Setting {};
16 
18  GICPFactor(const Setting& setting = Setting())
19  : target_index(std::numeric_limits<size_t>::max()),
20  source_index(std::numeric_limits<size_t>::max()),
21  mahalanobis(Eigen::Matrix4d::Zero()) {}
22 
34  template <typename TargetPointCloud, typename SourcePointCloud, typename TargetTree, typename CorrespondenceRejector>
35  bool linearize(
36  const TargetPointCloud& target,
37  const SourcePointCloud& source,
38  const TargetTree& target_tree,
39  const Eigen::Isometry3d& T,
40  size_t source_index,
41  const CorrespondenceRejector& rejector,
42  Eigen::Matrix<double, 6, 6>* H,
43  Eigen::Matrix<double, 6, 1>* b,
44  double* e) {
45  //
46  this->source_index = source_index;
47  this->target_index = std::numeric_limits<size_t>::max();
48 
49  const Eigen::Vector4d transed_source_pt = T * traits::point(source, source_index);
50 
51  size_t k_index;
52  double k_sq_dist;
53  if (!traits::nearest_neighbor_search(target_tree, transed_source_pt, &k_index, &k_sq_dist) || rejector(target, source, T, k_index, source_index, k_sq_dist)) {
54  return false;
55  }
56 
57  target_index = k_index;
58 
59  const Eigen::Matrix4d RCR = traits::cov(target, target_index) + T.matrix() * traits::cov(source, source_index) * T.matrix().transpose();
60  mahalanobis.block<3, 3>(0, 0) = RCR.block<3, 3>(0, 0).inverse();
61 
62  const Eigen::Vector4d residual = traits::point(target, target_index) - transed_source_pt;
63 
64  Eigen::Matrix<double, 4, 6> J = Eigen::Matrix<double, 4, 6>::Zero();
65  J.block<3, 3>(0, 0) = T.linear() * skew(traits::point(source, source_index).template head<3>());
66  J.block<3, 3>(0, 3) = -T.linear();
67 
68  *H = J.transpose() * mahalanobis * J;
69  *b = J.transpose() * mahalanobis * residual;
70  *e = 0.5 * residual.transpose() * mahalanobis * residual;
71 
72  return true;
73  }
74 
80  template <typename TargetPointCloud, typename SourcePointCloud>
81  double error(const TargetPointCloud& target, const SourcePointCloud& source, const Eigen::Isometry3d& T) const {
82  if (target_index == std::numeric_limits<size_t>::max()) {
83  return 0.0;
84  }
85 
86  const Eigen::Vector4d transed_source_pt = T * traits::point(source, source_index);
87  const Eigen::Vector4d residual = traits::point(target, target_index) - transed_source_pt;
88  return 0.5 * residual.transpose() * mahalanobis * residual;
89  }
90 
92  bool inlier() const { return target_index != std::numeric_limits<size_t>::max(); }
93 
94  size_t target_index;
95  size_t source_index;
96  Eigen::Matrix4d mahalanobis;
97 };
98 } // namespace small_gicp
size_t nearest_neighbor_search(const T &tree, const Eigen::Vector4d &point, size_t *k_index, double *k_sq_dist)
Find the nearest neighbor. If Traits<T>::nearest_neighbor_search is not defined, fallback to knn_sear...
Definition: traits.hpp:44
auto point(const T &points, size_t i)
Get i-th point. 4D vector is used to take advantage of SIMD intrinsics. The last element must be fill...
Definition: traits.hpp:40
auto cov(const T &points, size_t i)
Get i-th covariance. Only the top-left 3x3 matrix is filled, and the bottom row and the right col mus...
Definition: traits.hpp:52
Definition: flat_container.hpp:12
Eigen::Matrix3d skew(const Eigen::Vector3d &x)
Create skew symmetric matrix.
Definition: lie.hpp:13
Definition: gicp_factor.hpp:15
GICP (distribution-to-distribution) per-point error factor.
Definition: gicp_factor.hpp:14
GICPFactor(const Setting &setting=Setting())
Constructor.
Definition: gicp_factor.hpp:18
bool inlier() const
Returns true if this factor is not rejected as an outlier.
Definition: gicp_factor.hpp:92
Eigen::Matrix4d mahalanobis
Fused precision matrix.
Definition: gicp_factor.hpp:96
size_t target_index
Target point index.
Definition: gicp_factor.hpp:94
bool linearize(const TargetPointCloud &target, const SourcePointCloud &source, const TargetTree &target_tree, const Eigen::Isometry3d &T, size_t source_index, const CorrespondenceRejector &rejector, Eigen::Matrix< double, 6, 6 > *H, Eigen::Matrix< double, 6, 1 > *b, double *e)
Linearize the factor.
Definition: gicp_factor.hpp:35
double error(const TargetPointCloud &target, const SourcePointCloud &source, const Eigen::Isometry3d &T) const
Evaluate error.
Definition: gicp_factor.hpp:81
size_t source_index
Source point index.
Definition: gicp_factor.hpp:95