Как откалибровать акселерометр Android и уменьшить шум, устранить гравитацию - PullRequest
13 голосов
/ 02 февраля 2011

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

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

Я пытался использовать различные «фильтры», но, похоже, не могу обернуться вокруг них. Я понимаю, что гравитация должна решаться каким-то образом, и, возможно, именно в этом я и ошибаюсь. В настоящее время я пробовал это, адаптированный из SO ответа , который ссылается на пример из iPhone SDK:

                accel[0] = event.values[0] * kFilteringFactor + accel[0] * (1.0f - kFilteringFactor);
                accel[1] = event.values[1] * kFilteringFactor + accel[1] * (1.0f - kFilteringFactor);


                double x = event.values[0] - accel[0];
                double y = event.values[1] - accel[1];

Постер говорит «поиграть» со значением kFilteringFactor (в примере kFilteringFactor = 0,1f), пока не будет выполнено. К сожалению, я все еще, кажется, получаю много шума, и все, что кажется, делает то, что показания появляются в виде крошечных десятичных знаков, что не очень мне помогает, и, кажется, просто делает датчик менее чувствительным. Математические центры моего мозга также атрофированы годами пренебрежения, поэтому я не совсем понимаю, как работает этот фильтр.

Может кто-нибудь объяснить мне как-то подробно, как получить полезное показание с акселерометра? Краткое руководство было бы невероятной помощью, поскольку я не нашел действительно хорошего (по крайней мере, нацеленного на мой уровень знаний). Я расстроен, потому что чувствую, что все это должно быть более очевидным для меня. Буду признателен за любую помощь или направление, и, конечно, я могу предоставить больше примеров из моего кода, если это необходимо.

Надеюсь, я не прошу слишком много кормить ложкой; Я бы не спрашивал, если бы не пытался понять это какое-то время. Также похоже, что есть некоторый интерес со стороны других членов SO.

Ответы [ 3 ]

5 голосов
/ 03 февраля 2011

Частичный ответ:

Точность. Если вы ищете высокую точность, недорогие акселерометры, которые вы найдете в мобильных телефонах, не подорвут горчицу. Для сравнения, трехосный датчик, подходящий для промышленного или научного использования, стоит на север от 1500 долл. США только за датчик; добавление аппаратного обеспечения для его питания и превращение показаний в то, что может использовать компьютер, удваивает цену. Датчик в телефонной трубке работает значительно дешевле 5 долларов.

Шум. Дешевые датчики неточны, а неточность приводит к шуму. Неточный датчик, который не движется, не всегда будет показывать нули, он будет показывать значения по обе стороны в некотором диапазоне. Самое лучшее, что вы можете сделать, - это охарактеризовать датчик, не двигаясь, чтобы понять, насколько он шумный, и использовать его для округления измерений до менее точного масштаба на основе ожидаемой ошибки. (Другими словами, если он находится в пределах ± x м / с ^ 2 от нуля, можно с уверенностью сказать, что датчик не движется, но вы не можете быть точно уверены, потому что он может двигаться очень медленно.) Вам придется делать это на каждом устройстве, потому что они не все используют один и тот же акселерометр и ведут себя по-разному. Я полагаю, что это одно из преимуществ iPhone: аппаратное обеспечение в значительной степени однородно.

Гравитация. В документации SensorEvent обсуждается вопрос о том, как вывести гравитацию из того, что говорит акселерометр. Вы заметите, что он имеет большое сходство с кодом, который вы разместили, за исключением того, что он более понятен в том, что он делает. : -)

НТН.

4 голосов
/ 03 февраля 2011

Чтобы получить правильные показания акселерометра, вам нужно использовать уравнение скорости = SQRT (x * x + y * y + z * z).Используя это, когда телефон находится в состоянии покоя, скорость будет гравитационной - 9,8 м / с.Поэтому, если вы вычтете это (SensorManager.GRAVITY_EARTH), тогда, когда телефон находится в состоянии покоя, вы получите показание 0 м / с.Что касается шума, Blrfl может быть прав насчет дешевых акселерометров, даже когда мой телефон находится в состоянии покоя, он непрерывно мигает несколько долей метра в секунду.Вы можете просто установить небольшой порог, например 0,4 м / с, и если скорость не превышает этого, то он находится в покое.

1 голос
/ 06 декабря 2015

Как вы справляетесь с нервозностью? Вы сглаживаете данные. Вместо того чтобы рассматривать последовательность значений датчика как ваши значения, вы усредняете их на постоянной основе, и новая сформированная последовательность становится значениями, которые вы используете. Это перемещает каждое дрожащее значение ближе к скользящей средней. Усреднение обязательно избавляет от быстрых изменений в смежных значениях ... и именно поэтому люди используют терминологию Низкая (частота) Проходная фильтрация, поскольку данные, которые первоначально могли сильно различаться для выборки (или единицы времени), теперь изменяются медленнее.

Например, вместо использования значений 10 6 7 11 7 10 вы можете усреднить их многими способами. Например, мы можем вычислить следующее значение из равного веса скользящего среднего (т. Е. Вашей последней обработанной точки данных) со следующей точкой необработанных данных. Используя 50-50 для вышеприведенных чисел, мы получили бы 10, 8, 7,5, 9,25, 8,125, 9,0675. Эта новая последовательность, наши обработанные данные, будет использоваться вместо зашумленных данных. И мы могли бы использовать смесь, отличную от 50-50, конечно.

В качестве аналогии представьте, что вы сообщаете, где находится определенный человек, используя только ваше зрение. У вас есть хороший вид на более широкий пейзаж, но человек поглощен туманом. Вы увидите части тела, которые привлекают ваше внимание: движущаяся левая рука, правая нога, блестящие очки и т. Д., Которые дрожат, НО каждое значение довольно близко к истинному центру масс. Если мы запустим какое-то усреднение, мы получим значения, которые приближаются к центру масс этой цели, когда она движется сквозь туман, и в действительности более точные, чем значения, которые мы (датчик) сообщили, которые были зашумлены туман.

Теперь кажется, что мы теряем потенциально интересные данные, чтобы получить скучную кривую. Это имеет смысл, хотя. Если мы пытаемся воссоздать точную картину человека в тумане, первая задача - получить хорошее плавное приближение центра масс. К этому мы можем затем добавить данные от дополнительного датчика / процесса измерения. Например, другой человек может быть близко к этой цели. Этот человек может дать очень точное описание движений тела, но может быть в густом тумане и вообще не знать, где заканчивается цель. Это дополнительная позиция к тому, что мы впервые получили - вторые данные дают детали точно, без ощущения приблизительного местоположения. Две части данных будут сшиты вместе. Мы пропустили бы первый набор (как ваша проблема, представленная здесь), чтобы получить общее местоположение, лишенное шума. Мы хотели бы передать второй набор данных, чтобы получить детали без нежелательного вводящего в заблуждение вклада в общую позицию. Мы используем высококачественные глобальные данные и высококачественные локальные данные, каждый набор которых оптимизирован взаимодополняющим образом и защищен от повреждения другого набора (через 2 фильтрации).

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

Подводя итог, мы получаем низкочастотные данные от датчиков, которые дрожат, но остаются близко к «центру масс».Мы объединяем это базовое сглаженное значение с данными, которые точны в деталях, но смещаются, поэтому этот второй набор фильтруется верхними частотами.Мы получаем лучшее из обоих миров, когда обрабатываем каждую группу данных, чтобы очистить их от некорректных аспектов.Для акселерометра мы эффективно сглаживаем / пропускаем данные, выполняя некоторое изменение скользящего среднего по его измеренным значениям.Если бы мы обрабатывали данные гироскопа, мы делали бы математику, которая эффективно сохраняла бы детали (принимает дельты), отвергая при этом накопленную ошибку, которая в конечном итоге росла и повреждала гладкую кривую акселерометра.Как?По сути, мы используем фактические гироскопические значения (не средние), но используем небольшое количество выборок (дельт) куска при получении наших общих окончательных чистых значений.Использование небольшого количества дельт сохраняет общую среднюю кривую в основном вдоль тех же средних значений, которые отслеживаются ступенью нижних частот (усредненными данными акселерометра), которая составляет основную часть каждой конечной точки данных.

...