使用Android实现精确的指南针

时间:2015-11-20 20:13:50

标签: android android-sensors panoramas azimuth

用两周的时间尝试不同的方法来计算手机的方位角,但我发现基本上有两个问题:

我的问题

  1. 360º转弯并不总是360º。如果我快速转弯,我会在转弯结束前完成360º,如果我慢慢走,我会在转弯结束后完成我的360º。
  2. 当我把它放在桌子上时,方位角会随机移动。或者甚至保持在相同的位置,对于任何 tick ,我得到+ - 3度,所以如果我保持200º并且我等待,我可能是197º。然后,如果我一直等待,它可能会达到194º,但我会留下来。
  3. 我在寻找什么?

    对于问题 1 .- ,我正在寻找X轴上的精确移动(方位角)。在HelloPanoramaGL project sample中可以找到一个很好的例子。它移动平稳,你可以感受到你正在移动一个真实的全景。

    对于问题 2 .- This project based in a Panorama for iOS同时执行1.-和2.-。当你转弯时,它会获得相同的位置。

    我尝试了什么

    好吧,两周之后,我敢说我已经完成了我在互联网上发现的所有事情,例如:

    • 尝试设置已弃用的Sensor.TYPE_ORIENTATION,但它是为我提供最佳结果的那个。
    • 尝试Sensor.TYPE_ACCELEROMETERSensor.TYPE_MAGNETIC_FIELD的组合。还adding a Low Pass Filter to the Sensors
    • 使用Sensor.TYPE_ROTATION_VECTOR等其他传感器等待任何希望使其正常工作。

    但是我的问题没有解决。

    这是我现在的代码:

    声明所有传感器:

        private SensorManager sensorManager;
        private Sensor magnetic_field;
        private Sensor accelerometer;
        private Sensor orientation;
    

    初始化onCreate():

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        orientation = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        magnetic_field = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    

    在onResume()上注册监听器:

        sensorManager.registerListener(this, magnetic_field, SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(this, orientation, SensorManager.SENSOR_DELAY_FASTEST);
        // tried with SENSOR_DELAY_FASTEST, SENSOR_DELAY_UI and SENSOR_DELAY_GAME
    

    并获得结果:

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            float azimuth1 = event.values[0];
            return;
        }
    
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            mGravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values;
        if (mGravity != null && mGeomagnetic != null) {
            float R_[] = new float[9];
            float I_[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R_, I_, mGravity, mGeomagnetic);
            if (success) {
                float orientation[] = new float[3];
                SensorManager.getOrientation(R_, orientation);
                azimut = orientation[0]; // orientation contains: azimut, pitch and roll
            }
        }
    }
    

    如果你可以帮助我,那就太好了。

    非常感谢。

    问候。

    圣拉斐尔。

0 个答案:

没有答案