如何从旋转向量(Sensor.TYPE_ROTATION_VECTOR)获取欧拉角

8

我也注意到文档与设备实际移动的情况不一致。显然,所有设备的旋转都是错误的。 - user458577
你如何获取这些值?通过使用getOrientation函数吗? - Hoan Nguyen
我刚刚看到了这个视频:https://www.youtube.com/watch?v=C7JQ7Rpwn2k#t=2307,它非常好地解释了这些概念。特别是,你可能不想使用欧拉角,而是使用旋转矩阵。 - mbonnin
1个回答

11
您的传感器工作正常。
然而,旋转向量条目不能简单地与围绕特定轴的旋转角度相关联。SensorEvent 结构由时间戳、传感器、准确性和值组成。根据矢量,values 的 float[] 大小会变化(1-5)。
旋转向量值基于单位四元数,共同形成表示此世界框架相对于您的智能手机固定框架方向的矢量enter image description here。它们是无量纲和顺时针正数。

手机的方向由将东北天坐标与手机坐标对齐所需的旋转表示。也就是说,将该旋转应用于世界框架 (X,Y,Z) 会将其与手机坐标 (x,y,z) 对齐。

如果该矢量是旋转矩阵,则可以将其写为
v_body = R_rot_vec * v_world (<--),将世界矢量推入智能手机固定描述中。
此外关于该矢量:
旋转向量的三个元素等于一个单位四元数的最后三个分量。保留HTML标签。

Q: 那么该怎么做呢?
根据你的欧拉角约定(可能有24个序列,有效的12个),你可以通过应用例如123序列来计算相应的角度u := [ψ,θ,φ]:
enter image description here
如果您已经有了旋转矩阵条目,则可以像这样获得欧拉角:
123 seq euler angles
使用321序列:
321 seq euler angles
q1-3始终是values[0-2] (不要被u_ijk所困扰,因为ref(Diebel)使用与标准不同的约定)

但是,请等一下,您的链接表只有3个值,这与我得到的结果类似。 这是我的一个SensorEvent,最后三个从values[]中打印出来。

timestamp      sensortype accuracy values[0]    values[1]   values[2]
23191581386897 11         -75      -0.0036907701 -0.014922042 0.9932963

4q-3个数值=1q未知数。第一个q0是冗余信息,doku中说它应该在values[3]下面,具体取决于您的API级别。因此,我们可以使用范数(=长度)从其他三个中计算出q0。
unit-norm
设置方程||q|| = 1并解决q0。现在所有的q0-q3都已知。
此外,我的安卓4.4.2版本中没有第四个预估航向精度(以弧度计)在values[4]中,所以我评估了event.accuracy

for (SensorEvent e : currentEvent) {
    if (e != null) {
        String toMsg = "";
        for(int i = 0; i < e.values.length;i++) {
            toMsg += " " + String.valueOf(e.values[i]);
        }
        iBinder.msgString(String.valueOf(e.timestamp) + " "+String.valueOf(e.sensor.getType()) + " " + String.valueOf(e.accuracy) + toMsg, 0);
    }
}

将这些方程转化为代码,你就能把事情搞定了。
这是一个短小的转换工具,可以使用XYZ或ZYX来转换四元数。它可以从shellgithub运行。(BSD许可证)
与XYZ相关的部分
/*quaternation to euler in XYZ (seq:123)*/
double* quat2eulerxyz(double* q) {
  /*euler-angles*/
  double psi = atan2( -2.*(q[2]*q[3] - q[0]*q[1]) , q[0]*q[0] - q[1]*q[1]- q[2]*q[2] + q[3]*q[3] ); 
  double theta = asin( 2.*(q[1]*q[3] + q[0]*q[2]) );
  double phi = atan2( 2.*(-q[1]*q[2] + q[0]*q[3]) , q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3] );   
  /*save var. by simply pushing them back into the array and return*/
  q[1] = psi; 
  q[2] = theta;
  q[3] = phi;
  return q;
}

以下是一些将四元数应用于欧拉角的示例: 在此输入图片描述





R(psi,theta,phi) = R_z(phi)R_y(theta)R_x(psi) (<--)

这个技巧是从右到左应用基本旋转,尽管我们从左到右阅读序列。 这些是你要经历的三个基本旋转,才能从中得到答案。
A to B: *v_B = R(psi,theta,phi) v_A*







你能看一下这个答案吗?https://dev59.com/olsW5IYBdhLWcg3wbWtv - Skizo-ozᴉʞS ツ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接