Intereting Posts
SetRequestProperty throwing java.lang.IllegalStateException: невозможно установить свойство запроса после подключения Применение FM-радио в разработке android Кинжал 2: инжектирование введенного пользователем параметра в объект Как преобразовать успешный орган Response к определенному типу с помощью модификации? Google Play – разница между низкой степенью зрелости и средней зрелостью Android-карты: как определить центр карты после завершения перетаскивания Альтернатива Android EditText Проблема с электронной почтой (отправка гиперссылки по электронной почте) Ошибка установки: INSTALL_FAILED_OLDER_SDK WebView в ScrollView: «Просмотр слишком большой, чтобы вписаться в кеш-файл» – как переделать макет? Я хочу, чтобы мой RecyclerView не перерабатывал некоторые элементы Как я могу использовать несколько компонентов GLSurfaceView в одном макете? Привязать к сервису из нового контекста для изменения конфигурации или привязки из контекста приложения? GetActionBar () возвращает null в PreferenceActivity (AppCompat-v7 21) Как загрузить изображение для Android ImageView из classpath?

Ускорение системы координат устройства в абсолютную систему координат

С моего устройства Android я могу прочитать массив значений линейного ускорения (в системе координат устройства) и массив абсолютных значений ориентации (в системе координат Земли). Мне нужно получить линейные значения ускорения в последней координате. система.

Как я могу их преобразовать?

EDIT после ответа Али в комментарии:

Хорошо, поэтому, если я правильно понимаю, когда я измеряю линейное ускорение, положение телефона полностью не имеет значения, потому что показания приведены в системе координат Земли. правильно?

Но я просто сделал тест, где я поместил телефон в разные позиции и получил ускорение в разных осях. Есть 3 пары изображений – первые показывают, как я помещаю устройство (извините за мастерство мастера Paint), а во втором показывают показания из данных, предоставленных линейным acc. датчик:

  1. Устройство на левой стороне

Первая позицияПервые чтения

  1. Устройство, лежащее на спине

Вторая позицияВторое чтение

  1. Устройство

Введите описание изображения здесьВведите описание изображения здесь

И теперь – почему в третьем случае ускорение происходит вдоль оси Z (а не Y), так как положение устройства не имеет значения?

Solutions Collecting From Web of "Ускорение системы координат устройства в абсолютную систему координат"

Я, наконец, сумел это решить! Таким образом, чтобы получить вектор ускорения в системе координат Земли, вам необходимо:

  1. Получить ротационную матрицу ( float[16] чтобы ее можно было использовать позже классом android.opengl.Matrix ) из SensorManager.getRotationMatrix() (используя SENSOR.TYPE_MAGNETIC_FIELD датчиков SENSOR.TYPE_GRAVITY и SENSOR.TYPE_MAGNETIC_FIELD качестве параметров),
  2. Используйте android.opengl.Matrix.invertM() на матрице вращения, чтобы инвертировать ее (не транспонировать!),
  3. Используйте датчик Sensor.TYPE_LINEAR_ACCELERATION , чтобы получить вектор линейного ускорения (в Sensor.TYPE_LINEAR_ACCELERATION устройства sys.),
  4. Используйте android.opengl.Matrix.multiplyMV() чтобы умножить матрицу вращения на вектор линейного ускорения.

И вот оно! Надеюсь, я сэкономлю драгоценное время для других.

Спасибо за Эдварда Фалька и Али за подсказки!

Основываясь на ответе @ alex, вот фрагмент кода:

 private float[] gravityValues = null; private float[] magneticValues = null; @Override public void onSensorChanged(SensorEvent event) { if ((gravityValues != null) && (magneticValues != null) && (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)) { float[] deviceRelativeAcceleration = new float[4]; deviceRelativeAcceleration[0] = event.values[0]; deviceRelativeAcceleration[1] = event.values[1]; deviceRelativeAcceleration[2] = event.values[2]; deviceRelativeAcceleration[3] = 0; // Change the device relative acceleration values to earth relative values // X axis -> East // Y axis -> North Pole // Z axis -> Sky float[] R = new float[16], I = new float[16], earthAcc = new float[16]; SensorManager.getRotationMatrix(R, I, gravityValues, magneticValues); float[] inv = new float[16]; android.opengl.Matrix.invertM(inv, 0, R, 0); android.opengl.Matrix.multiplyMV(earthAcc, 0, inv, 0, deviceRelativeAcceleration, 0); Log.d("Acceleration", "Values: (" + earthAcc[0] + ", " + earthAcc[1] + ", " + earthAcc[2] + ")"); } else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) { gravityValues = event.values; } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticValues = event.values; } } 

Согласно документации вы получаете линейное ускорение в системе координат телефона.

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

(Возможно, у вас уже есть функция, выполняющая это умножение, но я не занимаюсь программированием на Android, и я не знаком с ее API.)

Хорошим учебником по матрице вращения является рукопись Matrix Matrix Matrix IMU: Theory . Удачи!

Хорошо, прежде всего, если вы пытаетесь сделать настоящую инерциальную навигацию на Android, у вас есть ваша работа, вырезанная для вас. Дешевый маленький сенсор, используемый в смартфонах, недостаточно точно. Хотя, была проведена некоторая интересная работа по межсайтовой навигации на небольших расстояниях, например внутри здания. Есть, вероятно, документы по этому вопросу, которые вы можете выкопать. Google «Конференция разработчиков Motion Interface Developers», и вы можете найти что-то полезное – это конференция, которую Invensense выпустила пару месяцев назад.

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

Что вы хотите сделать, это использовать версию Android, которая поддерживает виртуальные датчики TYPE_GRAVITY и TYPE_LINEAR_ACCELERATION. Вам понадобится устройство с гироскопами, чтобы получить достаточно точные и точные показания.

Внутри система объединяет гироскопы, акселерометры и магнитометры, чтобы придумать истинные значения для ориентации устройства. Это эффективно разделяет устройство акселерометра на его компоненты силы тяжести и ускорения.

Итак, вы хотите настроить прослушиватели датчиков для TYPE_GRAVITY, TYPE_LINEAR_ACCERERATION и TYPE_MAGNETOMETER. Используйте данные гравитации и магнитометра в качестве входных данных SensorManager. GetRotationMatrix (), чтобы получить матрицу вращения, которая преобразует мировые координаты в координаты устройства или наоборот. В этом случае вам понадобится часть «versa». То есть, преобразуйте вход линейного ускорения в мировые координаты, умножив их на транспонирование матрицы ориентации.