How to use Scipy Rotation for transforming Orientations between Coordinate Systems with the help of euler angles?

Viewed 1160

So lets assume my body has the following extrinsic orientation in the Coordinate System A:

A = [20,30,40] # extrinsic xyz in degrees

And the following Orientation in the Coordinate System B:

B = [10, 25, 50]

So the transformation from A to B is:

T = [-10, -5, 10]

So that:

B = A + T

Now I want to do the same using scipy.Rotation:

from scipy.spatial.transform import Rotation

A = Rotation.from_euler('xyz' ,[20, 30, 40], degrees=True)
B = Rotation.from_euler('xyz', [10, 25, 50], degrees=True)
T = Rotation.from_euler('xyz', [-10, -5, 10], degrees=True)
result =  A  * T # This seems to be wrong?

print(result.as_euler('xyz', degrees=True)) # Output: [14.02609598 21.61478378 48.20912092]

Where is my mistake here? What am I doint wrong. I need to use scipy rotation because, I will apply that same rotation given in euler angles on quaternions too.

1 Answers

The transformation from A to B is incorrect. You need to be careful when considering rotations in 3D as rotations about different axes do not commute with each other.

According to your understanding, the T in the following code should get the object to [0, 0, 0]. But it doesn't.

A = Rotation.from_euler('xyz' ,[20, 30, 40], degrees=True)
T = Rotation.from_euler('xyz', [-20, -30, -40], degrees=True)
result =  A * T
print(result.as_euler('xyz', degrees=True)) 
# output: [-25.4441408    5.14593816  -4.1802616 ]

However, if you reverse the order of the rotations, you go to [0, 0, 0] as expected.

A = Rotation.from_euler('xyz' ,[20, 30, 40], degrees=True)
T = Rotation.from_euler('zyx', [-40, -30, -20], degrees=True)
result =  A * T
print(result.as_euler('xyz', degrees=True)) 

# output: [ 4.77083202e-15  0.00000000e+00 -1.98784668e-15] practically [0,0,0]

The correct transformation from A to B will be T = [-14.74053552, -1.237896, 10.10094351]. Refer to the following.

A = Rotation.from_euler('xyz' ,[20, 30, 40], degrees=True)
AToZero = Rotation.from_euler('zyx', [-40, -30, -20], degrees=True)
ZeroToB = Rotation.from_euler('xyz', [10, 25, 50], degrees=True)
T = AToZero*ZeroToB
print(T.as_euler('xyz', degrees=True))
# output: [-14.74053552  -1.237896    10.10094351]
result =  A * T
print(result.as_euler('xyz', degrees=True)) 
# ouput: [10. 25. 50.]
Related