Точность компаса и акселерометра - PullRequest
1 голос
/ 22 октября 2010

Я сделал свое собственное приложение в Android, которое использует датчики компаса и акселерометра для отображения градусов поворота и наклона моего устройства.Я инициализировал всех слушателей и объекты, которые мне были нужны (я следовал некоторым учебникам), и теперь я могу ловить степени по своему желанию.Проблема в том, что измерения, которые возвращают датчики, не точны.Я имею в виду, даже если я пытаюсь округлить значения градусов, которые я улавливаю датчиком, они колеблются между - / + 7 (или 8) градусами каждую долю секунды, даже если я остаюсь в поле травы вдали от любого источника помех.То, что я хочу получить, это точное измерение градусов, что-то вроде метода округления значений, которые я получаю от датчиков.

    float[] mags = null;
    float[] accels = null;
    float[] R = new float[matrix_size];
    float[] outR = new float[matrix_size];
    float[] I = new float[matrix_size];
    float[] values = null;

    private void startSensor() {
    sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorMan.registerListener(this, sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);

}

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
        return;
    }

    switch (event.sensor.getType()) {
    case Sensor.TYPE_MAGNETIC_FIELD:
        mags = event.values.clone();
        break;
    case Sensor.TYPE_ACCELEROMETER:
        accels = event.values.clone();
        break;
    }

    if (mags != null && accels != null) {
        SensorManager.getRotationMatrix(R, I, accels, mags);
        // Correct if screen is in Landscape
        SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X,
                SensorManager.AXIS_Z, outR);

        SensorManager.getOrientation(outR, values);
        azimuth = (float) Math.round((Math.toDegrees(values[0]))*7)/7;
        azimuth = ( azimuth + 360)%360; 
        //here is inclination. The problem is just the same with compass
        //inclination=-Math.round((float) (values[1]*(360/(2*Math.PI))));

        //other code to update my view
        //in azimuth i have the degree value. It changes continuously
        //even if i aim still the same direction
    }
}

Ответы [ 3 ]

1 голос
/ 24 августа 2011

См. Мой ответ здесь: Сглаживание данных с датчика

Я запускаю этот фильтр для значений событий акселерометра и магометра перед передачей их в SensorManager.getRotationMatrix().Я думаю, что этот алгоритм имеет то преимущество, что ему не нужно хранить большой массив исторических значений, а только предыдущий выходной массив нижних частот.

Алгоритм был получен из этой записи в Википедии: http://en.wikipedia.org/wiki/Low-pass_filter#Algorithmic_implementation

0 голосов
/ 22 октября 2012

Я сделал это, используя фильтр Калмана отсюда: Сайт Грега Черняка

Я отправляю данные на порт udp и сглаживаю их на ПК, используя python. Но я думаю, что вы можете найти реализацию фильтра Калмана для Java / Android там.

0 голосов
/ 29 июня 2011

То, что вы видите, является реальной вещью - датчики ориентации на большинстве телефонов достаточно хороши, чтобы дать вам приблизительный компас.

Если вы хотите сгладить отображаемое значение, чтобы оно давало вамчто-то, что не меняется случайным образом, я рекомендую реализовать http://en.wikipedia.org/wiki/Moving_average или другой фильтр сглаживания в Java для этого результата ориентации.

Для достижения максимальной производительности вы можете написать фильтр с помощью NDK и использоватьбиблиотека ускоренных аккумуляторов: http://www.boost.org/doc/libs/1_46_1/doc/html/accumulators.html

...