3737
3838namespace libRSF
3939{
40+
41+ /* * @brief Converts a quaterion to Tait–Bryan angles
42+ * From:
43+ * Wikipedia contributors,
44+ * "Conversion between quaternions and Euler angles"
45+ * Wikipedia, The Free Encyclopedia,
46+ * https://en.wikipedia.org/w/index.php?title=Conversion_between_quaternions_and_Euler_angles&oldid=883423661
47+ * (accessed February 15, 2019).
48+ *
49+ * @param Quaternion ceres quaternion with ordering w,x,y,z
50+ * @param Yaw rotation around z
51+ * @param Pitch rotation around y
52+ * @param Roll rotation around x
53+ */
54+ template <typename T>
55+ inline void QuaternionToRPY (const T* Quaternion, T* Roll, T* Pitch, T* Yaw);
56+
4057 /* * @brief invert a quaternion
4158 *
4259 * @param Quaternion ceres quaternion with ordering w,x,y,z
@@ -48,6 +65,36 @@ namespace libRSF
4865 template <typename T>
4966 inline T RotationBetween (const T* Vector1, const T* Vector2, T* Quaternion);
5067
68+ template <typename T>
69+ inline void QuaternionToRPY (const T* Quaternion, T* Roll, T* Pitch, T* Yaw)
70+ {
71+
72+ const T& Qw = Quaternion[0 ];
73+ const T& Qx = Quaternion[1 ];
74+ const T& Qy = Quaternion[2 ];
75+ const T& Qz = Quaternion[3 ];
76+
77+ /* * conversion from Wikipedia */
78+ // roll (x-axis rotation)
79+ T sinr_cosp = +2.0 * (Qw * Qx + Qy * Qz);
80+ T cosr_cosp = +1.0 - 2.0 * (Qx * Qx + Qy * Qy);
81+ Roll[0 ] = ceres::atan2 (sinr_cosp, cosr_cosp);
82+
83+ // pitch (y-axis rotation)
84+ T sinp = +2.0 * (Qw * Qy - Qz * Qx);
85+ if (sinp >= T (1 ))
86+ Pitch[0 ] = T (M_PI / 2 ); // use 90 degrees if out of range
87+ else if (sinp <= T (-1 ))
88+ Pitch[0 ] = T (-M_PI / 2 );
89+ else
90+ Pitch[0 ] = ceres::asin (sinp);
91+
92+ // yaw (z-axis rotation)
93+ T siny_cosp = +2.0 * (Qw * Qz + Qx * Qy);
94+ T cosy_cosp = +1.0 - 2.0 * (Qy * Qy + Qz * Qz);
95+ Yaw[0 ] = ceres::atan2 (siny_cosp, cosy_cosp);
96+ }
97+
5198 template <typename T>
5299 inline void InvertQuaterion (const T* Quaternion, T* QuaternionInv)
53100 {
0 commit comments