简体   繁体   English

Android磁力计全局坐标

[英]Android magnetometer global coordinates

I have an app that reads the values returned by the magnetometer. 我有一个读取磁力计返回值的应用程序。
The way it does it at the moment is in the phone's coordinates system. 目前,它的执行方式是在手机的坐标系中。

I want to be able to always read the magnetic field vector in a global coordinates system (x,y,z - east, north, sky) 我希望能够始终读取全局坐标系中的磁场矢量(x,y,z-东,北,天空)

The code I tried (inspired from this question ) will result in a value of 0 for the x axis component, and variable y,z depending on the way I tilt the phone. 我尝试的代码(受此问题启发)将导致x轴分量的值为0,并且根据我倾斜手机的方式将变量y,z赋值。 As far I understood, the rotation matrix transform should make my coordinates system global, but it doesn't seem that way. 据我了解,旋转矩阵变换应该使我的坐标系成为全局坐标,但事实并非如此。

The expected behaviour would be to have the same value on the x,y,z components as long as I hold the phone in one place, no matter its tilt. 只要我将手机放在一个位置,无论倾斜度如何,预期的行为都是在x,y,z分量上具有相同的值。

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() == Sensor.TYPE_ACCELEROMETER) {
        // 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() == Sensor.TYPE_MAGNETIC_FIELD) {

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

        float[] R = new float[9];  //rotation matrix
        float[] I = new float[9];  //inclination
        SensorManager.getRotationMatrix(R, I, gravity, magnetic);
        float [] A_D = event.values.clone();  // device coordinates
        float [] A_W = new float[3];          // global coodinates
        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]);
    }

The code is correct but there is always fluctuation as gravity is only an estimate. 该代码是正确的,但总会出现波动,因为gravity只是一个估计值。 Actually, if the device is still, the accelerometer in the world coordinate should theoretically be the same independent of position since the only force acting on it is minus gravity and thus accelerometer should be gravity when the device is still. 实际上,如果设备accelerometer ,则世界坐标系中的accelerometer理论上应与位置无关,而相同,因为作用在其上的唯一力是minus gravity ,因此当设备静止时, accelerometer应为gravity You can only expect that the East and North coordinates are very small when the device is still. 您只能期望设备静止时EastNorth坐标非常小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM