有了四元数和欧拉角,如何计算测量设备的绝对角度(python)?
Having Quaternions and Euler Angles, how can I calculate the absolute angles of the measuring device (with python)?
设置 是一个给我四元数和欧拉角的测量设备。测量装置安装在圆盘上,圆盘本身安装在臂上。手臂可以上下旋转,同时固定在一端,大约 240 度,因为它坐在吊架上。圆盘可以顺时针和逆时针旋转,双向无限旋转。
左边是侧视图,右边是俯视图。我想测量的可能旋转被绘制为箭头。
目标显示两个值,一个是手臂角度,一个是圆盘旋转角度,都在 -180 到 180 度之间。
测量仪数据的旋转顺序为ZYX(roll,pitch,yaw),四元数为WXYZ。 X 正向东,Y 向北,Z 向上。旋转测量装置本身的顺序不固定(手臂和磁盘运动可以混合)。
我了解到欧拉角是相对于物体的,因此在物体旋转时会发生变化。此外,我了解到轮换顺序很重要。我读到反转旋转顺序(到 XYZ)会给我外在旋转(= 用于根据世界的不变轴而不是对象的内在轴获得对象的相同最终方向的旋转),但我有不知道这是否/如何用于解决我的问题。
我没有找到任何 python 函数来实现我的目标,并且不了解走这条路所需的数学知识。我是否忽略了解决该问题的简单方法?如果没有,您会如何处理?
EDIT1:找到一个计算手臂角度的解决方案:
- 定义基矢量(0,0,1),即z轴在中立位置(即手臂与地球平行)
- 通过将设备的四元数定义的旋转应用于基本向量来获取当前 z 轴
- 使用arccos(numpy.clip(dot(rotatedVectorZ, baseVectorZ), -1.0, 1.0))计算原z轴与旋转z轴的夹角,等于臂角。
计算出的角度永远不会为负,因此每个值有两个可能的位置,但这对我的情况来说已经足够了。
对于计算旋转角度,我的想法是将x向量投影到x-y平面,方法是将z设置为0,然后对向量进行归一化,然后计算两者之间的角度(1,0,0) 轴和投影矢量,但这不起作用,因为手臂角度有一些偏移接近 90 度。
现在我正在考虑旋转设备的 x、y、z 坐标(我通过将四元数定义的旋转应用于每个向量 (1,0,0)、(0,1,0 ) 和 (0,0,1)) 以这样的方式在球体中使 z 轴对齐,这将使我能够计算原始 x 轴 (1,0,0) 和旋转轴之间的差异,但我我不确定这是否按预期工作。
编辑 2: 找到了一种 确定磁盘旋转角度的工作方法 在 0 到 180 度之间:
- 定义基向量(1,0,0),即x轴中立位置(即圆盘不旋转)
- 通过将设备的四元数定义的旋转应用于基本向量来获取当前 x 轴
- 通过计算垂直于原始 z 轴(即 0,0,1)和当前 z 轴(等于 0,0,1 和应用程序设备当前四元数的值)
- 归一化该轴向量并计算将当前 z 轴旋转到原始 z 轴 (0,0,1) 的四元数
- 使用该四元数旋转当前的 x 轴(参见步骤 2)。这模拟了手臂运动到与地球平行的位置。
- 计算新 x 轴与基本 x 轴 (1,0,0) 之间的角度
现在圆盘的旋转角度是180度space。
编辑 3: 找到了 最终解决方案 以获得 0 到 360 度之间的旋转角度。我们可以使用 arctan2(determinant, dot(current_x-vector, base_x-axis)) 而不是使用点积的 arccos,因为两个向量现在都在同一平面上(z beeing 0)。
Arm Angle:计算设备的基础z轴(0,0,1)与当前z轴的夹角(即设备的四元数对基本 z 轴 (0,0,1).
Disk Rotation Angle:通过计算两个归一化向量的叉积来计算垂直于设备的基本z轴和当前z轴的轴。然后用设备的四元数旋转基本x轴(0,0,1),然后沿着刚刚计算的垂直轴旋转一个度,其中a是我们刚开始计算的手臂角度。现在我们可以计算旋转两次的x轴与原始x轴之间的角度(0,0,1)。
有关详细信息,请参阅顶部我的原始问题 post。
设置 是一个给我四元数和欧拉角的测量设备。测量装置安装在圆盘上,圆盘本身安装在臂上。手臂可以上下旋转,同时固定在一端,大约 240 度,因为它坐在吊架上。圆盘可以顺时针和逆时针旋转,双向无限旋转。
左边是侧视图,右边是俯视图。我想测量的可能旋转被绘制为箭头。
目标显示两个值,一个是手臂角度,一个是圆盘旋转角度,都在 -180 到 180 度之间。
测量仪数据的旋转顺序为ZYX(roll,pitch,yaw),四元数为WXYZ。 X 正向东,Y 向北,Z 向上。旋转测量装置本身的顺序不固定(手臂和磁盘运动可以混合)。
我了解到欧拉角是相对于物体的,因此在物体旋转时会发生变化。此外,我了解到轮换顺序很重要。我读到反转旋转顺序(到 XYZ)会给我外在旋转(= 用于根据世界的不变轴而不是对象的内在轴获得对象的相同最终方向的旋转),但我有不知道这是否/如何用于解决我的问题。
我没有找到任何 python 函数来实现我的目标,并且不了解走这条路所需的数学知识。我是否忽略了解决该问题的简单方法?如果没有,您会如何处理?
EDIT1:找到一个计算手臂角度的解决方案:
- 定义基矢量(0,0,1),即z轴在中立位置(即手臂与地球平行)
- 通过将设备的四元数定义的旋转应用于基本向量来获取当前 z 轴
- 使用arccos(numpy.clip(dot(rotatedVectorZ, baseVectorZ), -1.0, 1.0))计算原z轴与旋转z轴的夹角,等于臂角。
计算出的角度永远不会为负,因此每个值有两个可能的位置,但这对我的情况来说已经足够了。
对于计算旋转角度,我的想法是将x向量投影到x-y平面,方法是将z设置为0,然后对向量进行归一化,然后计算两者之间的角度(1,0,0) 轴和投影矢量,但这不起作用,因为手臂角度有一些偏移接近 90 度。
现在我正在考虑旋转设备的 x、y、z 坐标(我通过将四元数定义的旋转应用于每个向量 (1,0,0)、(0,1,0 ) 和 (0,0,1)) 以这样的方式在球体中使 z 轴对齐,这将使我能够计算原始 x 轴 (1,0,0) 和旋转轴之间的差异,但我我不确定这是否按预期工作。
编辑 2: 找到了一种 确定磁盘旋转角度的工作方法 在 0 到 180 度之间:
- 定义基向量(1,0,0),即x轴中立位置(即圆盘不旋转)
- 通过将设备的四元数定义的旋转应用于基本向量来获取当前 x 轴
- 通过计算垂直于原始 z 轴(即 0,0,1)和当前 z 轴(等于 0,0,1 和应用程序设备当前四元数的值)
- 归一化该轴向量并计算将当前 z 轴旋转到原始 z 轴 (0,0,1) 的四元数
- 使用该四元数旋转当前的 x 轴(参见步骤 2)。这模拟了手臂运动到与地球平行的位置。
- 计算新 x 轴与基本 x 轴 (1,0,0) 之间的角度
现在圆盘的旋转角度是180度space。
编辑 3: 找到了 最终解决方案 以获得 0 到 360 度之间的旋转角度。我们可以使用 arctan2(determinant, dot(current_x-vector, base_x-axis)) 而不是使用点积的 arccos,因为两个向量现在都在同一平面上(z beeing 0)。
Arm Angle:计算设备的基础z轴(0,0,1)与当前z轴的夹角(即设备的四元数对基本 z 轴 (0,0,1).
Disk Rotation Angle:通过计算两个归一化向量的叉积来计算垂直于设备的基本z轴和当前z轴的轴。然后用设备的四元数旋转基本x轴(0,0,1),然后沿着刚刚计算的垂直轴旋转一个度,其中a是我们刚开始计算的手臂角度。现在我们可以计算旋转两次的x轴与原始x轴之间的角度(0,0,1)。
有关详细信息,请参阅顶部我的原始问题 post。