/** * @file BearingS2.h * * @brief Manifold measurement between two points on a unit sphere * * @date Jan 26, 2012 * @author Alex Cunningham */ #pragma once #include #include #include namespace gtsam { class GTSAM_UNSTABLE_EXPORT BearingS2 { protected: Rot2 azimuth_, elevation_; public: static const size_t dimension = 2; /// @name Constructors /// @{ /** Default constructor - straight ahead */ BearingS2() {} /** Build from components */ BearingS2(double azimuth, double elevation) : azimuth_(Rot2::fromAngle(azimuth)), elevation_(Rot2::fromAngle(elevation)) {} BearingS2(const Rot2& azimuth, const Rot2& elevation) : azimuth_(azimuth), elevation_(elevation) {} // access const Rot2& azimuth() const { return azimuth_; } const Rot2& elevation() const { return elevation_; } /// @} /// @name Measurements /// @{ /** * Observation function for downwards-facing camera */ // FIXME: will not work for TARGET = Point3 template static BearingS2 fromDownwardsObservation(const POSE& A, const TARGET& B) { return fromDownwardsObservation(A.pose(), B.translation()); } static BearingS2 fromDownwardsObservation(const Pose3& A, const Point3& B); /** Observation function with standard, forwards-facing camera */ static BearingS2 fromForwardObservation(const Pose3& A, const Point3& B); /// @} /// @name Testable /// @{ /** print with optional string */ void print(const std::string& s = "") const; /** assert equality up to a tolerance */ bool equals(const BearingS2& x, double tol = 1e-9) const; /// @} /// @name Manifold /// @{ /// Dimensionality of tangent space = 2 DOF - used to autodetect sizes inline static size_t Dim() { return dimension; } /// Dimensionality of tangent space = 2 DOF inline size_t dim() const { return dimension; } /// Retraction from R^2 to BearingS2 manifold neighborhood around current pose /// Tangent space parameterization is [azimuth elevation] BearingS2 retract(const Vector& v) const; /// Local coordinates of BearingS2 manifold neighborhood around current pose Vector localCoordinates(const BearingS2& p2) const; private: /// @} /// @name Advanced Interface /// @{ // Serialization function friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /*version*/) { ar & BOOST_SERIALIZATION_NVP(azimuth_); ar & BOOST_SERIALIZATION_NVP(elevation_); } }; /// traits template<> struct traits : public Testable {}; } // \namespace gtsam