gtsam
Loading...
Searching...
No Matches
TangentLieGroup-inl.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
3 * Atlanta, Georgia 30332-0415
4 * All Rights Reserved
5 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
6 * See LICENSE for the license information
7 * -------------------------------------------------------------------------- */
8
16
17#pragma once
18
19#include <unsupported/Eigen/MatrixFunctions>
20
21namespace gtsam {
22
23template <typename G>
24TangentLieGroup<G> TangentLieGroup<G>::operator*(
25 const TangentLieGroup& other) const {
26 const BaseJacobian Ad = traits<G>::AdjointMap(this->first);
27 return {traits<G>::Compose(this->first, other.first),
28 this->second + Ad * other.second};
29}
30
31template <typename G>
32TangentLieGroup<G> TangentLieGroup<G>::inverse() const {
33 const G gInverse = traits<G>::Inverse(this->first);
34 return {gInverse, -traits<G>::AdjointMap(gInverse) * this->second};
35}
36
37template <typename G>
38TangentLieGroup<G> TangentLieGroup<G>::retract(const TangentVector& xi,
39 ChartJacobian H1,
40 ChartJacobian H2) const {
41 Jacobian Dexp;
42 const TangentLieGroup delta = Expmap(xi, H2 ? &Dexp : nullptr);
43 const TangentLieGroup result = compose(delta);
44 if (H1) *H1 = delta.inverse().AdjointMap();
45 if (H2) *H2 = Dexp;
46 return result;
47}
48
49template <typename G>
50typename TangentLieGroup<G>::TangentVector TangentLieGroup<G>::localCoordinates(
51 const TangentLieGroup& other, ChartJacobian H1, ChartJacobian H2) const {
52 const TangentLieGroup relative = between(other);
53 Jacobian Dlog;
54 const TangentVector xi =
55 Logmap(relative, H1 || H2 ? ChartJacobian(&Dlog) : ChartJacobian());
56 if (H1) *H1 = -Dlog * relative.inverse().AdjointMap();
57 if (H2) *H2 = Dlog;
58 return xi;
59}
60
61template <typename G>
62TangentLieGroup<G> TangentLieGroup<G>::Expmap(const TangentVector& xi,
63 ChartJacobian H) {
64 const auto [u, v] = split(xi);
65 Matrix D1, D2;
66 const TangentLieGroup result =
67 Expmap(u, v, H ? SplitJacobian(D1) : SplitJacobian(),
68 H ? SplitJacobian(D2) : SplitJacobian());
69 if (H) {
70 H->leftCols(n) = D1;
71 H->rightCols(n) = D2;
72 }
73 return result;
74}
75
76template <typename G>
77TangentLieGroup<G> TangentLieGroup<G>::Expmap(
78 const Eigen::Ref<const BaseTangent>& u,
79 const Eigen::Ref<const BaseTangent>& v, SplitJacobian H1,
80 SplitJacobian H2) {
81 if constexpr (internal::TangentLieGroupJacobian<G>::expmapAvailable) {
82 Jacobian derivative;
83 const auto [g, transported] = internal::TangentLieGroupJacobian<G>::expmap(
84 u, v, H1 || H2 ? &derivative : nullptr);
85 if (H1) *H1 = derivative.leftCols(n);
86 if (H2) *H2 = derivative.rightCols(n);
87 return {g, transported};
88 }
89
90 BaseJacobian Dg;
91 const G g = traits<G>::Expmap(u, &Dg);
92 const BaseTangent transported = traits<G>::AdjointMap(g) * Dg * v;
93 if (H1) {
94 const Jacobian derivative = rightJacobian(join(u, v));
95 *H1 = derivative.leftCols(n);
96 if (H2) *H2 = derivative.rightCols(n);
97 } else if (H2) {
98 *H2 = Matrix::Zero(dimension, n);
99 H2->bottomRows(n) = Dg;
100 }
101 return {g, transported};
102}
103
104template <typename G>
105typename TangentLieGroup<G>::TangentVector TangentLieGroup<G>::Logmap(
106 const TangentLieGroup& p, ChartJacobian H) {
107 BaseJacobian Dg;
108 const BaseTangent u = traits<G>::Logmap(p.first, &Dg);
109 const BaseJacobian AdInverse =
111 const BaseTangent v = Dg * AdInverse * p.second;
112 const TangentVector xi = join(u, v);
113 if (H) {
114 const Jacobian derivative = rightJacobian(xi);
115 const BaseJacobian Q = derivative.template bottomLeftCorner<n, n>();
116 H->setZero();
117 H->template topLeftCorner<n, n>() = Dg;
118 H->template bottomRightCorner<n, n>() = Dg;
119 H->template bottomLeftCorner<n, n>() = -Dg * Q * Dg;
120 }
121 return xi;
122}
123
124template <typename G>
125typename TangentLieGroup<G>::Jacobian TangentLieGroup<G>::rightJacobian(
126 const TangentVector& xi) {
127 const auto [u, v] = split(xi);
128 if constexpr (internal::TangentLieGroupJacobian<G>::available) {
130 }
131
132 const BaseJacobian A = -G::adjointMap(u);
133 const BaseJacobian B = -G::adjointMap(v);
134 using Augmented = Eigen::Matrix<double, 3 * n, 3 * n>;
135 Augmented M = Augmented::Zero();
136 M.template block<n, n>(0, n).setIdentity();
137 M.template block<n, n>(n, n) = A;
138 M.template block<n, n>(n, 2 * n) = B;
139 M.template block<n, n>(2 * n, 2 * n) = A;
140 const Augmented expM = M.exp();
141 const BaseJacobian J = expM.template block<n, n>(0, n);
142 const BaseJacobian Q = expM.template block<n, n>(0, 2 * n);
143 Jacobian result = Jacobian::Zero();
144 result.template topLeftCorner<n, n>() = J;
145 result.template bottomRightCorner<n, n>() = J;
146 result.template bottomLeftCorner<n, n>() = Q;
147 return result;
148}
149
150template <typename G>
151typename TangentLieGroup<G>::Jacobian TangentLieGroup<G>::AdjointMap() const {
152 const BaseJacobian Ad = traits<G>::AdjointMap(this->first);
153 const BaseJacobian adV = G::adjointMap(this->second);
154 Jacobian result = Jacobian::Zero();
155 result.template topLeftCorner<n, n>() = Ad;
156 result.template bottomRightCorner<n, n>() = Ad;
157 result.template bottomLeftCorner<n, n>() = adV * Ad;
158 return result;
159}
160
161template <typename G>
162typename TangentLieGroup<G>::Jacobian TangentLieGroup<G>::adjointMap(
163 const TangentVector& xi) {
164 const auto [u, v] = split(xi);
165 const BaseJacobian adU = G::adjointMap(u);
166 Jacobian result = Jacobian::Zero();
167 result.template topLeftCorner<n, n>() = adU;
168 result.template bottomRightCorner<n, n>() = adU;
169 result.template bottomLeftCorner<n, n>() = G::adjointMap(v);
170 return result;
171}
172
173template <typename G>
174std::pair<typename TangentLieGroup<G>::BaseTangent,
175 typename TangentLieGroup<G>::BaseTangent>
176TangentLieGroup<G>::split(const TangentVector& xi) {
177 return {xi.template head<n>(), xi.template tail<n>()};
178}
179
180template <typename G>
181typename TangentLieGroup<G>::TangentVector TangentLieGroup<G>::join(
182 const BaseTangent& u, const BaseTangent& v) {
183 TangentVector xi;
184 xi << u, v;
185 return xi;
186}
187
188template <typename G>
189void TangentLieGroup<G>::print(const std::string& s) const {
190 std::cout << s << "TangentLieGroup" << std::endl;
191 traits<G>::Print(this->first, " group: ");
192 traits<BaseTangent>::Print(this->second, " tangent: ");
193}
194
195} // namespace gtsam
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Split the graph into two parts: one corresponds to the given spanning tree, and the other corresponds...
Definition graph-inl.h:245
@ Logmap
Use the SE_2(3) NavState Logmap for every backend.
Definition PreintegrationParams.h:32
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Optional closed-form kernels used by TangentLieGroup::Expmap() and its private rightJacobian() helper...
Definition TangentLieGroup.h:51
Tangent Lie group TG = G ⋉ 𝔤, with dimension 2 dim(G).
Definition TangentLieGroup.h:97