scipy 如何在python中通过欧拉旋转来旋转一个旋转?

2j4z5cfb  于 2022-11-10  发布在  Python
关注(0)|答案(1)|浏览(272)

我想要什么

  • 输入:非规格化轴旋转
  • 输出:四元数旋转,但额外旋转-90度y轴(euler)

我拥有的一切


# !/usr/bin/env python3

# from math import radians, degrees, cos, sin, atan2, asin, pow, floor

# import numpy as np

from scipy.spatial.transform import Rotation

# r = Rotation.from_rotvec(rotation_by_axis).as_quat()

r = Rotation.from_quat([-0.0941422, 0.67905384, -0.2797612, 0.67212856]) # example
print("Input (as Euler): " + str(r.as_euler('xyz', degrees=True)))
print("Output (as Euler): " + str(r.apply([0, -90, 0])))

结果是:

Input (as Euler): [-83.23902624  59.33323676 -98.88314731]
Output (as Euler): [-22.33941658 -74.31676511  45.58474405]

如何获得输出[-83.23902624 -30.66676324 -98.88314731]

错误的解决方法

这只是有时起作用(为什么?)。

rotation = r.from_quat([rotation.x, rotation.y, rotation.z, rotation.w])
rotation = rotation.as_euler('xyz', degrees=True)
print(rotation)
rotation = r.from_euler('xyz', [rotation[0], rotation[1]-90, rotation[2]], degrees=True)
print(rotation.as_euler('xyz', degrees=True))
rotation = rotation.as_quat()

怎么做才更好呢?
因为有时我会得到错误的值:

[  -8.25897711  -16.54712028    -1.90525288]
[ 171.74102289  -73.45287972   178.09474712]

[  -7.18492129   22.22525264     0.44373851]
[  -7.18492129  -67.77474736     0.44373851]

[   7.52491766  -37.71896037   -40.86915413]
[-172.47508234  -52.28103963   139.13084587]

[  -1.79610826   37.83068221    31.20184248]
[  -1.79610826  -52.16931779    31.20184248]

[-113.5719734   -54.28744892   141.73007557]
[  66.4280266   -35.71255108   -38.26992443]

[ -83.23903078   59.33323752   -98.88315157]
[ -83.23903078  -30.66676248   -98.88315157]

[  -9.67960912   -7.23784945    13.56800885]
[ 170.32039088  -82.76215055  -166.43199115]

[  -6.21695895    5.66996884   -11.16152822]
[  -6.21695895  -84.33003116   -11.16152822]

[   0.            0.             0.        ]
[   0.          -90.             0.        ]

[   0.            0.             0.        ]
[   0.          -90.             0.        ]

这里错了:

[  -8.25897711  -16.54712028    -1.90525288]
[ 171.74102289  -73.45287972   178.09474712]

这里好了:

[  -7.18492129   22.22525264     0.44373851]
[  -7.18492129  -67.77474736     0.44373851]

我需要它的原因是:https://github.com/Arthur151/ROMP/issues/193#issuecomment-1156960708

kiayqfof

kiayqfof1#

apply用于将旋转应用于向量;它不适用于欧拉旋转角等非“数学”向量:将它们作为三元组进行相加或缩放是没有意义的。
要合并旋转,请使用*。因此,例如,要绕第一次旋转定义的y轴再旋转20度:

In [1]: import numpy as np

In [2]: np.set_printoptions(suppress=True) # don't show round-off

In [3]: from scipy.spatial.transform import Rotation

In [4]: def e(x,y,z): return Rotation.from_euler('xyz', [x,y,z], degrees=True)

In [5]: def s(r): return r.as_euler('xyz', degrees=True)

In [6]: display(s(e(0,20,0) * e(10,0,0)))
Out[6]: array([10., 20.,  0.])

然而,一般来说,这个旋转不会只加到y分量的总旋转中。这是因为附加旋转的轴是由第一个旋转定义的,但总旋转包括所有组合:

In [7]: s(e(0,20,0) * e(0,0,10))
Out[7]: array([ 3.61644157, 19.68349808, 10.62758414])

如上所示的组合旋转是非常标准的;例如,在多关节机器人中,要找到最终元素的方向,您可以使用上面所示的“组合”技术,每个关节旋转一次,由适当的轴定义(例如,z表示“髋关节”偏航旋转,x表示“腕关节”滚动旋转)
如果你 * 确实 * 需要操纵欧拉角,你的“糟糕的解决方案”是可以的。记住,欧拉表示中的中间旋转通常被限制在90度以下的绝对值:

In [8]: s(e(0,135,0))
Out[8]: array([180.,  45., 180.])

相关问题