Мне кажется, что мне здесь не хватает чего-то очень важного. Вопрос касается pytransform3d. Скорее всего, мне не хватает базового понимания 3D-преобразований и/или библиотеки pytransform3d.
Вот настройка:
< img alt="введите описание изображения здесь" src="https://i.sstatic.net/7AMv4Ame.png" />
Система координат O находится внутри куба , а системы координат A и B находятся по углам, как показано.
У меня есть две матрицы преобразования O2A и O2B ( назван в стиле, используемом в pytransform3d). Поскольку я не знаю, как визуализировать матрицы вращения, я конвертирую их во внутренние вращения Эйлера по XYZ. Используя сдвиги и внутренние вращения Эйлера по XYZ, я могу визуально подтвердить, что матрицы преобразования O2A и O2B верны.
Теперь я хочу вычислить матрица преобразования A2B. Используя numpy, я получаю A2B = inv(O2A) @ O2B, который я понимаю и доволен. Опять же, просто для проверки, я могу преобразовать во внутренние вращения Эйлера XYZ и проверить визуально на графике.
Теперь, согласно документам pytransform3d concat и invert_transform , это должно быть то же самое, что и A2B = pytr.concat(pytr.invert_transform(O2A), O2B), но это не так. Если я посмотрю на сдвиги и внутренние эйлеровы вращения XYZ этого результата, они не будут такими, как я ожидал. Глядя на эту страницу документации, кажется, что она должна быть такой же, но мне трудно понять, почему.
Вопрос: В каком смысле полученный A2B является преобразованием < em>от A до B? Возможно, мне нужно выполнить дополнительную постобработку результата перед извлечением переводов и внутренних вращений Эйлера XYZ?
Ниже у меня есть базовый фрагмент Python, чтобы показать значения:
import numpy as np
from math import degrees, radians
from numpy.linalg import inv
import pytransform3d.rotations as pyrot
import pytransform3d.transformations as pytr
def print_rp(X2Y):
r = list(map(degrees, pyrot.intrinsic_euler_xyz_from_active_matrix(inv(X2Y[0:3,0:3]))))
p = X2Y[0:3,3:4].ravel().tolist()
print(f"intrinsic Euler XYZ rotations {r}")
print(f"translations {p}")
print("# O2A")
O2A = pytr.transform_from(
R = np.block([[1,0,0],[0,1,0],[0,0,1]]),
p = [0.05,0.05,-0.05]
)
print_rp(O2A)
print("# O2B")
O2B = pytr.transform_from(
R = np.block([[-1,-0,-0],[0,-1,0],[0,0,1]]),
p = [0.05,-0.05,-0.05],
)
print_rp(O2B)
print("# A2B (should work but doesn't)")
A2B = pytr.concat(pytr.invert_transform(O2A), O2B)
print_rp(A2B)
print("# A2B (works but do not know why)")
A2B = pytr.concat(O2B, pytr.invert_transform(O2A))
print_rp(A2B)
print("# A2B (works as expected)")
A2B = inv(O2A) @ O2B
print_rp(A2B)
И вывод:
# O2A
intrinsic Euler XYZ rotations [0.0, 0.0, 0.0]
translations [0.05, 0.05, -0.05]
# O2B
intrinsic Euler XYZ rotations [0.0, 0.0, 180.0]
translations [0.05, -0.05, -0.05]
# A2B (should work but doesn't)
intrinsic Euler XYZ rotations [0.0, 0.0, 180.0]
translations [0.1, 0.0, 0.0]
# A2B (works but do not know why)
intrinsic Euler XYZ rotations [0.0, 0.0, 180.0]
translations [0.0, -0.1, 0.0]
# A2B (works as expected)
intrinsic Euler XYZ rotations [0.0, 0.0, 180.0]
translations [0.0, -0.1, 0.0]
Подробнее здесь: https://stackoverflow.com/questions/786 ... ransform3d