Хорошо, мы поняли это, работая с вращениями Эйлера и преобразовывая их в кватернионы:
Нам пришлось изменить все определение того, как triad_openvr вычисляет углы Эйлера
def convert_to_euler(pose_mat):
pitch = 180 / math.pi * math.atan2(pose_mat[2][1], pose_mat[2][2])
yaw = 180 / math.pi * math.asin(pose_mat[2][0])
roll = 180 / math.pi * math.atan2(-pose_mat[1][0], pose_mat[0][0])
x = pose_mat[0][3]
y = pose_mat[1][3]
z = pose_mat[2][3]
return [x,y,z,yaw,pitch,roll]
И затем пришлось дополнительно делать некоторые повороты эйлеровых координат, происходящих от контроллера здесь (крен соответствует X, рыскание соответствует Y, а шаг соответствует оси Z по неизвестной причине):
r0 = np.array([math.radians(-180-euler[5]), math.radians(euler[3]), -math.radians(euler[4]+180)])
Asа также предварительно поверните наши точки LiDAR, чтобы они соответствовали смещению осей нашей конструкции реального мира:
coord_x = (float(polar_point[0])/1000)*math.sin(math.radians(float(polar_point[1])))*(-1)
coord_y = (float(polar_point[0])/1000)*math.cos(math.radians(float(polar_point[1])))*(math.sqrt(3))*(0.5)-0.125
coord_z = (float(polar_point[0])/1000)*math.cos(math.radians(float(polar_point[1])))*(-0.5)
Это был, наконец, случай восстановления кватернионов из углов Эйлера (обходной путь, как мы знаем)и выполняйте вращение и перевод в указанном порядке.