diff --git a/gtsam/base/LieMatrix.h b/gtsam/base/LieMatrix.h index ca6cf1b3f..2a8d4bc41 100644 --- a/gtsam/base/LieMatrix.h +++ b/gtsam/base/LieMatrix.h @@ -174,6 +174,10 @@ private: } }; + +// Define GTSAM traits +namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -182,4 +186,6 @@ template<> struct dimension : public Dynamic { }; +} + } // \namespace gtsam diff --git a/gtsam/base/LieScalar.h b/gtsam/base/LieScalar.h index cb1196de0..2ed81b1df 100644 --- a/gtsam/base/LieScalar.h +++ b/gtsam/base/LieScalar.h @@ -112,6 +112,9 @@ namespace gtsam { double d_; }; + // Define GTSAM traits + namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -120,4 +123,6 @@ namespace gtsam { struct dimension : public Dynamic { }; + } + } // \namespace gtsam diff --git a/gtsam/base/Manifold.h b/gtsam/base/Manifold.h index b8ec03402..4bea1c919 100644 --- a/gtsam/base/Manifold.h +++ b/gtsam/base/Manifold.h @@ -13,14 +13,15 @@ * @file Manifold.h * @brief Base class and basic functions for Manifold types * @author Alex Cunningham + * @author Frank Dellaert */ #pragma once -#include #include #include #include +#include namespace gtsam { @@ -45,6 +46,21 @@ namespace gtsam { // Traits, same style as Boost.TypeTraits // All meta-functions below ever only declare a single type // or a type/value/value_type +namespace traits { + +// is group, by default this is false +template +struct is_group: public std::false_type { +}; + +// identity, no default provided, by default given by default constructor +template +struct identity { + static T value() { + return T(); + } +}; + // is manifold, by default this is false template struct is_manifold: public std::false_type { @@ -54,22 +70,13 @@ struct is_manifold: public std::false_type { template struct dimension; -// Chart is a map from T -> vector, retract is its inverse -template -struct DefaultChart { - BOOST_STATIC_ASSERT(is_manifold::value); - typedef Eigen::Matrix::value, 1> vector; - DefaultChart(const T& t) : - t_(t) { - } - vector apply(const T& other) { - return t_.localCoordinates(other); - } - T retract(const vector& d) { - return t_.retract(d); - } -private: - T const & t_; +/** + * zero::value is intended to be the origin of a canonical coordinate system + * with canonical(t) == DefaultChart(zero::value).apply(t) + * Below we provide the group identity as zero *in case* it is a group + */ +template struct zero: public identity { + BOOST_STATIC_ASSERT(is_group::value); }; // double @@ -82,24 +89,6 @@ template<> struct dimension : public std::integral_constant { }; -template<> -struct DefaultChart { - typedef Eigen::Matrix vector; - DefaultChart(double t) : - t_(t) { - } - vector apply(double other) { - vector d; - d << other - t_; - return d; - } - double retract(const vector& d) { - return t_ + d[0]; - } -private: - double t_; -}; - // Fixed size Eigen::Matrix type template @@ -130,10 +119,74 @@ struct dimension > : public std::integral_c BOOST_STATIC_ASSERT(M!=Eigen::Dynamic && N!=Eigen::Dynamic); }; +} // \ namespace traits + +// Chart is a map from T -> vector, retract is its inverse +template +struct DefaultChart { + BOOST_STATIC_ASSERT(traits::is_manifold::value); + typedef Eigen::Matrix::value, 1> vector; + DefaultChart(const T& t) : + t_(t) { + } + vector apply(const T& other) { + return t_.localCoordinates(other); + } + T retract(const vector& d) { + return t_.retract(d); + } +private: + T const & t_; +}; + +/** + * Canonical::value is a chart around zero::value + * An example is Canonical + */ +template class Canonical { + DefaultChart chart; +public: + typedef T type; + typedef typename DefaultChart::vector vector; + Canonical() : + chart(traits::zero::value()) { + } + // Convert t of type T into canonical coordinates + vector apply(const T& t) { + return chart.apply(t); + } + // Convert back from canonical coordinates to T + T retract(const vector& v) { + return chart.retract(v); + } +}; + +// double + +template<> +struct DefaultChart { + typedef Eigen::Matrix vector; + DefaultChart(double t) : + t_(t) { + } + vector apply(double other) { + vector d; + d << other - t_; + return d; + } + double retract(const vector& d) { + return t_ + d[0]; + } +private: + double t_; +}; + +// Fixed size Eigen::Matrix type + template struct DefaultChart > { typedef Eigen::Matrix T; - typedef Eigen::Matrix::value, 1> vector; + typedef Eigen::Matrix::value, 1> vector; DefaultChart(const T& t) : t_(t) { } @@ -202,7 +255,7 @@ private: } }; -} // namespace gtsam +} // \ namespace gtsam /** * Macros for using the ManifoldConcept diff --git a/gtsam/geometry/Cal3Bundler.h b/gtsam/geometry/Cal3Bundler.h index dded932e8..2de5a808d 100644 --- a/gtsam/geometry/Cal3Bundler.h +++ b/gtsam/geometry/Cal3Bundler.h @@ -169,6 +169,9 @@ private: }; +// Define GTSAM traits +namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -177,4 +180,13 @@ template<> struct dimension : public std::integral_constant { }; +template<> +struct zero { + static Cal3Bundler value() { + return Cal3Bundler(0, 0, 0); + } +}; + +} + } // namespace gtsam diff --git a/gtsam/geometry/Cal3DS2.h b/gtsam/geometry/Cal3DS2.h index eb3bb3623..d716d398e 100644 --- a/gtsam/geometry/Cal3DS2.h +++ b/gtsam/geometry/Cal3DS2.h @@ -168,6 +168,9 @@ private: }; +// Define GTSAM traits +namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -175,5 +178,8 @@ struct is_manifold : public std::true_type { template<> struct dimension : public std::integral_constant { }; + +} + } diff --git a/gtsam/geometry/Cal3_S2.h b/gtsam/geometry/Cal3_S2.h index 6f1e75bad..a87a30e36 100644 --- a/gtsam/geometry/Cal3_S2.h +++ b/gtsam/geometry/Cal3_S2.h @@ -240,6 +240,9 @@ private: }; +// Define GTSAM traits +namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -248,5 +251,11 @@ template<> struct dimension : public std::integral_constant { }; +template<> +struct zero { + static Cal3_S2 value() { return Cal3_S2();} +}; + +} } // \ namespace gtsam diff --git a/gtsam/geometry/PinholeCamera.h b/gtsam/geometry/PinholeCamera.h index 02f283224..4b93ca70c 100644 --- a/gtsam/geometry/PinholeCamera.h +++ b/gtsam/geometry/PinholeCamera.h @@ -303,7 +303,7 @@ public: return K_.uncalibrate(pn); } - typedef Eigen::Matrix::value> Matrix2K; + typedef Eigen::Matrix::value> Matrix2K; /** project a point from world coordinate to the image * @param pw is a point in world coordinates @@ -613,6 +613,9 @@ private: }; +// Define GTSAM traits +namespace traits { + template struct is_manifold > : public std::true_type { }; @@ -622,4 +625,14 @@ struct dimension > : public std::integral_constant< int, dimension::value + dimension::value> { }; +template +struct zero > { + static PinholeCamera value() { + return PinholeCamera(zero::value(), + zero::value()); + } +}; + } + +} // \ gtsam diff --git a/gtsam/geometry/Point2.h b/gtsam/geometry/Point2.h index ffd3c2f80..7d1fab133 100644 --- a/gtsam/geometry/Point2.h +++ b/gtsam/geometry/Point2.h @@ -250,6 +250,13 @@ private: /// multiply with scalar inline Point2 operator*(double s, const Point2& p) {return p*s;} +// Define GTSAM traits +namespace traits { + +template<> +struct is_group : public std::true_type { +}; + template<> struct is_manifold : public std::true_type { }; @@ -260,3 +267,5 @@ struct dimension : public std::integral_constant { } +} + diff --git a/gtsam/geometry/Point3.h b/gtsam/geometry/Point3.h index b333ac1e9..d69ceb861 100644 --- a/gtsam/geometry/Point3.h +++ b/gtsam/geometry/Point3.h @@ -242,6 +242,13 @@ namespace gtsam { /// Syntactic sugar for multiplying coordinates by a scalar s*p inline Point3 operator*(double s, const Point3& p) { return p*s;} + // Define GTSAM traits + namespace traits { + + template<> + struct is_group : public std::true_type { + }; + template<> struct is_manifold : public std::true_type { }; @@ -250,4 +257,5 @@ namespace gtsam { struct dimension : public std::integral_constant { }; + } } diff --git a/gtsam/geometry/Pose2.h b/gtsam/geometry/Pose2.h index 13fa6aba0..b6a2314ff 100644 --- a/gtsam/geometry/Pose2.h +++ b/gtsam/geometry/Pose2.h @@ -321,6 +321,9 @@ inline Matrix wedge(const Vector& xi) { typedef std::pair Point2Pair; GTSAM_EXPORT boost::optional align(const std::vector& pairs); +// Define GTSAM traits +namespace traits { + template<> struct is_manifold : public std::true_type { }; @@ -329,5 +332,7 @@ template<> struct dimension : public std::integral_constant { }; +} + } // namespace gtsam diff --git a/gtsam/geometry/Pose3.h b/gtsam/geometry/Pose3.h index c5013270f..5f99b25ac 100644 --- a/gtsam/geometry/Pose3.h +++ b/gtsam/geometry/Pose3.h @@ -354,6 +354,13 @@ inline Matrix wedge(const Vector& xi) { typedef std::pair Point3Pair; GTSAM_EXPORT boost::optional align(const std::vector& pairs); +// Define GTSAM traits +namespace traits { + +template<> +struct is_group : public std::true_type { +}; + template<> struct is_manifold : public std::true_type { }; @@ -362,4 +369,6 @@ template<> struct dimension : public std::integral_constant { }; +} + } // namespace gtsam diff --git a/gtsam/geometry/Rot3.h b/gtsam/geometry/Rot3.h index eb6078ef2..62ac9f3f9 100644 --- a/gtsam/geometry/Rot3.h +++ b/gtsam/geometry/Rot3.h @@ -491,6 +491,13 @@ namespace gtsam { */ GTSAM_EXPORT std::pair RQ(const Matrix3& A); + // Define GTSAM traits + namespace traits { + + template<> + struct is_group : public std::true_type { + }; + template<> struct is_manifold : public std::true_type { }; @@ -499,5 +506,5 @@ namespace gtsam { struct dimension : public std::integral_constant { }; - + } }