Made clear template argument is a class, eliminated small amount of copy/paste.
parent
6648da20fe
commit
36f8510d7d
|
@ -21,43 +21,40 @@ template<typename T> struct traits_x;
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/// VectorSpace Implementation for Fixed sizes
|
/// VectorSpace Implementation for Fixed sizes
|
||||||
template<typename V, int N>
|
template<class Class, int N>
|
||||||
struct VectorSpaceImpl: Testable<V> {
|
struct VectorSpaceImpl {
|
||||||
|
|
||||||
typedef vector_space_tag structure_category;
|
typedef vector_space_tag structure_category;
|
||||||
|
|
||||||
/// @name Group
|
/// @name Group
|
||||||
/// @{
|
/// @{
|
||||||
typedef additive_group_tag group_flavor;
|
typedef additive_group_tag group_flavor;
|
||||||
static V Identity() { return V::identity();}
|
static Class Identity() { return Class::identity();}
|
||||||
static V Compose(const V& v1, const V& v2) { return v1+v2;}
|
static Class Compose(const Class& v1, const Class& v2) { return v1+v2;}
|
||||||
static V Between(const V& v1, const V& v2) { return v2-v1;}
|
static Class Between(const Class& v1, const Class& v2) { return v2-v1;}
|
||||||
static V Inverse(const V& m) { return -m;}
|
static Class Inverse(const Class& m) { return -m;}
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// @name Manifold
|
/// @name Manifold
|
||||||
/// @{
|
/// @{
|
||||||
enum { dimension = N };
|
|
||||||
typedef V ManifoldType;
|
|
||||||
typedef Eigen::Matrix<double, N, 1> TangentVector;
|
typedef Eigen::Matrix<double, N, 1> TangentVector;
|
||||||
typedef OptionalJacobian<N, N> ChartJacobian;
|
typedef OptionalJacobian<N, N> ChartJacobian;
|
||||||
static int GetDimension(const V& m) { return N;}
|
|
||||||
|
|
||||||
typedef Eigen::Matrix<double, N, N> Jacobian;
|
typedef Eigen::Matrix<double, N, N> Jacobian;
|
||||||
|
static int GetDimension(const Class&) { return N;}
|
||||||
|
|
||||||
static TangentVector Local(const V& origin, const V& other,
|
static TangentVector Local(const Class& origin, const Class& other,
|
||||||
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
||||||
if (H1) *H1 = - Jacobian::Identity();
|
if (H1) *H1 = - Jacobian::Identity();
|
||||||
if (H2) *H2 = Jacobian::Identity();
|
if (H2) *H2 = Jacobian::Identity();
|
||||||
V v = other-origin;
|
Class v = other-origin;
|
||||||
return v.vector();
|
return v.vector();
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Retract(const V& origin, const TangentVector& v,
|
static Class Retract(const Class& origin, const TangentVector& v,
|
||||||
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
||||||
if (H1) *H1 = Jacobian::Identity();
|
if (H1) *H1 = Jacobian::Identity();
|
||||||
if (H2) *H2 = Jacobian::Identity();
|
if (H2) *H2 = Jacobian::Identity();
|
||||||
return origin + V(v);
|
return origin + Class(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -65,31 +62,31 @@ struct VectorSpaceImpl: Testable<V> {
|
||||||
/// @name Lie Group
|
/// @name Lie Group
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
static TangentVector Logmap(const V& m, ChartJacobian Hm = boost::none) {
|
static TangentVector Logmap(const Class& m, ChartJacobian Hm = boost::none) {
|
||||||
if (Hm) *Hm = Jacobian::Identity();
|
if (Hm) *Hm = Jacobian::Identity();
|
||||||
return m.vector();
|
return m.vector();
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Expmap(const TangentVector& v, ChartJacobian Hv = boost::none) {
|
static Class Expmap(const TangentVector& v, ChartJacobian Hv = boost::none) {
|
||||||
if (Hv) *Hv = Jacobian::Identity();
|
if (Hv) *Hv = Jacobian::Identity();
|
||||||
return V(v);
|
return Class(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Compose(const V& v1, const V& v2, ChartJacobian H1,
|
static Class Compose(const Class& v1, const Class& v2, ChartJacobian H1,
|
||||||
ChartJacobian H2) {
|
ChartJacobian H2) {
|
||||||
if (H1) *H1 = Jacobian::Identity();
|
if (H1) *H1 = Jacobian::Identity();
|
||||||
if (H2) *H2 = Jacobian::Identity();
|
if (H2) *H2 = Jacobian::Identity();
|
||||||
return v1 + v2;
|
return v1 + v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Between(const V& v1, const V& v2, ChartJacobian H1,
|
static Class Between(const Class& v1, const Class& v2, ChartJacobian H1,
|
||||||
ChartJacobian H2) {
|
ChartJacobian H2) {
|
||||||
if (H1) *H1 = - Jacobian::Identity();
|
if (H1) *H1 = - Jacobian::Identity();
|
||||||
if (H2) *H2 = Jacobian::Identity();
|
if (H2) *H2 = Jacobian::Identity();
|
||||||
return v2 - v1;
|
return v2 - v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Inverse(const V& v, ChartJacobian H) {
|
static Class Inverse(const Class& v, ChartJacobian H) {
|
||||||
if (H) *H = - Jacobian::Identity();
|
if (H) *H = - Jacobian::Identity();
|
||||||
return -v;
|
return -v;
|
||||||
}
|
}
|
||||||
|
@ -97,47 +94,43 @@ struct VectorSpaceImpl: Testable<V> {
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// VectorSpace implementation for dynamic types. TODO get rid of copy/paste
|
/// VectorSpace implementation for dynamic types.
|
||||||
template<typename V>
|
template<class Class>
|
||||||
struct VectorSpaceImpl<V,Eigen::Dynamic>: Testable<V> {
|
struct VectorSpaceImpl<Class,Eigen::Dynamic> {
|
||||||
|
|
||||||
typedef vector_space_tag structure_category;
|
|
||||||
|
|
||||||
/// @name Group
|
/// @name Group
|
||||||
/// @{
|
/// @{
|
||||||
typedef additive_group_tag group_flavor;
|
typedef additive_group_tag group_flavor;
|
||||||
static V Identity() { return V::identity();}
|
static Class Identity() { return Class::identity();}
|
||||||
static V Compose(const V& v1, const V& v2) { return v1+v2;}
|
static Class Compose(const Class& v1, const Class& v2) { return v1+v2;}
|
||||||
static V Between(const V& v1, const V& v2) { return v2-v1;}
|
static Class Between(const Class& v1, const Class& v2) { return v2-v1;}
|
||||||
static V Inverse(const V& m) { return -m;}
|
static Class Inverse(const Class& m) { return -m;}
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// @name Manifold
|
/// @name Manifold
|
||||||
/// @{
|
/// @{
|
||||||
enum { dimension = V::dimension};
|
typedef Eigen::VectorXd TangentVector;
|
||||||
typedef V ManifoldType;
|
typedef OptionalJacobian<Eigen::Dynamic,Eigen::Dynamic> ChartJacobian;
|
||||||
typedef Eigen::Matrix<double, dimension, 1> TangentVector;
|
static int GetDimension(const Class& m) { return m.dim();}
|
||||||
typedef OptionalJacobian<dimension, dimension> ChartJacobian;
|
|
||||||
static int GetDimension(const V& m) { return m.dim();}
|
|
||||||
|
|
||||||
static Eigen::Matrix<double, dimension, dimension> Eye(const V& m) {
|
static Eigen::MatrixXd Eye(const Class& m) {
|
||||||
int dim = GetDimension(m);
|
int dim = GetDimension(m);
|
||||||
return Eigen::Matrix<double, dimension, dimension>::Identity(dim, dim);
|
return Eigen::MatrixXd::Identity(dim, dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TangentVector Local(const V& origin, const V& other,
|
static TangentVector Local(const Class& origin, const Class& other,
|
||||||
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
||||||
if (H1) *H1 = - Eye(origin);
|
if (H1) *H1 = - Eye(origin);
|
||||||
if (H2) *H2 = Eye(other);
|
if (H2) *H2 = Eye(other);
|
||||||
V v = other-origin;
|
Class v = other-origin;
|
||||||
return v.vector();
|
return v.vector();
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Retract(const V& origin, const TangentVector& v,
|
static Class Retract(const Class& origin, const TangentVector& v,
|
||||||
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
ChartJacobian H1 = boost::none, ChartJacobian H2 = boost::none) {
|
||||||
if (H1) *H1 = Eye(origin);
|
if (H1) *H1 = Eye(origin);
|
||||||
if (H2) *H2 = Eye(origin);
|
if (H2) *H2 = Eye(origin);
|
||||||
return origin + V(v);
|
return origin + Class(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -145,34 +138,33 @@ struct VectorSpaceImpl<V,Eigen::Dynamic>: Testable<V> {
|
||||||
/// @name Lie Group
|
/// @name Lie Group
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
static TangentVector Logmap(const V& m, ChartJacobian Hm = boost::none) {
|
static TangentVector Logmap(const Class& m, ChartJacobian Hm = boost::none) {
|
||||||
if (Hm) *Hm = Eye(m);
|
if (Hm) *Hm = Eye(m);
|
||||||
return m.vector();
|
return m.vector();
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Expmap(const TangentVector& v, ChartJacobian Hv = boost::none) {
|
static Class Expmap(const TangentVector& v, ChartJacobian Hv = boost::none) {
|
||||||
if (Hv) {
|
Class result(v);
|
||||||
ManifoldType m;
|
if (Hv)
|
||||||
*Hv = Eye(m);
|
*Hv = Eye(v);
|
||||||
}
|
return result;
|
||||||
return V(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Compose(const V& v1, const V& v2, ChartJacobian H1,
|
static Class Compose(const Class& v1, const Class& v2, ChartJacobian H1,
|
||||||
ChartJacobian H2) {
|
ChartJacobian H2) {
|
||||||
if (H1) *H1 = Eye(v1);
|
if (H1) *H1 = Eye(v1);
|
||||||
if (H2) *H2 = Eye(v2);
|
if (H2) *H2 = Eye(v2);
|
||||||
return v1 + v2;
|
return v1 + v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Between(const V& v1, const V& v2, ChartJacobian H1,
|
static Class Between(const Class& v1, const Class& v2, ChartJacobian H1,
|
||||||
ChartJacobian H2) {
|
ChartJacobian H2) {
|
||||||
if (H1) *H1 = - Eye(v1);
|
if (H1) *H1 = - Eye(v1);
|
||||||
if (H2) *H2 = Eye(v2);
|
if (H2) *H2 = Eye(v2);
|
||||||
return v2 - v1;
|
return v2 - v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static V Inverse(const V& v, ChartJacobian H) {
|
static Class Inverse(const Class& v, ChartJacobian H) {
|
||||||
if (H) *H = -Eye(v);
|
if (H) *H = -Eye(v);
|
||||||
return -v;
|
return -v;
|
||||||
}
|
}
|
||||||
|
@ -183,8 +175,18 @@ struct VectorSpaceImpl<V,Eigen::Dynamic>: Testable<V> {
|
||||||
/// A helper that implements the traits interface for GTSAM lie groups.
|
/// A helper that implements the traits interface for GTSAM lie groups.
|
||||||
/// To use this for your gtsam type, define:
|
/// To use this for your gtsam type, define:
|
||||||
/// template<> struct traits<Type> : public VectorSpace<Type> { };
|
/// template<> struct traits<Type> : public VectorSpace<Type> { };
|
||||||
template<typename V>
|
template<class Class>
|
||||||
struct VectorSpace: VectorSpaceImpl<V, V::dimension> {};
|
struct VectorSpace: Testable<Class>, VectorSpaceImpl<Class, Class::dimension> {
|
||||||
|
|
||||||
|
typedef vector_space_tag structure_category;
|
||||||
|
|
||||||
|
/// @name Manifold
|
||||||
|
/// @{
|
||||||
|
enum { dimension = Class::dimension};
|
||||||
|
typedef Class ManifoldType;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/// A helper that implements the traits interface for GTSAM lie groups.
|
/// A helper that implements the traits interface for GTSAM lie groups.
|
||||||
/// To use this for your gtsam type, define:
|
/// To use this for your gtsam type, define:
|
||||||
|
@ -398,11 +400,11 @@ struct traits_x<Eigen::Matrix<double, M, N, Options, MaxRows, MaxCols> > {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Vector Space concept
|
/// Vector Space concept
|
||||||
template<typename V>
|
template<typename T>
|
||||||
class IsVectorSpace: public IsLieGroup<V> {
|
class IsVectorSpace: public IsLieGroup<T> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename traits_x<V>::structure_category structure_category_tag;
|
typedef typename traits_x<T>::structure_category structure_category_tag;
|
||||||
|
|
||||||
BOOST_CONCEPT_USAGE(IsVectorSpace) {
|
BOOST_CONCEPT_USAGE(IsVectorSpace) {
|
||||||
BOOST_STATIC_ASSERT_MSG(
|
BOOST_STATIC_ASSERT_MSG(
|
||||||
|
@ -414,7 +416,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
V p, q, r;
|
T p, q, r;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
Loading…
Reference in New Issue