167 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
|  | /**
 | ||
|  |  * @file PoseRTV.h | ||
|  |  * @brief Pose3 with translational velocity | ||
|  |  * @author Alex Cunningham | ||
|  |  */ | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <gtsam/base/DerivedValue.h>
 | ||
|  | #include <gtsam/geometry/Pose3.h>
 | ||
|  | 
 | ||
|  | namespace gtsam { | ||
|  | 
 | ||
|  | /// Syntactic sugar to clarify components
 | ||
|  | typedef Point3 Velocity3; | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * Robot state for use with IMU measurements | ||
|  |  * - contains translation, translational velocity and rotation | ||
|  |  */ | ||
|  | class PoseRTV : public DerivedValue<PoseRTV> { | ||
|  | protected: | ||
|  | 
 | ||
|  | 	Pose3 Rt_; | ||
|  | 	Velocity3 v_; | ||
|  | 
 | ||
|  | public: | ||
|  | 	// constructors - with partial versions
 | ||
|  | 	PoseRTV() {} | ||
|  | 	PoseRTV(const Point3& pt, const Rot3& rot, const Velocity3& vel) | ||
|  | 	: Rt_(rot, pt), v_(vel) {} | ||
|  | 	PoseRTV(const Rot3& rot, const Point3& pt, const Velocity3& vel) | ||
|  | 	: Rt_(rot, pt), v_(vel) {} | ||
|  | 	explicit PoseRTV(const Point3& pt) | ||
|  | 	: Rt_(Rot3::identity(), pt) {} | ||
|  | 	PoseRTV(const Pose3& pose, const Velocity3& vel) | ||
|  | 	: Rt_(pose), v_(vel) {} | ||
|  | 	explicit PoseRTV(const Pose3& pose) | ||
|  | 	: Rt_(pose) {} | ||
|  | 
 | ||
|  | 	/** build from components - useful for data files */ | ||
|  | 	PoseRTV(double roll, double pitch, double yaw, double x, double y, double z, | ||
|  | 			double vx, double vy, double vz); | ||
|  | 
 | ||
|  | 	/** build from single vector - useful for Matlab - in RtV format */ | ||
|  | 	explicit PoseRTV(const Vector& v); | ||
|  | 
 | ||
|  | 	// access
 | ||
|  | 	const Point3& t() const { return Rt_.translation(); } | ||
|  | 	const Rot3& R() const { return Rt_.rotation(); } | ||
|  | 	const Velocity3& v() const { return v_; } | ||
|  | 	const Pose3& pose() const { return Rt_; } | ||
|  | 
 | ||
|  | 	// longer function names
 | ||
|  | 	const Point3& translation() const { return Rt_.translation(); } | ||
|  | 	const Rot3& rotation() const { return Rt_.rotation(); } | ||
|  | 	const Velocity3& velocity() const { return v_; } | ||
|  | 
 | ||
|  | 	// Access to vector for ease of use with Matlab
 | ||
|  | 	// and avoidance of Point3
 | ||
|  | 	Vector vector() const; | ||
|  | 	Vector translationVec() const { return Rt_.translation().vector(); } | ||
|  | 	Vector velocityVec() const { return v_.vector(); } | ||
|  | 
 | ||
|  | 	// testable
 | ||
|  | 	bool equals(const PoseRTV& other, double tol=1e-6) const; | ||
|  | 	void print(const std::string& s="") const; | ||
|  | 
 | ||
|  | 	// Manifold
 | ||
|  | 	static size_t Dim() { return 9; } | ||
|  | 	size_t dim() const { return Dim(); } | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * retract/unretract assume independence of components | ||
|  | 	 * Tangent space parameterization: | ||
|  | 	 * 	 - v(0-2): Rot3 (roll, pitch, yaw) | ||
|  | 	 * 	 - v(3-5): Point3 | ||
|  | 	 * 	 - v(6-8): Translational velocity | ||
|  | 	 */ | ||
|  | 	PoseRTV retract(const Vector& v) const; | ||
|  | 	Vector localCoordinates(const PoseRTV& p) const; | ||
|  | 
 | ||
|  | 	// Lie
 | ||
|  | 	/**
 | ||
|  | 	 * expmap/logmap are poor approximations that assume independence of components | ||
|  | 	 * Currently implemented using the poor retract/unretract approximations | ||
|  | 	 */ | ||
|  | 	static PoseRTV Expmap(const Vector& v); | ||
|  | 	static Vector Logmap(const PoseRTV& p); | ||
|  | 
 | ||
|  | 	PoseRTV inverse() const; | ||
|  | 
 | ||
|  | 	PoseRTV compose(const PoseRTV& p) const; | ||
|  | 
 | ||
|  | 	static PoseRTV identity() { return PoseRTV(); } | ||
|  | 
 | ||
|  | 	/** Derivatives calculated numerically */ | ||
|  | 	PoseRTV between(const PoseRTV& p, | ||
|  | 			boost::optional<Matrix&> H1=boost::none, | ||
|  | 			boost::optional<Matrix&> H2=boost::none) const; | ||
|  | 
 | ||
|  | 	// measurement functions
 | ||
|  | 	/** Derivatives calculated numerically */ | ||
|  | 	double range(const PoseRTV& other, | ||
|  | 			boost::optional<Matrix&> H1=boost::none, | ||
|  | 			boost::optional<Matrix&> H2=boost::none) const; | ||
|  | 
 | ||
|  | 	// IMU-specific
 | ||
|  | 
 | ||
|  | 	/// Dynamics integrator for ground robots
 | ||
|  | 	/// Always move from time 1 to time 2
 | ||
|  | 	PoseRTV planarDynamics(double vel_rate, double heading_rate, double max_accel, double dt) const; | ||
|  | 
 | ||
|  | 	/// Simulates flying robot with simple flight model
 | ||
|  | 	/// Integrates state x1 -> x2 given controls
 | ||
|  | 	/// x1 = {p1, r1, v1}, x2 = {p2, r2, v2}, all in global coordinates
 | ||
|  | 	/// @return x2
 | ||
|  | 	PoseRTV flyingDynamics(double pitch_rate, double heading_rate, double lift_control, double dt) const; | ||
|  | 
 | ||
|  | 	/// General Dynamics update - supply control inputs in body frame
 | ||
|  | 	PoseRTV generalDynamics(const Vector& accel, const Vector& gyro, double dt) const; | ||
|  | 
 | ||
|  | 	/// Dynamics predictor for both ground and flying robots, given states at 1 and 2
 | ||
|  | 	/// Always move from time 1 to time 2
 | ||
|  | 	/// @return imu measurement, as [accel, gyro]
 | ||
|  | 	Vector imuPrediction(const PoseRTV& x2, double dt) const; | ||
|  | 
 | ||
|  | 	/// predict measurement and where Point3 for x2 should be, as a way
 | ||
|  | 	/// of enforcing a velocity constraint
 | ||
|  | 	/// This version splits out the rotation and velocity for x2
 | ||
|  | 	Point3 translationIntegration(const Rot3& r2, const Velocity3& v2, double dt) const; | ||
|  | 
 | ||
|  | 	/// predict measurement and where Point3 for x2 should be, as a way
 | ||
|  | 	/// of enforcing a velocity constraint
 | ||
|  | 	/// This version takes a full PoseRTV, but ignores the existing translation for x2
 | ||
|  | 	inline Point3 translationIntegration(const PoseRTV& x2, double dt) const { | ||
|  | 		return translationIntegration(x2.rotation(), x2.velocity(), dt); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/// @return a vector for Matlab compatibility
 | ||
|  | 	inline Vector translationIntegrationVec(const PoseRTV& x2, double dt) const { | ||
|  | 		return translationIntegration(x2, dt).vector(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/**
 | ||
|  | 	 * Apply transform to this pose, with optional derivatives | ||
|  | 	 * equivalent to: | ||
|  | 	 * local = trans.transform_from(global, Dtrans, Dglobal) | ||
|  | 	 * | ||
|  | 	 * Note: the transform jacobian convention is flipped | ||
|  | 	 */ | ||
|  | 	PoseRTV transformed_from(const Pose3& trans, | ||
|  | 			boost::optional<Matrix&> Dglobal=boost::none, | ||
|  | 			boost::optional<Matrix&> Dtrans=boost::none) const; | ||
|  | 
 | ||
|  | private: | ||
|  | 	/** Serialization function */ | ||
|  | 	friend class boost::serialization::access; | ||
|  | 	template<class Archive> | ||
|  | 	void serialize(Archive & ar, const unsigned int version) { | ||
|  | 		ar & BOOST_SERIALIZATION_NVP(Rt_); | ||
|  | 		ar & BOOST_SERIALIZATION_NVP(v_); | ||
|  | 	} | ||
|  | }; | ||
|  | 
 | ||
|  | } // \namespace gtsam
 |