diff --git a/gtsam/base/concepts.h b/gtsam/base/concepts.h index fb62ddd0b..7935ab56b 100644 --- a/gtsam/base/concepts.h +++ b/gtsam/base/concepts.h @@ -18,15 +18,7 @@ namespace gtsam { -namespace traits { - -/** - * @name Algebraic Structure Traits - * @brief Associate a unique tag with each of the main GTSAM concepts - */ -//@{ -template struct structure_category; -//@} +template struct traits {}; /** * @name Algebraic Structure Tags @@ -39,46 +31,110 @@ struct lie_group_tag: public manifold_tag, public group_tag {}; struct vector_space_tag: public lie_group_tag {}; //@} -}// namespace traits +// Group operator syntax flavors +struct multiplicative_group_tag {}; +struct additive_group_tag {}; -namespace manifold { +template +struct traits { -/** @name Free functions any Manifold needs to define */ -//@{ -//@} + // Typedefs required by all manifold types. + typedef multiplicative_group_tag group_flavor; + typedef lie_group_tag structure_category; + typedef Transformation ManifoldType; -namespace traits { + enum { dimension = 6 }; + typedef Eigen::Matrix TangentVector; + typedef OptionalJacobian ChartJacobian; -/** @name Manifold Traits */ -//@{ -template struct dimension; -template struct TangentVector; -template struct DefaultChart; -template struct ChartJacobian { - typedef OptionalJacobian::value, dimension::value> value; + // Required by all Manifold types. + static TangentVector Local(const ManifoldType& origin, + const ManifoldType& other); + + static ManifoldType Retract(const ManifoldType& origin, + const TangentVector& v); + + static int GetDimension(const ManifoldType& m){ return dimension; } + + // For Group. Only implemented for groups + static ManifoldType Compose(const ManifoldType& m1, + const ManifoldType& m2); + static ManifoldType Between(const ManifoldType& m1, + const ManifoldType& m2); + static ManifoldType Inverse(const ManifoldType& m); + + static Vector3 Act(const ManifoldType& T, + const Vector3& p); + static Vector3 Act(const ManifoldType& T, + const Vector3& p, + OptionalJacobian<3,3> Hp); + + + // For Lie Group. Only implemented for lie groups. + static ManifoldType Compose(const ManifoldType& m1, + const ManifoldType& m2, + ChartJacobian H1, + ChartJacobian H2); + static ManifoldType Between(const ManifoldType& m1, + const ManifoldType& m2, + ChartJacobian H1, + ChartJacobian H2); + static ManifoldType Inverse(const ManifoldType& m, + ChartJacobian H); + static Vector3 Act(const ManifoldType& T, + const Vector3& p, + OptionalJacobian<3, dimension> HT, + OptionalJacobian<3, 3> Hp); + static const ManifoldType Identity; + static TangentVector Local(const ManifoldType& origin, + const ManifoldType& other, + ChartJacobian Horigin, + ChartJacobian Hother); + + static ManifoldType Retract(const ManifoldType& origin, + const TangentVector& v, + ChartJacobian Horigin, + ChartJacobian Hv); + + static TangentVector Logmap(const ManifoldType& m); + static ManifoldType Expmap(const TangentVector& v); + static TangentVector Logmap(const ManifoldType& m, ChartJacobian Hm); + static ManifoldType Expmap(const TangentVector& v, ChartJacobian Hv); + + // For Testable + static void Print(const ManifoldType& T); + static void Equals(const ManifoldType& m1, + const ManifoldType& m2, + double tol = 1e-8); }; -//@} -}// \ namespace manifold::traits /// Check invariants for Manifold type template -BOOST_CONCEPT_REQUIRES(((Testable)),(bool)) // -check_invariants(const T& a, const T& b) { - typedef typename traits::DefaultChart::type Chart; - // no invariants to check for manifolds, so always true if concept check compiles - return true; +BOOST_CONCEPT_REQUIRES(((Testable >)),(bool)) // +check_manifold_invariants(const T& a, const T& b, double tol=1e-9) { + traits::TangentVector v0 = traits::Local(a,a); + traits::TangentVector v = traits::Local(a,b); + T c = traits::Retract(a,v); + return v0.norm() < tol && traits::Equals(b,c,tol); } -} // \ namespace manifold +#define GTSAM_MANIFOLD_DECLARATIONS(MANIFOLD,DIM,TANGENT_VECTOR) \ + typedef MANIFOLD ManifoldType;\ + typedef manifold_tag structure_category; \ + struct dimension : public boost::integral_constant {};\ + typedef TANGENT_VECTOR TangentVector;\ + typedef OptionalJacobian ChartJacobian; \ + static TangentVector Local(const ManifoldType& origin, \ + const ManifoldType& other, \ + ChartJacobian Horigin=boost::none, \ + ChartJacobian Hother=boost::none); \ + static ManifoldType Retract(const ManifoldType& origin, \ + const TangentVector& v,\ + ChartJacobian Horigin=boost::none, \ + ChartJacobian Hv=boost::none); \ + static int GetDimension(const ManifoldType& m) { return dimension; } -#define GTSAM_MANIFOLD(TEMPLATE,MANIFOLD,DIM,TANGENT_VECTOR,DEFAULT_CHART) \ -namespace manifold { \ -namespace traits { \ -template