Сенсор Android TYPE_LINEAR_ACCELERATION - что он показывает?

Я разрабатываю приложение для отслеживания ускорения автомобиля. Я использовал стандартный акселерометр, предварительно проверив его в определенном положении.

Затем, при условии, что ориентация телефона не меняется, я зарегистрировал данные акселерометра за заданное время и рассчитанные параметры перемещения, одним из которых является скорость автомобиля в конце теста.

Он работает довольно хорошо, по прямой, горизонтальной дороге: ошибка в несколько процентов.

Но потом я узнал, что на уровне API 10 есть виртуальный датчик под названием TYPE_LINEAR_ACCELERATION и, насколько я понимаю, он должен делать то, что мне нужно: фильтровать гравитацию, изменения ориентации - поэтому я могу использовать ее и получить чистое линейное ускорение мобильного устройства.

НО в реальной жизни..

Я сделал простое приложение, которое делает небольшой тест:

//public class Accelerometer implements SensorEventListener { ...
public void onSensorChanged(SensorEvent se) 
{
    if(!active)
        return;

    lastX = se.values[SensorManager.DATA_X];
    lastY = se.values[SensorManager.DATA_Y];
    lastZ = se.values[SensorManager.DATA_Z];
    long now = System.currentTimeMillis();
    interval = now - lastEvetn;
    lastEvetn = now;
    out.write(Float.toString(lastX) + ";" + 
                    Float.toString(lastY) + ";" + 
                    Float.toString(lastZ) + ";" + 
                    Long.toString(interval) + "\n");
}

Я связываю слушателя со следующими параметрами:

  mSensorManager.registerListener(linAcc,
                mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
                SensorManager.SENSOR_DELAY_GAME);

Он работает нормально, но когда я анализировал дамп данных, вычисляя скорость, например, V = V0 + AT, где V0 = 0 сначала, затем - скорость интервала до этого, A = acceleration (SQRT (x*x+y*y+z*z)) (t = время интервала), в конце концов я получаю очень низкая скорость - в три раза меньше реальной скорости.

Изменение типа датчика на TYPE_ACCELEROMETER, калибровка и использование той же формулы для расчета скорости - я получаю хорошие результаты, намного ближе к реальности.

Итак, вопрос:

Что действительно показывает Sensor.TYPE_LINEAR_ACCELERATION?

Где я ошибаюсь или что-то не так с реализацией Sensor.TYPE_LINEAR_ACCELERATION?

Я использовал телефон Samsung Nexus S.

Ответ 1

Очень интересный вопрос !!!!

Я разрабатываю что-то похожее на ваше приложение. То, что я нашел о TYPE_LINEAR_ACCELERATION, не радует меня.

1) TYPE_LINEAR_ACCELERATION, TYPE_GRAVITY, ecc реализованы только для Android 2.3 (и выше) Итак, у меня есть Android 2.2, и я не могу их протестировать.

2) TYPE_LINEAR_ACCELERATION не так точен, как это было бы, потому что есть некоторая простая проблема при вычитании гравитации. На самом деле это "датчик синтеза", который использует акселерометр и ориентацию, чтобы знать, куда направлена сила тяжести, а затем подводная лодка. это.

Здесь я нашел очень полезный ответ, который объясняет это:

https://groups.google.com/forum/#!topic/android-developers/GOm9yhTFZaM

TYPE_ACCELEROMETER использует акселерометр и только акселерометр. Возвращает необработанные события акселерометра с минимальной обработкой или без обработки в все.

TYPE_GYROSCOPE (если присутствует) использует гироскоп и только гироскоп. Как и выше, он возвращает необработанные события (угловая скорость и рад/с) без обработка вообще (без компенсации смещения/масштаба).

TYPE_ORIENTATION устарело. Возвращает ориентацию как рыскание/ шаг/крен в градусах. Это не очень хорошо определено и может быть только полагаться, когда устройство не имеет "рулона". Этот датчик использует комбинация акселерометра и магнитометра. минимально лучшие результаты можно получить с помощью помощников SensorManager. Этот Датчик сильно "обработан".

TYPE_LINEAR_ACCELERATION, TYPE_GRAVITY, TYPE_ROTATION_VECTOR являются "слитые" датчики, которые возвращают соответственно линейное ускорение, вектор гравитации и вращения (кватернион). Не определено как они реализованы. На некоторых устройствах они реализованы в ч/б, на некоторых устройствах они используют акселерометр + магнитометр, на некоторые другие устройства они используют гироскоп.

На Nexus S и Xoom гироскоп в настоящее время НЕ используется. Они ведут себя как если бы не было доступного гироскопа, как на Nexus One или Droid. Мы планирует улучшить эту ситуацию в будущем выпуске.

В настоящее время единственный способ воспользоваться гироскопом - это использовать TYPE_GYROSCOPE и интегрировать вывод вручную.

Надеюсь, это поможет,

Mathias

Во всяком случае, в разных местах в Интернете я не нашел ни слова о датчике телефона и его возможностях из-за того, что они не точные...

Еще немного точности можно достичь, используя фильтр Калмана, но я понятия не имею, как...

Ответ 2

Я понимаю, что мой ответ довольно поздний. Я столкнулся с этой нитью, когда искал информацию о TYPE_LINEAR_ACCERERATION.

Неправильно делать a = sqrt (ax ^ 2 + ay ^ 2 + az ^ 2), а затем делать v = u + at. Это будет работать только тогда, когда v и a находятся в одном и том же направлении. И любое отклонение создало бы ошибки. Ускорение и скорость являются векторными величинами и должны рассматриваться как таковые. Вы должны сделать vx = ux + axt, vy = uy + ayt и vz = uz + azt. а затем v = sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2).

Ответ 3

TYPE_LINEAR_ACCELERATION не показывает "сырые" данные от датчика, он показывает данные, которые обрабатывались высокочастотным фильтром, поэтому постоянное ускорение, такое как гравитация или любое другое медленно меняющееся ускорение, не может проходить через фильтр.

У вашего автомобиля довольно постоянное ускорение, которое не может пройти фильтр. Если вы быстро измените свое ускорение, нажав на тормоза, затем нажав педаль акселерометра, затем вернитесь к тормозам, тогда TYPE_LINEAR_ACCELERATION покажет довольно правильный результат, иначе он всегда будет показывать меньше фактического значения ускорения.

Используйте TYPE_ACCELEROMETER, а затем удалите G (9.81) вручную. На самом деле, вам нужно измерить G самостоятельно, когда реальное ускорение равно 0, а затем использовать значение TYPE_ACCELEROMETER как G. В моем случае это 9.6.

TYPE_ACCELEROMETER хорош для быстрого изменения ускорения, которое длится менее 1 секунды, подобно тому, как вы двигаете рукой, подражая коробке или сражению с мечом.

Ответ 4

TYPE_LINEAR_ACCERERATION - трехмерный вектор, указывающий ускорение вдоль каждой оси устройства, не считая гравитации. TYPE_ACCELEROMETER = TYPE_GRAVITY + TYPE_LINEAR_ACCELERATION

Ответ 5

Вы должны умножить свой абсолютный вектор, полученный из TYPE_LINEAR_ACCELERATION, на инвертированную матрицу из TYPE_ROTATION_VECTOR.