自定义Python四元数转欧拉角函数结果不符问题排查
四元数转欧拉角结果不符的问题排查
我自己实现了一个四元数转欧拉角的函数,参考维基百科的公式和C++实现,代码如下:
import math def quaternion_to_euler(quaternion: tuple): w, x, y, z = quaternion roll = math.atan2(2*(w*x + y*z), 1 - 2*(x * x + y * y)) pitch = math.asin(2*(w*y - z*x)) yaw = math.atan2(2*(w*z + x*y), 1 - 2*(y * y + z * z)) return(roll, pitch, yaw)
测试输入四元数(0.73007, -0.03484, 0.68173, 0.03199)时,自定义函数输出:
roll: -0.10618318122804299, pitch: 1.5022308055111253, yaw: -0.011586976613645479
但用在线旋转转换工具得到的结果完全不同:
roll: -0.9466037, pitch: 1.454085, yaw: 0.9425664
我用scipy库验证了结果,代码如下:
from scipy.spatial.transform import Rotation as R rr = R.from_quat([-0.03484, 0.68173, 0.03199, 0.73007]) print(rr.as_euler('xyz'))
输出和自定义函数完全一致,这让我困惑问题出在哪。
问题根源分析
你的自定义函数和scipy的结果一致,说明代码实现本身是正确的,问题出在参数定义的不一致,常见的差异点包括:
- 四元数的分量顺序:你的函数使用
(w, x, y, z)(实部在前),但很多在线工具默认使用(x, y, z, w)(虚部在前)的输入顺序。你可以尝试把输入四元数调整为(-0.03484, 0.68173, 0.03199, 0.73007)输入在线工具,看结果是否匹配。 - 欧拉角的旋转顺序与轴定义:不同工具对roll、pitch、yaw对应的旋转轴和旋转顺序(比如
xyz、zyx、yxz等)定义不同。你的函数和scipy使用的是xyz顺序(roll绕X轴,pitch绕Y轴,yaw绕Z轴),而在线工具可能采用了其他旋转顺序(比如航空领域常见的zyx顺序:yaw-Z、pitch-Y、roll-X),或者对roll/pitch/yaw的轴定义完全不同。 - 角度单位:虽然你的结果和在线工具的数值看起来都是弧度,但也不排除部分在线工具默认输出角度,不过这个案例中数值范围不符合,可能性较低。
验证方法
- 查看在线工具的文档,确认它使用的四元数分量顺序和欧拉角的旋转顺序、轴定义。
- 按照在线工具的参数定义调整你的输入或转换逻辑,再对比结果。
内容的提问来源于stack exchange,提问作者fednem
相关产品推荐
相关产品推荐

