gtsam
Loading...
Searching...
No Matches
Manifold.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
19
20#pragma once
21
22#include <gtsam/base/Matrix.h>
23#include <gtsam/base/Testable.h>
25#include <gtsam/base/concepts.h>
26
27#include <type_traits>
28#include <utility>
29
30namespace gtsam {
31
33struct manifold_tag {};
34
52
53template <typename T> struct traits;
54
55namespace internal {
56
58template <class C, class ChartJacobian>
60 std::declval<const C&>().localCoordinates(
61 std::declval<const C&>(), std::declval<ChartJacobian>(),
62 std::declval<ChartJacobian>()));
63
65template <class C, class TangentVector, class ChartJacobian>
66using RetractWithJacobians = decltype(std::declval<const C&>().retract(
67 std::declval<const TangentVector&>(), std::declval<ChartJacobian>(),
68 std::declval<ChartJacobian>()));
69
71template<class Class>
73
74 inline constexpr static auto dim = Class::dimension;
75
76 Class p, q;
77 Eigen::Matrix<double, dim, 1> v;
79
80 GTSAM_CONCEPT_USAGE(HasManifoldPrereqs) {
81 v = p.localCoordinates(q);
82 q = p.retract(v);
83 }
84};
85
87template<class Class, int N>
89 // Get dimension at compile-time for fixed-size manifolds, and at
90 // run-time for dynamic-size manifolds.
91 static size_t GetDimension(const Class& m) {
92 if constexpr (N == Eigen::Dynamic) {
93 return m.dim();
94 } else {
95 return static_cast<size_t>(N);
96 }
97 }
98};
99
103template<class Class>
104struct ManifoldTraits: GetDimensionImpl<Class, Class::dimension> {
105
106 // Check that Class has the necessary machinery
107 GTSAM_CONCEPT_ASSERT(HasManifoldPrereqs<Class>);
108
109 // Dimension of the manifold
110 inline constexpr static auto dimension = Class::dimension;
111
112 // Typedefs required by all manifold types.
113 typedef Class ManifoldType;
114 typedef manifold_tag structure_category;
115 typedef Eigen::Matrix<double, dimension, 1> TangentVector;
116 typedef OptionalJacobian<dimension, dimension> ChartJacobian;
117
118 // Local coordinates
119 static TangentVector Local(const Class& origin, const Class& other) {
120 return origin.localCoordinates(other);
121 }
122
123 template <class C = Class,
125 static TangentVector Local(const Class& origin, const Class& other,
126 ChartJacobian H1, ChartJacobian H2 = {}) {
127 return origin.localCoordinates(other, H1, H2);
128 }
129
130 // Retraction back to manifold
131 static Class Retract(const Class& origin, const TangentVector& v) {
132 return origin.retract(v);
133 }
134
135 template <class C = Class,
137 static Class Retract(const Class& origin, const TangentVector& v,
138 ChartJacobian H1, ChartJacobian H2 = {}) {
139 return origin.retract(v, H1, H2);
140 }
141};
142
144template <class T, class = void>
145struct HasLocalJacobians : std::false_type {};
146
147template <class T>
149 T, std::void_t<decltype(traits<T>::Local(
150 std::declval<const T&>(), std::declval<const T&>(),
151 std::declval<typename traits<T>::ChartJacobian>(),
152 std::declval<typename traits<T>::ChartJacobian>()))>>
153 : std::true_type {};
154
156template<class Class> struct Manifold: ManifoldTraits<Class>, Testable<Class> {};
157
158} // \ namespace internal
159
161template<typename T>
162GTSAM_CONCEPT_REQUIRES(IsTestable<T>, bool) //
163check_manifold_invariants(const T& a, const T& b, double tol=1e-9) {
166 T c = traits<T>::Retract(a,v);
167 return v0.norm() < tol && traits<T>::Equals(b,c,tol);
168}
169
171template<typename T>
173
174public:
175
176 using structure_category_tag = typename traits<T>::structure_category;
177 static inline constexpr int dim = traits<T>::dimension;
178 using ManifoldType = typename traits<T>::ManifoldType;
179 using TangentVector = typename traits<T>::TangentVector;
180 // Concept marker: allows checking IsManifold<T>::value in templates
181 static constexpr bool value =
182 std::is_base_of_v<manifold_tag, structure_category_tag>;
183
184 GTSAM_CONCEPT_USAGE(IsManifold) {
185 static_assert(
186 value,
187 "This type's structure_category trait does not assert it as a manifold (or derived)");
188 if constexpr (dim != Eigen::Dynamic) {
189 static_assert(TangentVector::SizeAtCompileTime == dim);
190 }
191
192 // make sure Chart methods are defined
193 v = traits<T>::Local(p, q);
194 q = traits<T>::Retract(p, v);
195 }
196
197private:
198
199 TangentVector v;
200 ManifoldType p, q;
201};
202
204template<typename T>
206 using value_type = const int;
207 static inline constexpr int value = traits<T>::dimension;
208 static_assert(value != Eigen::Dynamic,
209 "FixedDimension instantiated for dynamically-sized type.");
210};
211} // \ namespace gtsam
212
214// * Macros for using the ManifoldConcept
215// * - An instantiation for use inside unit tests
216// * - A typedef for use inside generic algorithms
217// *
218// * NOTE: intentionally not in the gtsam namespace to allow for classes not in
219// * the gtsam namespace to be more easily enforced as testable
220// */
221#define GTSAM_CONCEPT_MANIFOLD_INST(T) template class gtsam::IsManifold<T>;
222#define GTSAM_CONCEPT_MANIFOLD_TYPE(T) using _gtsam_IsManifold_##T = gtsam::IsManifold<T>;
typedef and functions to augment Eigen's MatrixXd
Special class for optional Jacobian arguments.
Concept check for values that can be used in unit tests.
decltype(std::declval< const C & >().retract( std::declval< const TangentVector & >(), std::declval< ChartJacobian >(), std::declval< ChartJacobian >())) RetractWithJacobians
Probe for a class member retract implementation with Jacobians.
Definition Manifold.h:66
decltype( std::declval< const C & >().localCoordinates( std::declval< const C & >(), std::declval< ChartJacobian >(), std::declval< ChartJacobian >())) LocalCoordinatesWithJacobians
Probe for a class member localCoordinates implementation with Jacobians.
Definition Manifold.h:59
STL namespace.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
check_manifold_invariants(const T &a, const T &b, double tol=1e-9)
Check invariants for Manifold type.
Definition Manifold.h:163
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
tag to assert a type is a manifold
Definition Manifold.h:33
Requirements on type to pass it to Manifold template below.
Definition Manifold.h:72
Traits to get dimension, supporting both fixed and dynamic.
Definition Manifold.h:88
A helper that implements the traits interface for GTSAM manifolds.
Definition Manifold.h:104
Detect whether a traits type provides Local with Jacobians.
Definition Manifold.h:145
Both ManifoldTraits and Testable.
Definition Manifold.h:156
Manifold concept.
Definition Manifold.h:172
Give fixed size dimension of a type, fails at compile time if dynamic.
Definition Manifold.h:205
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
A testable concept check that should be placed in applicable unit tests and in generic algorithms.
Definition Testable.h:59
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152