gtsam_points
Loading...
Searching...
No Matches
pose3_interpolation_factor.hpp
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2021 Kenji Koide (k.koide@aist.go.jp)
3
4#pragma once
5
6#include <gtsam/geometry/Pose3.h>
7#include <gtsam/nonlinear/NonlinearFactor.h>
8#include <gtsam_points/util/gtsam_migration.hpp>
9
10namespace gtsam_points {
11
15class Pose3InterpolationFactor : public gtsam::NoiseModelFactor3<gtsam::Pose3, gtsam::Pose3, gtsam::Pose3> {
16public:
17 Pose3InterpolationFactor(gtsam::Key xi, gtsam::Key xj, gtsam::Key xk, const double t, const gtsam::SharedNoiseModel& noise_model)
18 : gtsam::NoiseModelFactor3<gtsam::Pose3, gtsam::Pose3, gtsam::Pose3>(noise_model, xi, xj, xk),
19 t(t) {}
20
21 virtual ~Pose3InterpolationFactor() override {}
22
23 virtual void print(const std::string& s = "", const gtsam::KeyFormatter& keyFormatter = gtsam::DefaultKeyFormatter) const override {
24 std::cout << s << "Pose3InterpolationFactor";
25 std::cout << "(" << keyFormatter(this->keys()[0]) << ", " << keyFormatter(this->keys()[1]) << ", " << keyFormatter(this->keys()[2]) << ")"
26 << std::endl;
27 }
28
29public:
30 virtual gtsam::Vector evaluateError(
31 const gtsam::Pose3& xi,
32 const gtsam::Pose3& xj,
33 const gtsam::Pose3& xk,
34 OptionalMatrixType H_xi = NoneValue,
35 OptionalMatrixType H_xj = NoneValue,
36 OptionalMatrixType H_xk = NoneValue) const override {
37 //
38 const auto& Ri = xi.rotation();
39 const auto& Rj = xj.rotation();
40 const auto& Rk = xk.rotation();
41
42 const auto& ti = xi.translation();
43 const auto& tj = xj.translation();
44 const auto& tk = xk.translation();
45
46 if (!H_xi) {
47 const gtsam::Rot3 Rint = gtsam::interpolate(Ri, Rj, t);
48 const gtsam::Rot3 Re = Rk.between(Rint);
49 const gtsam::Vector3 re = gtsam::Rot3::Logmap(Re);
50 const gtsam::Vector3 te = tk - (1.0 - t) * ti - t * tj;
51
52 return (gtsam::Vector6() << re, te).finished();
53 }
54
55 gtsam::Matrix33 H_Rint_Ri, H_Rint_Rj;
56 const gtsam::Rot3 Rint = gtsam::interpolate(Ri, Rj, t, H_Rint_Ri, H_Rint_Rj);
57
58 // H_Re_Rint == Identity
59 gtsam::Matrix33 H_Re_Rk;
60 const gtsam::Rot3 Re = Rk.between(Rint, H_Re_Rk);
61
62 gtsam::Matrix33 H_re_Re;
63 const gtsam::Vector3 re = gtsam::Rot3::Logmap(Re, H_re_Re);
64
65 const gtsam::Vector3 te = tk - (1.0 - t) * ti - t * tj;
66
67 (*H_xi) = gtsam::Matrix6::Zero();
68 (*H_xj) = gtsam::Matrix6::Zero();
69 (*H_xk) = gtsam::Matrix6::Zero();
70
71 // const gtsam::Matrix3 H_re_Rint = H_re_Re * H_Re_Rint;
72 const auto& H_re_Rint = H_re_Re;
73 H_xi->block<3, 3>(0, 0) = H_re_Rint * H_Rint_Ri;
74 H_xj->block<3, 3>(0, 0) = H_re_Rint * H_Rint_Rj;
75 H_xk->block<3, 3>(0, 0) = H_re_Re * H_Re_Rk;
76
77 H_xi->block<3, 3>(3, 3) = -(1.0 - t) * Ri.matrix();
78 H_xj->block<3, 3>(3, 3) = -t * Rj.matrix();
79 H_xk->block<3, 3>(3, 3) = Rk.matrix();
80
81 return (gtsam::Vector6() << re, te).finished();
82 }
83
84 static gtsam::Pose3 initial_guess(const gtsam::Pose3& xi, const gtsam::Pose3& xj, const double t) {
85 const gtsam::Rot3 Rint = gtsam::interpolate(xi.rotation(), xj.rotation(), t);
86 const gtsam::Vector3 tint = (1.0 - t) * xi.translation() + t * xj.translation();
87 return gtsam::Pose3(Rint, tint);
88 }
89
90private:
91 const double t;
92};
93
94} // namespace gtsam_points
Factor(xi, xj, xk) s.t. xk = Slerp(xi, xj, t)
Definition pose3_interpolation_factor.hpp:15