4.1 KiB
GTSAM Concepts
Concepts define (see Generic Programming Techniques)
- associated types
- valid expressions
- invariants
- complexity guarantees
GTSAM Types start with Uppercase, e.g., gtsam::Point2
, and are models of the concepts MANIFOLD, GROUP, LIE_GROUP, VECTOR_SPACE
traits
gtsam::traits
is our way to associate these concepts with types. We will not use Eigen-style or STL-style traits, that define many properties at once. Rather, we use boost::mpl style meta-programming functions to facilitate meta-programming.
Traits allow us to play with types that are outside GTSAM control, e.g., Eigen::VectorXd
.
The naming conventions are as follows:
-
Types:
gtsam::traits::SomeAssociatedType<T>::type
, i.e., they are MixedCase and define atype
, for example:template<> gtsam::traits::TangentVector<Point2> { typedef Vector2 type; }
-
Values:
gtsam::traits::someValue<T>::value
, i.e., they are mixedCase starting with a lowercase letter and define avalue
, but also avalue_type
. For example:template<> gtsam::traits::dimension<Point2> { static const int value = 2; typedef const int value_type; // const ? }
-
Functors:
gtsam::traits::someFunctor<T>::type
, i.e., they are mixedCase starting with a lowercase letter and define a functortype
. The funcor itself should define aresult_type
. Examplestruct Point2::retract { typedef Point2 result_type; Point2 p_; retract(const Point2& p) : p_(p) {} Point2 operator()(const Vector2& v) { return Point2(p.x()+v[0], p.y()+v[1]); } } template<> gtsam::traits::retract<Point2> { typedef Point2::retract type; }
The above is still up in the air. Do we need the type indirection? Could we just inherit the trait like so
template<> gtsam::traits::retract<Point2> : Point2::retract { }
In which case we could just say
gtsam::traits::retract<Point2>(p)(v)
.
tags
Concepts are associated with a tag.
gtsam::tags::manifold_tag
gtsam::tags::group_tag
gtsam::tags::lie_group_tag
gtsam::tags::vector_space_tag
Can be queried gtsam::traits::structure_tag<T>
Testable
- values:
print
,equals
Anything else?
Manifold
Manifolds and charts are intimately linked concepts. We are only interested here in differentiable manifolds, continuous spaces that can be locally approximated at any point using a local vector space, called the tangent space. A chart is an invertible map from the manifold to the vector space.
In GTSAM we assume that a manifold type can yield such a chart at any point, and we require that a functor defaultChart
is available that
- values:
dimension
- functors
defaultChart
- types:
DefaultChart
is the type of chart returned by the functordefaultChart
- invariants:
defaultChart::result_type == DefaultChart::type
Anything else?
Chart
- types:
Manifold
,Vector
- values:
retract
,local
Are these values? They are just methods. Anything else?
Group
- values:
identity
- values:
compose
,inverse
, (between
)
Lie Group
Implements both MANIFOLD and GROUP
Vector Space
Lie Group where compose == +
Examples
An example of implementing a Manifold is here:
// GTSAM type
class Rot2 {
...
class Chart {
...
}
}
namespace gtsam {
namespace traits {
template<>
struct DefaultChart<Rot2> {
typedef Rot2::Chart type;
}
template<>
struct Manifold<Rot2::Chart> {
typedef Rot2 type;
}
template<>
struct Vector<Rot2::Chart> {
typedef Vector2 type;
}
}