11

我想要归档的是一种位置的“磁性指纹”。我使用 MAGNETIC_FIELD 传感器,如果我得到(不幸的是没有进一步解释)X、Y 和 Z 轴的3 个值

问题是,当我旋转设备时值会发生变化,所以我猜 3 轴是相对于设备的。我需要的是补偿设备旋转,以便我得到相同的 3 个值,无论设备如何旋转。

我尝试与旋转矩阵相乘(我知道如何得到),尝试与倾斜矩阵相乘等等,但没有任何效果。无论我尝试什么,当我旋转设备时,值仍然会发生变化。

那么有谁知道如何正确地做到这一点?最好使用代码,因为我读了很多东西,比如“那么你将不得不使用旋转矩阵来补偿它”,但没有找到一个具体的工作示例。

4

4 回答 4

3

做这个

private static final int TEST_GRAV = Sensor.TYPE_ACCELEROMETER;
private static final int TEST_MAG = Sensor.TYPE_MAGNETIC_FIELD;
private final float alpha = (float) 0.8;
private float gravity[] = new float[3];
private float magnetic[] = new float[3];

public void onSensorChanged(SensorEvent event) {
    Sensor sensor = event.sensor;
    if (sensor.getType() == TEST_GRAV) {
            // Isolate the force of gravity with the low-pass filter.
              gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
              gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
              gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
    } else if (sensor.getType() == TEST_MAG) {

            magnetic[0] = event.values[0];
            magnetic[1] = event.values[1];
            magnetic[2] = event.values[2];

            float[] R = new float[9];
            float[] I = new float[9];
            SensorManager.getRotationMatrix(R, I, gravity, magnetic);
            float [] A_D = event.values.clone();
            float [] A_W = new float[3];
            A_W[0] = R[0] * A_D[0] + R[1] * A_D[1] + R[2] * A_D[2];
            A_W[1] = R[3] * A_D[0] + R[4] * A_D[1] + R[5] * A_D[2];
            A_W[2] = R[6] * A_D[0] + R[7] * A_D[1] + R[8] * A_D[2];

            Log.d("Field","\nX :"+A_W[0]+"\nY :"+A_W[1]+"\nZ :"+A_W[2]);

        }
    }
于 2015-08-13T21:50:04.527 回答
2

解决方案 :

可能性 1:

MAGNETIC_FIELD 关于旋转非常不稳定,您无法仅通过一些数学来转换横向和纵向值,主要原因是硬件对不同的轴使用不同的捕捉器,然后当旋转发生时,您使用不同的硬件捕捉器,值将永远不会相同,在某些高端设备上它是相同的,但在大多数设备上不同。

如果您想在许多设备上依赖和兼容某些东西,您需要忘记计算带有旋转的 MAGNETIC_FIELD,而只需使用您的应用程序强制定向。强制“纵向”定向模式

可能性 2:

你谈到"magnetic fingerprint" of a location.如果它只是关于在没有 GPS 的情况下识别一个位置,你还有很多其他信息可以使用。首先是“Wifi SSID”,然后是“Mobile Networks Cells”,还有“Connected Wifi”等。如果您对此感兴趣,我可以为您提供代码。

可能性 3:

如果您绝对需要为您的位置计算 MAGNETIC_FIELD,并且不想强制旋转……您可以同时捕获值横向和纵向,而不是计算它们。然后,当您比较时,只需比较两个值。

此外,如果您正在寻找有磁铁或高磁性位置的地方,您可以使用高容差百分比来检测是否存在磁铁,

笔记 :

如果您坚持使用数学,请不要忘记几乎每台设备上的功能都会有所不同……请随时提供有关您问题的更多信息,我会很高兴调整我的答案;)

于 2015-06-13T03:53:01.110 回答
0

要获得磁场强度,您必须获得磁场的 x、y、z 值(来自 Sensor.TYPE_MAGNETIC_FIELD),并应用以下公式:

double magnetic_field_strength = Math.sqrt( (Xvalue*Xvalue) + (Yvalue*Yvalue) + (Zvalue*Zvalue) );

磁场强度以微特斯拉 (µT) 表示。
本网站称,可以注意到地球的平均磁场强度为 50 µT 。


所以一个可能的代码是:

private SensorEventListener sensorEventListener = new SensorEventListener() {   
    @Override
    public void onSensorChanged(SensorEvent event) {

        switch (event.sensor.getType()) {
        case Sensor.TYPE_MAGNETIC_FIELD:                        
            magnetic_field_strength = Math.sqrt((event.values[0]*event.values[0])+(event.values[1]*event.values[1])+(event.values[2]*event.values[2]));
            break;                      
        default: 
            return;
        }                
    }
}
于 2013-11-07T14:23:16.797 回答
-1

给出了相对于手机的磁场矢量坐标,如下图所示:

在此处输入图像描述

得到下图坐标系中的磁场矢量:

在此处输入图像描述

您必须将磁矢量与从getRotationMatrix()中检索到m的旋转矩阵相乘。该矢量将穿过地球指向磁北极。RR * m

如果你也将它与 inclination 相乘I,向量将围绕 X 轴旋转以完全在 Y 轴上:

[0 m 0] = I * R * 地磁(m = 地磁场大小)

对于地球上的每个位置,该向量应该是恒定的。但是,您手机上的结果可能会略有偏差,因为您必须非常小心,不要在旋转设备时改变传感器的位置。

于 2012-08-02T08:28:43.907 回答