Java 旋转矢量传感器的方位角、横摇和俯仰值

Java 旋转矢量传感器的方位角、横摇和俯仰值,java,android,math,rotation,quaternions,Java,Android,Math,Rotation,Quaternions,我试图将使用旋转矢量传感器类型时返回的5个值转换为滚动、方位角和俯仰 我使用的代码如下所示 @Override public void onSensorChanged(SensorEvent event) { double[] g = convertFloatsToDoubles(event.values.clone()); double norm = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2] + g[3] * g[3]

我试图将使用旋转矢量传感器类型时返回的5个值转换为滚动、方位角和俯仰

我使用的代码如下所示

@Override
public void onSensorChanged(SensorEvent event) {
    double[] g = convertFloatsToDoubles(event.values.clone());

    double norm = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2] + g[3] * g[3]);

    g[0] /= norm;
    g[1] /= norm;
    g[2] /= norm;
    g[3] /= norm;

    double xAng = (2 * Math.acos(g[0])) * (180 / Math.PI);
    double yAng = (2 * Math.acos(g[1])) * (180 / Math.PI);
    double zAng = (2 * Math.acos(g[2])) * (180 / Math.PI);
}

private double[] convertFloatsToDoubles(float[] input)
{
    if (input == null)
        return null;
        
    double[] output = new double[input.length];
    
    for (int i = 0; i < input.length; i++)
        output[i] = input[i];
        
    return output;
}
@覆盖
传感器更改时的公共无效(传感器事件){
double[]g=convertFloatsToDoubles(event.values.clone());
双范数=数学sqrt(g[0]*g[0]+g[1]*g[1]+g[2]*g[2]+g[3]*g[3]);
g[0]/=范数;
g[1]/=范数;
g[2]/=范数;
g[3]/=范数;
double-xAng=(2*Math.acos(g[0])*(180/Math.PI);
双阳=(2*Math.acos(g[1])*(180/Math.PI);
双藏=(2*Math.acos(g[2])*(180/Math.PI);
}
专用双精度[]转换器floatstodoubles(float[]输入)
{
如果(输入==null)
返回null;
double[]输出=新的double[input.length];
for(int i=0;i
问题在于变量
xAng
yAng
返回的值似乎被限制在80-280之间

至于
zAng
(我认为是方位角),它像罗盘一样工作,但当它返回0时,它似乎偏离磁南约12度

我想我所用的数学有问题,但我不确定到底是什么


传感器类型旋转向量的值定义为:

值[0]:x*sin(θ/2)

值[1]:y*sin(θ/2)

值[2]:z*sin(θ/2)

值[3]:cos(θ/2)

值[4]:估计航向精度(弧度)(如果不可用,则为-1)


以防它帮助任何想要完成相同任务的人。数学处理得完全不正确

下面的
onSensorChanged
已更新,因此它以度为单位返回正确的值

@Override
public void onSensorChanged(SensorEvent event) {
    //Get Rotation Vector Sensor Values
    double[] g = convertFloatsToDoubles(event.values.clone());

    //Normalise
    double norm = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2] + g[3] * g[3]);
    g[0] /= norm;
    g[1] /= norm;
    g[2] /= norm;
    g[3] /= norm;

    //Set values to commonly known quaternion letter representatives
    double x = g[0];
    double y = g[1];
    double z = g[2];
    double w = g[3];

    //Calculate Pitch in degrees (-180 to 180)
    double sinP = 2.0 * (w * x + y * z);
    double cosP = 1.0 - 2.0 * (x * x + y * y);
    double pitch = Math.atan2(sinP, cosP) * (180 / Math.PI);

    //Calculate Tilt in degrees (-90 to 90)
    double tilt;
    double sinT = 2.0 * (w * y - z * x);
    if (Math.abs(sinT) >= 1)
        tilt = Math.copySign(Math.PI / 2, sinT) * (180 / Math.PI);
    else
        tilt = Math.asin(sinT) * (180 / Math.PI);

    //Calculate Azimuth in degrees (0 to 360; 0 = North, 90 = East, 180 = South, 270 = West)
    double sinA = 2.0 * (w * z + x * y);
    double cosA = 1.0 - 2.0 * (y * y + z * z);
    double azimuth = Math.atan2(sinA, cosA) * (180 / Math.PI);
}