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

时间:2015-05-16 18:06:26

标签: android rotation orientation quaternions gyroscope

我在x方向上旋转了我的Android设备(从-180度到180度),见下图。 enter image description here
并且我假设只有旋转矢量x值被改变。 Y和z可能有一些噪音,但值之间差别不大。

然而,我收到了这个。请注意

https://docs.google.com/spreadsheets/d/1ZLoSKI8XNjI1v4exaXxsuMtzP0qWTP5Uu4C3YTwnsKo/edit?usp=sharing

我怀疑我的传感器有问题。

有什么想法吗?非常感谢你。

1 个答案:

答案 0 :(得分:7)

编辑我需要修改这个问题。出现了一些错误

您的传感器很好。
嗯,旋转矢量条目不能简单地与特定轴周围的旋转角度相关。 SensorEvent结构由时间戳,传感器,准确度和值组成。取决于向量,values的float []在1-5的大小不同。
旋转向量值基于单位四元组,所有这些一起形成一个向量,表示此世界框架相对于您的方向智能手机固定架上面 enter image description here 它们是无单位的,逆时针正向。

  

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

如果矢量是旋转矩阵,可以将其写为
v_body = R_rot_vec * v_world (<--)将世界矢量推入智能手机固定描述中。
此外,关于矢量:

  

旋转矢量的三个元素等于单位四元数&lt; cos(θ/ 2),x sin(θ/ 2),y <的最后三个分量/ em> sin(θ/ 2),z * sin(θ/ 2)&gt;。

问:那该怎么办呢?根据您的欧拉角度约定(可能有24个序列,有效12个序列),您可以通过例如计算相应的角度u:= [ψ,θ,φ]。应用 123 序列:
enter image description here如果您已经拥有旋转矩阵条目,请按以下方式获取euler:
123 seq euler angles
321 序列:
321 seq euler angles
q1-3始终是values[0-2] (不要被u_ijk弄糊涂,因为ref(Diebel)使用不同的约定符合标准)

但是等等,你的链接表只有3个值,这与我得到的值相似。这是我的一个SensorEvent,后三个是从values[]打印出来的     23191581386897 11 -75 -0.0036907701 -0.014922042 0.9932963     时间戳敏感类型精度值[0]值[1]值[2] 4q-3values = 1q未知。第一个q0是redunant信息(同样doku表示它应该在values[3]下,取决于您的API级别)。所以我们可以使用范数(= length)来计算其他三个中的q0。
unit-norm
设置方程|| q || = 1并求解q0。现在所有q0-3都是已知的。
此外我的android 4.4.2在value[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);
                }
            }

将这些方程式放入代码中,您将对事物进行排序。

由于我之前必须处理转换quat-&gt; eul,我写了一个小的C ++ - 代码转换Quats。使用 XYZ或ZYX 。如果您碰巧坐在“linux”-shell前面,可以将它用作conversion helper一点,或者只是查看文件夹中的源代码。 (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;
}

这里有一些将quats应用于euls的例子: enter image description here



问: ijk的序列代表什么?
将两个坐标框架A和B相互叠加(所有轴彼此叠加)并开始通过具有角度psi的i轴旋转框架B,然后使j轴具有角度theta最后一个z轴有phi。对于i,j,k,它也可以是α,β,γ。 我没有收到数字,因为它们令人困惑(Diebel与其他论文)。

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

技巧是从左到右应用基本旋转,尽管我们从左到右读取序列。 这是你要经历的三个基本轮换

A to B: *v_B = R(psi,theta,phi) v_A*



问:那么如何让欧拉角/ quats从[0°,0°,0°]转到例如。 [0°,90°,0°]?
首先将图片中的两个帧对齐,将已知的设备帧B分别对准“不可见”的世界帧A.当角度全部达到[0°时,完成叠加0°,0°]。只需弄清楚你现在坐在哪里的北,南和东,然后将设备框架B指向那些方向。现在,当您绕y轴逆时针旋转90°时,转换四元数时将获得所需的[0°,90°,0°]。
儒略

*运动学来源:Source Diebel(Stanford)有关于力学背景的实体信息(注意:对于Diebel XYZ表示为u_321(1,2,3),而ZYX表示为u_123(3,2,1)),{{3}是一个很好的起点。