Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

акселлерометр Unity, чувствительность и выход за лимит

Использую следующий код, чтобы получить показания акселлерометра и зафиксировать их максимум.
if (Input.acceleration.y > accelY) { accelY = Input.acceleration.y; } if (Input.acceleration.x > accelX) { accelX = Input.acceleration.x; } if (Input.acceleration.z > accelZ) { accelZ = Input.acceleration.z; }
accelYText.text = "Y = " + accelY.ToString(); accelZText.text = "Z = " + accelZ.ToString(); accelXText.text = "X = " + accelX.ToString();
Проблема в следующем - на разных телефонах есть некий лимит акселлерометра, допустим на моем это 1.90035 по оси х, 2.00055 по оси У и 1.8375 по оси Z. Больше этого значения оно не поднимается. На другом телефоне эти значения тоже около 2, хотя немного отличаются.
Вроде как бы и понятно все, лимит и лимит, но ребята из SmartTools со своим приложением Vibration Meter(не реклама, просто как образец для того, чтобы понять что я хочу) сумели каким то образом настроить чувствительность акселлерометра и мерить большие значения.
Для примера - максимум по их шкале около 13 баллов, но достичь их практически нереально - телефон надо просто бить об стену, чтобы вышло значение больше 11.
А когда меряешь в юнити, то лимит достигается довольно быстро - стукнул телефоном пару раз об подушку и вот они, цифры, выше которых значение не выдает акселлерометр.
Я понимаю что Vibration Meter написан не на Unity, он весит около 7 мб.
Но всё таки интересно - высокая чувствительность акселлерометра и его быстрое достижение максимума - это недоработка юнити, а в оригинальном андроиде всё ок, или есть какой то хитрый способ и в юне понизить чувствительность акселлерометра?
Всё проверялось и писалось под андроид. Возможно как то хелпер-классами android unity получится.


Ответ

Вы путаете величины.
Акселерометр измеряет ускорение.
А Vibration Meter колебания, там используют датчики, но информацию с них обрабатывают, получают интенсивность колебаний и приводят к какой-то из бальных шкал магнитуды землетрясений.

Сделал приложение через AndroidStudio напрямую беру показания с акселерометра. Получаю ускорение в м/с^2. Причем:
sensor.getMaximumRange())
Возвращает на моем телефоне 32. Это значит, что мой датчик не способен зафиксировать более чем 32м/с^2. Но опытным путем доказано, что максимум ~19.5 м/с^2, больше не фиксирует.
Еще одно замечание, в покое никогда не будет 0. Потому что действует ускорение свободного падения. Следовательно на одном из датчиков будет постоянная g, ее значение определенно как константа:
SensorManager.STANDARD_GRAVITY;
Следовательно ее в расчетах необходимо учитывать.

Аппаратные ограничения
Человек может придать своей руке ускорение 5g (50м/с^2) и более. А в телефонах предел измерения акселерометров меньше. Выходит проблема с быстрым достижением максимума не в Unity или Android, а в аппаратной части, достигнут лимит. Попробуйте измерять насколько меняется ускорение
vibration = Math.Abs(previousAccel-Accel)

Получение рывка
Рывок - векторная физическая величина, характеризующая темп (скорость) изменения ускорения тела. Является третьей производной по времени от радиус-вектора.
В примере рассмотрим получение xy части рывка.
Пример на java, выполнять нужно с фиксированным шагом (fixedUpdate() если юнити):
xyAccelPrev = xyAccel;//запоминаем ускорение по XY xyAccel = event.values[0]; //получаем ускорение по XY xyJerk = Math.abs(xyAccel-xyAccelPrev)/4; //получаем рывок по XY где 4 переводной коэфф if(xyJerk > xyJerkMax) xyJerkMax = xyJerk; //фиксируем максимальный рывок по XY xyAverageJerk = (xyAverageJerk+xyJerk)/2; //считаем среднее значение по XY
Вместо 4 можно поставить любое число, изменится диапазон значений.
для других осей аналогичный код. Вычислив по всем трем осям можно свести к вектору и получать его длину. Будет еще сложнее достичь максимального значения.
Чтобы поддерживать максимальное значение (9,75 на моем телефоне) нужно очень быстро перемещать из стороны в сторону, что достаточно сложно, получилось примерно как в Vibration Meter

Получение длины вектора ускорений
Вот как можно расширить диапазон измерения в 1.73, в т.ч. выше предела датчика. Для ускорений, псевдокод:
xyAccel//ускорение по xy xzAccel//ускорение по xz zyAccel//ускорение по zy Accel=sqrt(xyAccel^2+xzAccel^2+zyAccel^2)
Максимум получится достичь, если придать макс ускорение одновременно по всем осям. Аналогично вычисляется и для вектора рывка.

Комментариев нет:

Отправить комментарий