cyclic trait refactored
parent
edb1bbaa7b
commit
d94c8c72b8
|
@ -16,6 +16,9 @@
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/type_traits/is_base_of.hpp>
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
|
||||||
|
//FIXME temporary until all conflicts with namespace traits resolved
|
||||||
|
#define traits traits_foo
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
template <typename T> struct traits {};
|
template <typename T> struct traits {};
|
||||||
|
@ -35,7 +38,9 @@ struct vector_space_tag: public lie_group_tag {};
|
||||||
struct multiplicative_group_tag {};
|
struct multiplicative_group_tag {};
|
||||||
struct additive_group_tag {};
|
struct additive_group_tag {};
|
||||||
|
|
||||||
template<typename Transformation>
|
// a fictitious example
|
||||||
|
class Transformation;
|
||||||
|
template<>
|
||||||
struct traits<Transformation> {
|
struct traits<Transformation> {
|
||||||
|
|
||||||
// Typedefs required by all manifold types.
|
// Typedefs required by all manifold types.
|
||||||
|
@ -113,8 +118,8 @@ struct traits<Transformation> {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
BOOST_CONCEPT_REQUIRES(((Testable<traits<T> >)),(bool)) //
|
BOOST_CONCEPT_REQUIRES(((Testable<traits<T> >)),(bool)) //
|
||||||
check_manifold_invariants(const T& a, const T& b, double tol=1e-9) {
|
check_manifold_invariants(const T& a, const T& b, double tol=1e-9) {
|
||||||
traits<T>::TangentVector v0 = traits<T>::Local(a,a);
|
typename traits<T>::TangentVector v0 = traits<T>::Local(a,a);
|
||||||
traits<T>::TangentVector v = traits<T>::Local(a,b);
|
typename traits<T>::TangentVector v = traits<T>::Local(a,b);
|
||||||
T c = traits<T>::Retract(a,v);
|
T c = traits<T>::Retract(a,v);
|
||||||
return v0.norm() < tol && traits<T>::Equals(b,c,tol);
|
return v0.norm() < tol && traits<T>::Equals(b,c,tol);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +179,6 @@ class IsGroup {
|
||||||
public:
|
public:
|
||||||
typedef typename traits<G>::structure_category structure_category_tag;
|
typedef typename traits<G>::structure_category structure_category_tag;
|
||||||
typedef typename traits<G>::group_flavor flavor_tag;
|
typedef typename traits<G>::group_flavor flavor_tag;
|
||||||
static const size_t dim = traits<G>::dimension;
|
|
||||||
//typedef typename traits<G>::identity::value_type identity_value_type;
|
//typedef typename traits<G>::identity::value_type identity_value_type;
|
||||||
|
|
||||||
BOOST_CONCEPT_USAGE(IsGroup) {
|
BOOST_CONCEPT_USAGE(IsGroup) {
|
||||||
|
@ -216,7 +220,7 @@ check_group_invariants(const G& a, const G& b, double tol = 1e-9) {
|
||||||
|
|
||||||
|
|
||||||
#define GTSAM_ADDITIVE_GROUP(GROUP) \
|
#define GTSAM_ADDITIVE_GROUP(GROUP) \
|
||||||
typedef additive_gropu_tag group_flavor; \
|
typedef additive_group_tag group_flavor; \
|
||||||
static GROUP Compose(const GROUP &g, const GROUP & h) { return g + h;} \
|
static GROUP Compose(const GROUP &g, const GROUP & h) { return g + h;} \
|
||||||
static GROUP Between(const GROUP &g, const GROUP & h) { return h - g;} \
|
static GROUP Between(const GROUP &g, const GROUP & h) { return h - g;} \
|
||||||
static GROUP Inverse(const GROUP &g) { return -g;}
|
static GROUP Inverse(const GROUP &g) { return -g;}
|
||||||
|
@ -259,7 +263,7 @@ public:
|
||||||
private:
|
private:
|
||||||
LG g, h;
|
LG g, h;
|
||||||
TangentVector v;
|
TangentVector v;
|
||||||
OptionalJacobian Hg, Hh;
|
ChartJacobian Hg, Hh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,16 +64,14 @@ public:
|
||||||
|
|
||||||
#define CYCLIC_TEMPLATE size_t N
|
#define CYCLIC_TEMPLATE size_t N
|
||||||
#define CYCLIC_TYPE Cyclic<N>
|
#define CYCLIC_TYPE Cyclic<N>
|
||||||
GTSAM_GROUP_IDENTITY(CYCLIC_TEMPLATE, CYCLIC_TYPE)
|
|
||||||
GTSAM_ADDITIVE_GROUP(CYCLIC_TEMPLATE, CYCLIC_TYPE)
|
|
||||||
|
|
||||||
/// Define cyclic group to be a model of the Group concept
|
/// Define cyclic group traits to be a model of the Group concept
|
||||||
namespace traits {
|
template <CYCLIC_TEMPLATE>
|
||||||
template<size_t N>
|
struct traits<CYCLIC_TYPE > {
|
||||||
struct structure_category<Cyclic<N> > {
|
typedef group_tag structure_category;
|
||||||
typedef group_tag type;
|
GTSAM_ADDITIVE_GROUP(CYCLIC_TYPE);
|
||||||
|
static const CYCLIC_TYPE identity = CYCLIC_TYPE::Identity();
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
} // \namespace gtsam
|
} // \namespace gtsam
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
#include <gtsam/base/concepts.h>
|
#include <gtsam/base/concepts.h>
|
||||||
#include <gtsam/base/Matrix.h>
|
#include <gtsam/base/Matrix.h>
|
||||||
#include <Geometry/Quaternion.h>
|
|
||||||
|
|
||||||
#define QUATERNION_TEMPLATE typename _Scalar, int _Options
|
#define QUATERNION_TEMPLATE typename _Scalar, int _Options
|
||||||
#define QUATERNION_TYPE Eigen::Quaternion<_Scalar,_Options>
|
#define QUATERNION_TYPE Eigen::Quaternion<_Scalar,_Options>
|
||||||
|
@ -37,7 +36,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
typedef Eigen::Matrix<_Scalar, 3, 1, _Options, 3, 1> TangentVector;
|
typedef Eigen::Matrix<_Scalar, 3, 1, _Options, 3, 1> TangentVector;
|
||||||
typedef OptionalJacobian<3, 3> ChartJacobian;
|
typedef OptionalJacobian<3, 3> ChartJacobian;
|
||||||
|
|
||||||
static Q Compose(const Q &g, const Q & h, ChartJacobian Hg=NULL, ChartJacobian Hh=NULL) {
|
static Q Compose(const Q &g, const Q & h, ChartJacobian Hg=boost::none, ChartJacobian Hh=boost::none) {
|
||||||
if (Hg) {
|
if (Hg) {
|
||||||
//TODO : check Jacobian consistent with chart ( h.toRotationMatrix().transpose() ? )
|
//TODO : check Jacobian consistent with chart ( h.toRotationMatrix().transpose() ? )
|
||||||
*Hg = h.toRotationMatrix().transpose();
|
*Hg = h.toRotationMatrix().transpose();
|
||||||
|
@ -48,7 +47,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
}
|
}
|
||||||
return g * h;
|
return g * h;
|
||||||
}
|
}
|
||||||
static Q Between(const Q &g, const Q & h, ChartJacobian Hg=NULL, ChartJacobian Hh=NULL) {
|
static Q Between(const Q &g, const Q & h, ChartJacobian Hg=boost::none, ChartJacobian Hh=boost::none) {
|
||||||
Q d = g.inverse() * h;
|
Q d = g.inverse() * h;
|
||||||
if (Hg) {
|
if (Hg) {
|
||||||
//TODO : check Jacobian consistent with chart
|
//TODO : check Jacobian consistent with chart
|
||||||
|
@ -60,7 +59,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
static Q Inverse(const Q &g, ChartJacobian H=NULL) {
|
static Q Inverse(const Q &g, ChartJacobian H=boost::none) {
|
||||||
if (H) {
|
if (H) {
|
||||||
//TODO : check Jacobian consistent with chart
|
//TODO : check Jacobian consistent with chart
|
||||||
*H = -g.toRotationMatrix();
|
*H = -g.toRotationMatrix();
|
||||||
|
@ -70,7 +69,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
|
|
||||||
/// Exponential map, simply be converting omega to axis/angle representation
|
/// Exponential map, simply be converting omega to axis/angle representation
|
||||||
// TODO: implement Jacobian
|
// TODO: implement Jacobian
|
||||||
static Q Expmap(const Eigen::Ref<const TangentVector >& omega, ChartJacobian H=NULL) {
|
static Q Expmap(const Eigen::Ref<const TangentVector >& omega, ChartJacobian H=boost::none) {
|
||||||
if (omega.isZero())
|
if (omega.isZero())
|
||||||
return Q::Identity();
|
return Q::Identity();
|
||||||
else {
|
else {
|
||||||
|
@ -81,7 +80,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
|
|
||||||
/// We use our own Logmap, as there is a slight bug in Eigen
|
/// We use our own Logmap, as there is a slight bug in Eigen
|
||||||
// TODO: implement Jacobian
|
// TODO: implement Jacobian
|
||||||
static TangentVector Logmap(const Q& q, ChartJacobian H=NULL) {
|
static TangentVector Logmap(const Q& q, ChartJacobian H=boost::none) {
|
||||||
using std::acos;
|
using std::acos;
|
||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
static const double twoPi = 2.0 * M_PI,
|
static const double twoPi = 2.0 * M_PI,
|
||||||
|
@ -109,7 +108,7 @@ struct traits<QUATERNION_TYPE> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TangentVector Local(const Q& origin, const Q& other, ChartJacobian Horigin=NULL, ChartJacobian Hother=NULL) {
|
static TangentVector Local(const Q& origin, const Q& other, ChartJacobian Horigin=boost::none, ChartJacobian Hother=boost::none) {
|
||||||
return Logmap(Between(origin,other,Horigin,Hother));
|
return Logmap(Between(origin,other,Horigin,Hother));
|
||||||
// TODO: incorporate Jacobian of Logmap
|
// TODO: incorporate Jacobian of Logmap
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue