167 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
|  | /*
 | ||
|  |  * Rot2.h | ||
|  |  * | ||
|  |  *  Created on: Dec 9, 2009 | ||
|  |  *      Author: Frank Dellaert | ||
|  |  */ | ||
|  | 
 | ||
|  | #ifndef ROT2_H_
 | ||
|  | #define ROT2_H_
 | ||
|  | 
 | ||
|  | #include <boost/optional.hpp>
 | ||
|  | #include "Testable.h"
 | ||
|  | #include "Point2.h"
 | ||
|  | #include "Matrix.h"
 | ||
|  | #include "Lie.h"
 | ||
|  | 
 | ||
|  | namespace gtsam { | ||
|  | 
 | ||
|  |   /** Rotation matrix
 | ||
|  |    * NOTE: the angle theta is in radians unless explicitly stated | ||
|  |    */ | ||
|  |   class Rot2: Testable<Rot2>, public Lie<Rot2> { | ||
|  | 
 | ||
|  |   private: | ||
|  | 
 | ||
|  |     /** we store cos(theta) and sin(theta) */ | ||
|  |     double c_, s_; | ||
|  | 
 | ||
|  |     /** private constructor from cos/sin */ | ||
|  |     inline Rot2(double c, double s) : c_(c), s_(s) {} | ||
|  | 
 | ||
|  |     /** normalize to make sure cos and sin form unit vector */ | ||
|  |     Rot2& normalize(); | ||
|  | 
 | ||
|  |   public: | ||
|  | 
 | ||
|  |     /** default constructor, zero rotation */ | ||
|  |     Rot2() : c_(1.0), s_(0.0) {} | ||
|  | 
 | ||
|  |     /** "named constructors" */ | ||
|  | 
 | ||
|  |     /** Named constructor from angle == exponential map at identity  - theta is in radians*/ | ||
|  |     static Rot2 fromAngle(double theta); | ||
|  | 
 | ||
|  |     /** Named constructor from angle in degrees */ | ||
|  |     static Rot2 fromDegrees(double theta) { | ||
|  |     	const double degree = M_PI / 180; | ||
|  |     	return fromAngle(theta * degree); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** Named constructor from cos(theta),sin(theta) pair, will *not* normalize! */ | ||
|  |     static Rot2 fromCosSin(double c, double s); | ||
|  | 
 | ||
|  |     /** Named constructor that behaves as atan2, i.e., y,x order (!) and normalizes */ | ||
|  |   	static Rot2 atan2(double y, double x); | ||
|  | 
 | ||
|  |   	/** return angle */ | ||
|  |     double theta() const { return ::atan2(s_,c_); } | ||
|  | 
 | ||
|  |     /** return cos */ | ||
|  |     inline double c() const { return c_; } | ||
|  | 
 | ||
|  |     /** return sin */ | ||
|  |     inline double s() const { return s_; } | ||
|  | 
 | ||
|  |     /** print */ | ||
|  |     void print(const std::string& s = "theta") const; | ||
|  | 
 | ||
|  |     /** equals with an tolerance */ | ||
|  |     bool equals(const Rot2& R, double tol = 1e-9) const; | ||
|  | 
 | ||
|  |     /** return 2*2 rotation matrix */ | ||
|  |     Matrix matrix() const; | ||
|  | 
 | ||
|  |     /** return 2*2 transpose (inverse) rotation matrix   */ | ||
|  |     Matrix transpose() const; | ||
|  | 
 | ||
|  |     /** The inverse rotation - negative angle */ | ||
|  |     Rot2 inverse() const { return Rot2(c_, -s_);} | ||
|  | 
 | ||
|  |     /** Compose - make a new rotation by adding angles */ | ||
|  |     Rot2 operator*(const Rot2& R) const { | ||
|  | 			return fromCosSin(c_ * R.c_ - s_ * R.s_, s_ * R.c_ + c_ * R.s_); | ||
|  | 		} | ||
|  | 
 | ||
|  |     /** rotate from world to rotated = R*p */ | ||
|  |     Point2 rotate(const Point2& p) const; | ||
|  | 
 | ||
|  |     /** rotate from world to rotated = R'*p */ | ||
|  |     Point2 unrotate(const Point2& p) const; | ||
|  | 
 | ||
|  |     /** get the dimension by the type */ | ||
|  |     static inline size_t dim() { return 1; }; | ||
|  | 
 | ||
|  |   private: | ||
|  |     /** Serialization function */ | ||
|  |     friend class boost::serialization::access; | ||
|  |     template<class Archive> | ||
|  |     void serialize(Archive & ar, const unsigned int version) { | ||
|  |       ar & BOOST_SERIALIZATION_NVP(c_); | ||
|  |       ar & BOOST_SERIALIZATION_NVP(s_); | ||
|  |     } | ||
|  | 
 | ||
|  |   }; // Rot2
 | ||
|  | 
 | ||
|  | 	/* inline named constructor implementation */ | ||
|  | 	inline Rot2 Rot2::fromAngle(double theta) { | ||
|  | 		return Rot2(cos(theta), sin(theta)); | ||
|  | 	} | ||
|  | 
 | ||
|  |   // Lie group functions
 | ||
|  | 
 | ||
|  |   /** Global print calls member function */ | ||
|  |   inline void print(const Rot2& r, const std::string& s = "") { r.print(s); } | ||
|  | 
 | ||
|  |   /** Dimensionality of the tangent space */ | ||
|  |   inline size_t dim(const Rot2&) { return 1; } | ||
|  | 
 | ||
|  |   /** Expmap around identity - create a rotation from an angle */ | ||
|  |   template<> inline Rot2 expmap(const Vector& v) { | ||
|  |     if (zero(v)) return (Rot2()); | ||
|  |     else return Rot2::fromAngle(v(0)); | ||
|  |   } | ||
|  | 
 | ||
|  |   /** Logmap around identity - return the angle of the rotation */ | ||
|  |   inline Vector logmap(const Rot2& r) { | ||
|  |     return Vector_(1, r.theta()); | ||
|  |   } | ||
|  | 
 | ||
|  |   /** Compose - make a new rotation by adding angles */ | ||
|  |   inline Rot2 compose(const Rot2& R1, const Rot2& R2) { return R1*R2;} | ||
|  | 
 | ||
|  |   /** The inverse rotation - negative angle */ | ||
|  |   inline Rot2 inverse(const Rot2& R) { return R.inverse();} | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * rotate point from rotated coordinate frame to | ||
|  |    * world = R*p | ||
|  |    */ | ||
|  |   inline Point2 operator*(const Rot2& R, const Point2& p) {return R.rotate(p);} | ||
|  | 	Point2 rotate(const Rot2 & R, const Point2& p, boost::optional<Matrix&> H1 = | ||
|  | 			boost::none, boost::optional<Matrix&> H2 = boost::none); | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * rotate point from world to rotated | ||
|  |    * frame = R'*p | ||
|  |    */ | ||
|  | 	Point2 unrotate(const Rot2 & R, const Point2& p, boost::optional<Matrix&> H1 = | ||
|  | 			boost::none, boost::optional<Matrix&> H2 = boost::none); | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Calculate relative bearing to a landmark in local coordinate frame | ||
|  | 	 * @param point 2D location of landmark | ||
|  | 	 * @param H optional reference for Jacobian | ||
|  | 	 * @return 2D rotation \in SO(2) | ||
|  | 	 */ | ||
|  | 	Rot2 relativeBearing(const Point2& d); | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Calculate relative bearing and optional derivative | ||
|  | 	 */ | ||
|  | 	Rot2 relativeBearing(const Point2& d, boost::optional<Matrix&> H); | ||
|  | 
 | ||
|  | } // gtsam
 | ||
|  | 
 | ||
|  | #endif /* ROT2_H_ */
 |