-
Notifications
You must be signed in to change notification settings - Fork 0
/
6_tf_util.py
41 lines (32 loc) · 1.25 KB
/
6_tf_util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import math
import numpy as np
def getXYZFromMatrix(matrix):
"""
Extract Euler angles (rotation around x, y, and z axis) from a 4x4 rotation matrix.
This is with XYZ order, and Y must be in range (-90deg, 90deg)
@param matrix: np.array - A 4x4 numpy array representing the rotation matrix.
@return: tuple - A tuple containing the Euler angles (rot_x, rot_y, rot_z) in degrees.
"""
# Ensure the matrix is a numpy array
matrix = np.array(matrix)
# Threshold for numerical stability
threshold = 1e-6
# Extract angles based on XYZ rotation order
if abs(matrix[2, 1]) < 1 - threshold:
rot_x = np.arctan2(matrix[2, 1], matrix[2, 2])
rot_y = np.arcsin(-matrix[2, 0])
rot_z = np.arctan2(matrix[1, 0], matrix[0, 0])
else:
# Gimbal lock occurs
rot_z = 0 # Arbitrarily set
if matrix[2, 1] < -1 + threshold:
rot_x = -np.pi / 2
rot_y = np.arctan2(matrix[0, 1], matrix[1, 1])
else:
rot_x = np.pi / 2
rot_y = np.arctan2(-matrix[0, 1], -matrix[1, 1])
# Convert the angles from radians to degrees
rot_x = math.degrees(rot_x)
rot_y = math.degrees(rot_y)
rot_z = math.degrees(rot_z)
return rot_x, rot_y, rot_z