Андроид удаляет гравитацию из показаний акселерометра

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

Я хочу фильтровать гравитацию от каждой оси, а не от общего ускорения.

Не могли бы вы помочь мне? Мой код должен выглядеть примерно так:

public void onSensorChanged(SensorEvent sensorEvent) {
    float vals[] = sensorEvent.values;
    float accelerationX = filterGravity(vals[0]);
    float accelerationY = filterGravity(vals[1]);
    float accelerationZ = filterGravity(vals[2]);
}

Какой код следует поместить в методе filterGravity()?

Ответы

Ответ 1

Для базового решения вам понадобится фильтр нижних частот, другие подходы, такие как фильтр Калмана, довольно сложны в отношении математики позади. Простой пример для Android - это один клик от вашей ссылки в http://developer.android.com/reference/android/hardware/SensorEvent.html#values.

Проще говоря, фильтр нижних частот создает средневзвешенное значение из всех ваших значений истории. Если у вас, например, коэффициент фильтрации 0,1, это означает, что к предыдущему среднему значению добавляется 10% вашего текущего значения: newMeanValue = 10% от currentValue + 90% от oldMeanValue. Это означает, что даже если есть резкий пик, он будет медленно вызывать среднее значение из-за 10%.

Ответ 2

Линейное ускорение - это то, что вам нужно. Проверьте Sensor.TYPE_LINEAR_ACCELERATION здесь.

Ответ 3

Если у вас нет телефона с TYPE_LINEAR_ACCELERATION, вы застряли в TYPE_ACCELERATION, который не может отделить гравитацию (наклон) от линейного ускорения.

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

У меня есть много рабочих примеров в проекте с открытым исходным кодом Ускоритель Explorer.

Ответ 4

Не слишком уверен, что вы пытаетесь усвоить, но если вы ищете величину (которая даст результат между 0 и 1), тогда все, что вы делаете, делит результат на 10

public void onSensorChanged(SensorEvent sensorEvent) {
float vals[] = sensorEvent.values;
float accelerationX = (vals[0]/10);
float accelerationY = (vals[1]/10);
float accelerationZ = (vals[2]/10);

}

В игровой среде, когда датчик находится на полном наклоне, ваш объект будет на максимальной скорости