您的传感器工作正常。
然而,旋转向量条目不能简单地与围绕特定轴的旋转角度相关联。
SensorEvent 结构由时间戳、传感器、准确性和值组成。根据矢量,
values
的 float[] 大小会变化(1-5)。
旋转向量值基于单位四元数,共同形成表示此世界框架相对于您的智能手机固定框架方向的矢量
。它们是无量纲和顺时针正数。
手机的方向由将东北天坐标与手机坐标对齐所需的旋转表示。也就是说,将该旋转应用于世界框架 (X,Y,Z) 会将其与手机坐标 (x,y,z) 对齐。
如果该矢量是旋转矩阵,则可以将其写为
v_body = R_rot_vec * v_world (<--)
,将世界矢量推入智能手机固定描述中。
此外关于该矢量:
旋转向量的三个元素等于一个单位四元数的最后三个分量。保留HTML标签。
Q: 那么该怎么做呢?
根据你的欧拉角约定(可能有24个序列,有效的12个),你可以通过应用例如123序列来计算相应的角度u := [ψ,θ,φ]:
如果您已经有了旋转矩阵条目,则可以像这样获得欧拉角:
使用321序列:
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。
设置方程||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来转换四元数。它可以从shell
github运行。(BSD许可证)
与XYZ相关的部分
double* quat2eulerxyz(double* q) {
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] );
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*