36template <
class C,
class TangentVector,
class ChartJacobian>
38 std::declval<const TangentVector&>(), std::declval<ChartJacobian>()));
41template <
class C,
class ChartJacobian>
43 C::Logmap(std::declval<const C&>(), std::declval<ChartJacobian>()));
47 return n == Eigen::Dynamic || m == Eigen::Dynamic ? Eigen::Dynamic : n + m;
52 return n == Eigen::Dynamic || m == Eigen::Dynamic ? Eigen::Dynamic : n * m;
64template <
class Class,
int N>
66 using TangentVector = Eigen::Matrix<double, N, 1>;
69 static Class Retract(
const TangentVector& v) {
70 if constexpr (N == Eigen::Dynamic) {
71 return Class::Expmap(v);
73 return Class::Identity().retract(v);
77 template <
class C = Class,
79 static Class Retract(
const TangentVector& v, ChartJacobian H) {
80 if constexpr (N == Eigen::Dynamic) {
81 return Class::Expmap(v, H);
83 return Class::Identity().retract(v, {}, H);
87 static TangentVector Local(
const Class& value) {
88 if constexpr (N == Eigen::Dynamic) {
89 return Class::Logmap(value);
91 return Class::Identity().localCoordinates(value);
95 template <
class C = Class,
97 static TangentVector Local(
const Class& value, ChartJacobian H) {
98 if constexpr (N == Eigen::Dynamic) {
99 return Class::Logmap(value, H);
101 return Class::Identity().localCoordinates(value, {}, H);
113template <
class Class,
int N>
115 inline constexpr static auto dimension = N;
117 typedef Eigen::Matrix<double, N, N> Jacobian;
118 typedef Eigen::Matrix<double, N, 1> TangentVector;
121 static constexpr int Dim() {
return N; }
125 std::enable_if_t<M != Eigen::Dynamic, int>
dim()
const {
129 const Class& derived()
const {
return static_cast<const Class&
>(*this); }
131 Class compose(
const Class& g)
const {
return derived() * g; }
133 Class between(
const Class& g)
const {
return derived().inverse() * g; }
135 Class compose(
const Class& g, ChartJacobian H1, ChartJacobian H2 = {})
const {
136 if (H1) *H1 = g.inverse().AdjointMap();
137 if (H2) *H2 = identityMatrix();
138 return derived() * g;
141 Class between(
const Class& g, ChartJacobian H1, ChartJacobian H2 = {})
const {
142 Class result = derived().inverse() * g;
143 if (H1) *H1 = -result.inverse().AdjointMap();
144 if (H2) *H2 = identityMatrix();
148 Class inverse(ChartJacobian H)
const {
149 if (H) *H = -derived().AdjointMap();
150 return derived().inverse();
155 Class
expmap(
const TangentVector& v)
const {
156 return compose(Class::Expmap(v));
161 TangentVector
logmap(
const Class& g)
const {
162 return Class::Logmap(between(g));
166 template <
class C = Class,
170 ChartJacobian H1, ChartJacobian H2 = {})
const {
172 Class g = Class::Expmap(v, H2 ? &D_g_v : 0);
173 Class h = compose(g);
174 if (H1) *H1 = g.inverse().AdjointMap();
180 template <
class C = Class,
181 class = internal::LogmapWithJacobian<C, ChartJacobian>>
183 ChartJacobian H1, ChartJacobian H2 = {})
const {
184 Class h = between(g);
186 TangentVector v = Class::Logmap(h, (H1 || H2) ? &D_v_h : 0);
187 if (H1) *H1 = -D_v_h * h.inverse().AdjointMap();
193 static Class
Retract(
const TangentVector& v) {
194 return Class::ChartAtOrigin::Retract(v);
200 return Class::ChartAtOrigin::Local(g);
204 template <
class C = Class,
class =
decltype(C::ChartAtOrigin::Retract(
205 std::declval<const TangentVector&>(),
206 std::declval<ChartJacobian>()))>
207 static Class
Retract(
const TangentVector& v, ChartJacobian H) {
208 return Class::ChartAtOrigin::Retract(v, H);
212 template <
class C = Class,
213 class =
decltype(C::ChartAtOrigin::Local(
214 std::declval<const C&>(), std::declval<ChartJacobian>()))>
216 return Class::ChartAtOrigin::Local(g, H);
221 return compose(Class::ChartAtOrigin::Retract(v));
227 return Class::ChartAtOrigin::Local(between(g));
231 template <
class C = Class,
class =
decltype(C::ChartAtOrigin::Retract(
232 std::declval<const TangentVector&>(),
233 std::declval<ChartJacobian>()))>
235 ChartJacobian H1, ChartJacobian H2 = {})
const {
237 Class g = Class::ChartAtOrigin::Retract(v, H2 ? &D_g_v : 0);
238 Class h = compose(g);
239 if (H1) *H1 = g.inverse().AdjointMap();
245 template <
class C = Class,
246 class =
decltype(C::ChartAtOrigin::Local(
247 std::declval<const C&>(), std::declval<ChartJacobian>()))>
250 ChartJacobian H2 = {})
const {
251 Class h = between(g);
253 TangentVector v = Class::ChartAtOrigin::Local(h, (H1 || H2) ? &D_v_h : 0);
254 if (H1) *H1 = -D_v_h * h.inverse().AdjointMap();
261 Jacobian identityMatrix()
const {
262 if constexpr (N == Eigen::Dynamic) {
263 return Jacobian::Identity(derived().
dim(), derived().
dim());
265 return Jacobian::Identity();
280template <
class Class>
288 static Class Identity() {
return Class::Identity(); }
293 using typename Manifold::ChartJacobian;
294 using typename Manifold::ManifoldType;
295 using typename Manifold::TangentVector;
296 inline constexpr static auto dimension = Manifold::dimension;
297 using Jacobian = Eigen::Matrix<double, dimension, dimension>;
302 static TangentVector
Logmap(
const Class& m) {
return Class::Logmap(m); }
304 template <
class C = Class,
306 static TangentVector
Logmap(
const Class& m, ChartJacobian Hm) {
307 return Class::Logmap(m, Hm);
310 static Class Expmap(
const TangentVector& v) {
return Class::Expmap(v); }
312 template <
class C = Class,
314 static Class Expmap(
const TangentVector& v, ChartJacobian Hv) {
315 return Class::Expmap(v, Hv);
318 static Class Compose(
const Class& m1,
const Class& m2,
319 ChartJacobian H1 = {}, ChartJacobian H2 = {}) {
320 return m1.compose(m2, H1, H2);
323 static Class Between(
const Class& m1,
const Class& m2,
324 ChartJacobian H1 = {}, ChartJacobian H2 = {}) {
325 return m1.between(m2, H1, H2);
328 static Class Inverse(
const Class& m,
329 ChartJacobian H = {}) {
333 static Eigen::Matrix<double, dimension, dimension> AdjointMap(
339 return m.AdjointMap();
345template <
class Class>
356template <
class Class>
358 return l1.inverse().compose(l2);
362template <
class Class>
364 return Class::Logmap(l0.between(lp));
368template <
class Class>
370 return t.compose(Class::Expmap(d));
380 static constexpr bool value =
381 std::is_base_of_v<lie_group_tag, typename traits<T>::structure_category>;
391 "This type's trait does not assert it is a Lie group (or derived)");
407 ChartJacobian Hg, Hh;
416 typename MakeOptionalJacobian<T, T>::type Hx = {},
417 typename MakeOptionalJacobian<T, T>::type Hy = {},
418 typename MakeOptionalJacobian<T, double>::type Ht = {}) {
419 if (Hx || Hy || Ht) {
420 typename MakeJacobian<T, T>::type between_H_x, log_H, exp_H, compose_H_x;
426 X, Delta, compose_H_x);
428 if (Hx) *Hx = compose_H_x + t * exp_H * log_H * between_H_x;
429 if (Hy) *Hy = t * exp_H * log_H;
442class TransformCovariance {
444 typename T::Jacobian adjointMap_;
447 explicit TransformCovariance(
const T& X) : adjointMap_{X.AdjointMap()} {}
448 typename T::Jacobian operator()(
const typename T::Jacobian& covariance) {
449 return adjointMap_ * covariance * adjointMap_.transpose();
463#define GTSAM_CONCEPT_LIE_INST(T) template class gtsam::IsLieGroup<T>;
464#define GTSAM_CONCEPT_LIE_TYPE(T) \
465 using _gtsam_IsLieGroup_##T = gtsam::IsLieGroup<T>;
Concept check class for variable types with Group properties.
Base class and basic functions for Manifold types.
constexpr int dimensionSum(int n, int m)
Sum compile-time dimensions, propagating Eigen::Dynamic.
Definition Lie.h:46
decltype(C::Expmap( std::declval< const TangentVector & >(), std::declval< ChartJacobian >())) ExpmapWithJacobian
Probe for a class static Expmap implementation with a Jacobian.
Definition Lie.h:37
constexpr int dimensionProduct(int n, int m)
Multiply compile-time dimensions, propagating Eigen::Dynamic.
Definition Lie.h:51
decltype( C::Logmap(std::declval< const C & >(), std::declval< ChartJacobian >())) LogmapWithJacobian
Probe for a class static Logmap implementation with a Jacobian.
Definition Lie.h:42
Global functions in a separate testing namespace.
Definition chartTesting.h:28
T interpolate(const T &X, const T &Y, double t, typename MakeOptionalJacobian< T, T >::type Hx={}, typename MakeOptionalJacobian< T, T >::type Hy={}, typename MakeOptionalJacobian< T, double >::type Ht={})
Linear interpolation between X and Y by coefficient t.
Definition Lie.h:415
Vector logmap_default(const Class &l0, const Class &lp)
Log map centered at l0, s.t.
Definition Lie.h:363
@ Logmap
Use the SE_2(3) NavState Logmap for every backend.
Definition PreintegrationParams.h:32
Class between_default(const Class &l1, const Class &l2)
These core global functions can be specialized by new Lie types for better performance.
Definition Lie.h:357
Class expmap_default(const Class &t, const Vector &d)
Exponential map centered at l0, s.t.
Definition Lie.h:369
tag to assert a type is a group
Definition Group.h:31
Group operator syntax flavors.
Definition Group.h:34
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
Group Concept.
Definition Group.h:43
Chart-at-origin adapter for LieGroup-derived classes with explicit instance retract/localCoordinates ...
Definition Lie.h:65
A CRTP helper class that implements Lie group methods Prerequisites: methods operator*,...
Definition Lie.h:114
static TangentVector LocalCoordinates(const Class &g, ChartJacobian H)
LocalCoordinates at origin with optional derivative, when provided.
Definition Lie.h:215
Class expmap(const TangentVector &v, ChartJacobian H1, ChartJacobian H2={}) const
expmap with optional derivatives, when the class provides them
Definition Lie.h:169
TangentVector localCoordinates(const Class &g) const
localCoordinates as required by manifold concept: finds tangent vector between *this and g
Definition Lie.h:226
static constexpr int Dim()
Static method to get the dimension (compile-time or dynamic).
Definition Lie.h:121
TangentVector localCoordinates(const Class &g, ChartJacobian H1, ChartJacobian H2={}) const
localCoordinates with optional derivatives, when the chart provides them
Definition Lie.h:248
TangentVector logmap(const Class &g, ChartJacobian H1, ChartJacobian H2={}) const
logmap with optional derivatives, when the class provides them
Definition Lie.h:182
static Class Retract(const TangentVector &v, ChartJacobian H)
Retract at origin with optional derivative, when the chart provides it.
Definition Lie.h:207
Class retract(const TangentVector &v, ChartJacobian H1, ChartJacobian H2={}) const
retract with optional derivatives, when the chart provides them
Definition Lie.h:234
TangentVector logmap(const Class &g) const
logmap as required by manifold concept Applies logarithmic map to group element that takes *this to g
Definition Lie.h:161
static TangentVector LocalCoordinates(const Class &g)
LocalCoordinates at origin: possible in Lie group because it has an identity.
Definition Lie.h:199
Class retract(const TangentVector &v) const
retract as required by manifold concept: applies v at *this
Definition Lie.h:220
Class expmap(const TangentVector &v) const
expmap as required by manifold concept Applies exponential map to v and composes with *this
Definition Lie.h:155
static Class Retract(const TangentVector &v)
Retract at origin: possible in Lie group because it has an identity.
Definition Lie.h:193
std::enable_if_t< M !=Eigen::Dynamic, int > dim() const
Provided fixed dimension in dim() if needed.
Definition Lie.h:125
tag to assert a type is a Lie group
Definition Lie.h:271
A helper class that implements the traits interface for GTSAM lie groups.
Definition Lie.h:281
Both LieGroupTraits and Testable.
Definition Lie.h:346
Lie Group Concept.
Definition Lie.h:377
tag to assert a type is a manifold
Definition Manifold.h:33
A helper that implements the traits interface for GTSAM manifolds.
Definition Manifold.h:104
Manifold concept.
Definition Manifold.h:172
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152