I am rotating n 3D shape using Euler angles in the order of XYZ meaning that the object is first rotated along the
X axis, then
Y and then
Z. I want to convert the Euler angle to Quaternion and then get the same Euler angles back from the Quaternion using some [preferably] Python code or just some pseudocode or algorithm. Below, I have some code that converts Euler angle to Quaternion and then converts the Quaternion to get Euler angles. However, this does not give me the same Euler angles.
I think the problem is I don't know how to associate yaw, pitch and roll to X, Y an Z axes. Also, I don't know how to change order of conversions in the code to correctly convert the Euler angles to Quaternion and then convert the Quaternion to Euler angle so that I am able to get the same Euler angle back. Can someone help me with this?
And here's the code I used:
This function converts Euler angles to Quaternions:
def euler_to_quaternion(yaw, pitch, roll): qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2) qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2) return [qx, qy, qz, qw]
And this converts Quaternions to Euler angles:
def quaternion_to_euler(x, y, z, w): import math t0 = +2.0 * (w * x + y * z) t1 = +1.0 - 2.0 * (x * x + y * y) X = math.degrees(math.atan2(t0, t1)) t2 = +2.0 * (w * y - z * x) t2 = +1.0 if t2 > +1.0 else t2 t2 = -1.0 if t2 < -1.0 else t2 Y = math.degrees(math.asin(t2)) t3 = +2.0 * (w * z + x * y) t4 = +1.0 - 2.0 * (y * y + z * z) Z = math.degrees(math.atan2(t3, t4)) return X, Y, Z
And I use them as follow:
import numpy as np euler_Original = np.random.random(3) * 360).tolist() # Generate random rotation angles for XYZ within the range [0, 360) quat = euler_to_quaternion(euler_Original, euler_Original, euler_Original) # Convert to Quaternion newEulerRot = quaternion_to_euler(quat, quat, quat, quat) #Convert the Quaternion to Euler angles print (euler_Original) print (newEulerRot)
The print statements print different numbers for
newEulerRot which I don't want to be the case. For example if
euler_original contains numbers like
(0.2, 1.12, 2.31) in radians I get this Quaternion -->
[0.749, 0.290, -0.449, 0.389] and converting the Quaternion to Euler angles gives me this -->
(132.35, 64.17, 11.45) which is pretty wrong. I wonder how I can fix this?
Although I'm interested in getting the above code to work by making changes to it but, I would rather learn how to set up the equations correctly. This way I would know how I can get the correct Quaternions even if the order of rotations (XYZ --> YZX etc) for applying Euler angles is changed.