Skip to content

Commit b6675f5

Browse files
authored
Merge pull request #2192 from borglab/feature/custom_vecs
Bespoke vec methods
2 parents a16dff3 + 3fc5ab5 commit b6675f5

26 files changed

+368
-115
lines changed

gtsam/base/Group.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <gtsam/base/Testable.h>
2424

2525
#include <utility>
26+
#include <type_traits>
2627

2728
namespace gtsam {
2829

@@ -47,28 +48,25 @@ class IsGroup {
4748

4849
GTSAM_CONCEPT_USAGE(IsGroup) {
4950
static_assert(
50-
(std::is_base_of<group_tag, structure_category_tag>::value),
51+
(std::is_base_of_v<group_tag, structure_category_tag>),
5152
"This type's structure_category trait does not assert it as a group (or derived)");
5253
e = traits<G>::Identity();
5354
e = traits<G>::Compose(g, h);
5455
e = traits<G>::Between(g, h);
5556
e = traits<G>::Inverse(g);
56-
operator_usage(flavor);
57+
58+
if constexpr (std::is_same_v<flavor_tag, multiplicative_group_tag>) {
59+
e = g * h;
60+
//e = -g; // todo this should work, but it is failing for Quaternions
61+
} else if constexpr (std::is_same_v<flavor_tag, additive_group_tag>) {
62+
e = g + h;
63+
e = h - g;
64+
e = -g;
65+
}
5766
// todo: how do we test the act concept? or do we even need to?
5867
}
5968

6069
private:
61-
void operator_usage(multiplicative_group_tag) {
62-
e = g * h;
63-
//e = -g; // todo this should work, but it is failing for Quaternions
64-
}
65-
void operator_usage(additive_group_tag) {
66-
e = g + h;
67-
e = h - g;
68-
e = -g;
69-
}
70-
71-
flavor_tag flavor;
7270
G e, g, h;
7371
bool b;
7472
};

gtsam/base/Lie.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <gtsam/base/Manifold.h>
2727
#include <gtsam/base/Group.h>
2828

29+
#include <type_traits>
30+
2931
namespace gtsam {
3032

3133
/// A CRTP helper class that implements Lie group methods
@@ -56,15 +58,15 @@ struct LieGroup {
5658
Class compose(const Class& g, ChartJacobian H1,
5759
ChartJacobian H2 = {}) const {
5860
if (H1) *H1 = g.inverse().AdjointMap();
59-
if (H2) *H2 = Eigen::Matrix<double, N, N>::Identity();
61+
if (H2) *H2 = identityMatrix();
6062
return derived() * g;
6163
}
6264

6365
Class between(const Class& g, ChartJacobian H1,
6466
ChartJacobian H2 = {}) const {
6567
Class result = derived().inverse() * g;
6668
if (H1) *H1 = - result.inverse().AdjointMap();
67-
if (H2) *H2 = Eigen::Matrix<double, N, N>::Identity();
69+
if (H2) *H2 = identityMatrix();
6870
return result;
6971
}
7072

@@ -158,6 +160,17 @@ struct LieGroup {
158160
if (H2) *H2 = D_v_h;
159161
return v;
160162
}
163+
164+
private:
165+
166+
// Helper to get identity matrix of correct size for static or dynamic N
167+
Jacobian identityMatrix() const {
168+
if constexpr (N == Eigen::Dynamic) {
169+
return Jacobian::Identity(derived().dim(), derived().dim());
170+
} else {
171+
return Jacobian::Identity();
172+
}
173+
}
161174
};
162175

163176
/// tag to assert a type is a Lie group
@@ -271,12 +284,12 @@ class IsLieGroup: public IsGroup<T>, public IsManifold<T> {
271284
public:
272285
// Concept marker: allows checking IsLieGroup<T>::value in templates
273286
static constexpr bool value =
274-
std::is_base_of<lie_group_tag, typename traits<T>::structure_category>::value;
287+
std::is_base_of_v<lie_group_tag, typename traits<T>::structure_category>;
275288

276-
typedef typename traits<T>::structure_category structure_category_tag;
277-
typedef typename traits<T>::ManifoldType ManifoldType;
278-
typedef typename traits<T>::TangentVector TangentVector;
279-
typedef typename traits<T>::ChartJacobian ChartJacobian;
289+
using structure_category_tag = typename traits<T>::structure_category;
290+
using ManifoldType = typename traits<T>::ManifoldType;
291+
using TangentVector = typename traits<T>::TangentVector;
292+
using ChartJacobian = typename traits<T>::ChartJacobian;
280293

281294
GTSAM_CONCEPT_USAGE(IsLieGroup) {
282295
static_assert(

gtsam/base/Manifold.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <gtsam/base/OptionalJacobian.h>
2525
#include <gtsam/base/concepts.h>
2626

27+
#include <type_traits>
28+
2729
namespace gtsam {
2830

2931
/// tag to assert a type is a manifold
@@ -67,21 +69,17 @@ struct HasManifoldPrereqs {
6769
}
6870
};
6971

70-
/// Extra manifold traits for fixed-dimension types
72+
/// Traits to get dimension, supporting both fixed and dynamic
7173
template<class Class, int N>
7274
struct GetDimensionImpl {
73-
// Compile-time dimensionality
74-
static int GetDimension(const Class&) {
75-
return N;
76-
}
77-
};
78-
79-
/// Extra manifold traits for variable-dimension types
80-
template<class Class>
81-
struct GetDimensionImpl<Class, Eigen::Dynamic> {
82-
// Run-time dimensionality
75+
// Get dimension at compile-time for fixed-size manifolds, and at
76+
// run-time for dynamic-size manifolds.
8377
static int GetDimension(const Class& m) {
84-
return m.dim();
78+
if constexpr (N == Eigen::Dynamic) {
79+
return m.dim();
80+
} else {
81+
return N;
82+
}
8583
}
8684
};
8785

@@ -134,19 +132,21 @@ class IsManifold {
134132

135133
public:
136134

137-
typedef typename traits<T>::structure_category structure_category_tag;
138-
static const int dim = traits<T>::dimension;
139-
typedef typename traits<T>::ManifoldType ManifoldType;
140-
typedef typename traits<T>::TangentVector TangentVector;
135+
using structure_category_tag = typename traits<T>::structure_category;
136+
static inline constexpr int dim = traits<T>::dimension;
137+
using ManifoldType = typename traits<T>::ManifoldType;
138+
using TangentVector = typename traits<T>::TangentVector;
141139
// Concept marker: allows checking IsManifold<T>::value in templates
142140
static constexpr bool value =
143-
std::is_base_of<manifold_tag, structure_category_tag>::value;
141+
std::is_base_of_v<manifold_tag, structure_category_tag>;
144142

145143
GTSAM_CONCEPT_USAGE(IsManifold) {
146144
static_assert(
147145
value,
148146
"This type's structure_category trait does not assert it as a manifold (or derived)");
149-
static_assert(TangentVector::SizeAtCompileTime == dim);
147+
if constexpr (dim != Eigen::Dynamic) {
148+
static_assert(TangentVector::SizeAtCompileTime == dim);
149+
}
150150

151151
// make sure Chart methods are defined
152152
v = traits<T>::Local(p, q);
@@ -162,8 +162,8 @@ class IsManifold {
162162
/// Give fixed size dimension of a type, fails at compile time if dynamic
163163
template<typename T>
164164
struct FixedDimension {
165-
typedef const int value_type;
166-
static const int value = traits<T>::dimension;
165+
using value_type = const int;
166+
static inline constexpr int value = traits<T>::dimension;
167167
static_assert(value != Eigen::Dynamic,
168168
"FixedDimension instantiated for dynamically-sized type.");
169169
};

gtsam/base/MatrixLieGroup.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ namespace gtsam {
173173
template<typename T>
174174
class IsMatrixLieGroup : public IsLieGroup<T> {
175175
public:
176-
typedef typename traits<T>::LieAlgebra LieAlgebra;
177-
typedef typename traits<T>::TangentVector TangentVector;
176+
using LieAlgebra = typename traits<T>::LieAlgebra;
177+
using TangentVector = typename traits<T>::TangentVector;
178178

179179
GTSAM_CONCEPT_USAGE(IsMatrixLieGroup) {
180180
// hat and vee
@@ -207,7 +207,7 @@ namespace gtsam {
207207
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V43
208208
/// @deprecated: use T::Hat
209209
template <class T>
210-
Matrix wedge(const Vector& x) {
210+
[[deprecated("use T::Hat instead")]] Matrix wedge(const Vector& x) {
211211
return T::Hat(x);
212212
}
213213
#endif

0 commit comments

Comments
 (0)