Получение значений магнитного поля в глобальных координатах

Для приложения Android мне нужно получить измерения магнитного поля по оси глобальной (мировой) системы координат. Вот как я собираюсь (предполагаю) реализовать это. Пожалуйста, поправьте меня, если это необходимо. Также обратите внимание, что речь идет об алгоритмической части задачи, а не об Android API для сенсоров — у меня есть опыт работы с последними.

Первым шагом является получение данных датчика TYPE_MAGNETIC_FIELD (M) и данных датчика TYPE_ACCELEROMETER (G). Второй должен использоваться в соответствии с документацией Android, но я не уверен, что он не должен быть вместо этого TYPE_GRAVITY (опять же как G), потому что акселерометр, похоже, обеспечивает не чистую гравитацию.

Следующим шагом будет получение матриц поворота через getRotationMatrix(R, I, G, M), где R и I — матрицы поворота и наклона соответственно.

А теперь самая сомнительная часть: чтобы перевести M вектор в мировую систему координат, я полагаю умножить [R * I] * M.

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

Если существует какой-то исходный код, который уже делает это, я был бы признателен за размещение ссылки, но я не хочу использовать большие библиотеки общего назначения (например, для поддержки дополненной реальности) для этой конкретной задачи, потому что я бы хотел, чтобы это было как можно проще.

P.S.

Мне пришла в голову мысль добавить немного информации в исходный пост для ясности.

Предположим, что устройство лежит на столе и непрерывно считывает данные со своего магнитного датчика. Каждое измерение содержит 3 значения, представляющие магнитное поле по осям X, Y, Z, которые являются локальной системой координат устройства. Я так понимаю, что флуктуациями поля окружающей среды (сглаженными фильтром нижних частот) можно пренебречь, поэтому эти 3 значения должны оставаться почти одинаковыми все время, пока устройство остается на месте. Если мы вращаем устройство вокруг любой оси, значения меняются, потому что мы меняем локальную систему координат. Но само поле фактически не изменяется. Итак, я хочу преобразовать локальные измерения поля X, Y, Z в такие X', Y', Z', чтобы они сохраняли свои соответствующие значения независимо от вращения устройства, при условии, что устройство не перемещается со своего местоположения (только вращается).

Я реализовал алгоритм, описанный выше, и получил регулярные и заметные изменения значений X', Y', Z', полученных в результате предложенных преобразований, а значит, что-то здесь не так.

P.P.S.

Иногда я находил точную копию моего вопроса здесь, на SO - of-the-device-rotation">Как я могу получить вектор магнитного поля, не зависящий от вращения устройства? - но, к сожалению, ответ содержит мои предложения, и ОП этого вопроса подтверждает, что они не работают.


person Stan    schedule 13.11.2012    source источник
comment
Я не верю, что это возможно. Гравитация зафиксирует ориентацию устройства только по одной оси, поэтому вы знаете, что реальный мир находится внизу, но устройство все равно может указывать любое направление в пределах плоскости...   -  person Ifor    schedule 13.11.2012
comment
Вот почему Android использует комбинацию двух датчиков: гравитационного и магнитного, поэтому ориентация устройства полностью известна, а магнитное поле также известно в системе координат устройства. Если у вас есть вектор в одном базисе, вы точно сможете преобразовать его в другой.   -  person Stan    schedule 13.11.2012
comment
Только если магнитное поле всегда было ориентировано на истинный север, что не так... не говоря уже о локализованных возмущениях. Я думал, что вы после сопоставления реального измеренного магнитного поля с мировыми координатами, чтобы вы могли измерить местное изменение.   -  person Ifor    schedule 13.11.2012
comment
К сожалению, кажется, вы не выполняете мою задачу. Мне нужно измерить локальные свойства поля (в точках интереса), и они должны быть привязаны к глобальной системе координат. Изменение имеет смысл только в том случае, если применяется как дополнение к среднему значению.   -  person Stan    schedule 13.11.2012
comment
Ответ вы найдете здесь, на официальном сайте Android Developer: Официальный сайт SensorEvents для Android   -  person Master    schedule 17.03.2014


Ответы (2)


Координаты M по отношению к координате слова — это просто произведение R*M.

Матрица поворота R математически представляет собой замену базовой матрицы координаты устройства на координату слова. Пусть X, Y, Z будут основой координат устройства, а W_1, W_2 , W_3 — основа координат слова, тогда
M = m_1 X + m_2 Y + m_3
а также
M = c_1 W_1 + c_2 W_2 + c_3 W_3
где R * (m_1, m_2, m_3) = (c_1, c_2, c_3) транспонировать.

Фильтр нижних частот используется только для фильтрации ускорений в направлениях X, Y. RemapCoordinateSystem используется для изменения порядка базиса, т.е. изменения с W_1, W_2, W_3 на W_1, W_3, W_2.

person Hoan Nguyen    schedule 14.11.2012
comment
См. мой более подробный ответ в заголовке stackoverflow.com/questions/15315129/ - person Hoan Nguyen; 10.03.2013

Датчик магнитометра на вашем устройстве возвращает 3-вектор в координатах устройства. Вы можете использовать getRotationMatrix(), чтобы получить матрицу, которую можно использовать для преобразования этого вектора координат устройства в мировые координаты. Вы также можете узнать о кватернионах и напрямую использовать TYPE_ROTATION_VECTOR. Однако в Android нет библиотеки Quaternion (о которой я знаю), и это обсуждение выходит за рамки этого вопроса.

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

Теперь, что вы можете сделать, так это получить магнитное погружение. Это один из результатов getRotationMatrix(), хотя вам придется преобразовать матрицу в угол, чтобы она была полезной. Это тоже выходит за рамки данного вопроса.

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

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

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

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

person Edward Falk    schedule 13.11.2012
comment
Вы читали P.S. в вопросе? Я не могу придумать более понятного способа изложить свои требования, чем этот. Хорошо, у нас есть локальное магнитное поле в определенном месте. Если поле стабильно, и устройство знает, как изменилась его ориентация (без направленного движения), то почему я не могу получить пересчет измерений поля относительно текущей системы координат точки? Предположим, что это не глобальная система мира, а система координат пятна, которая, тем не менее, является внешней по отношению к устройству. Мне нужно исключить влияние вращения устройства на значения магнитного поля. - person Stan; 14.11.2012
comment
Аааа, теперь я понял (я думаю). Вы хотите держать устройство в одном месте и измерять, как меняется поле вокруг него? В этом случае я бы взял исходные показания магнитометра и гравиметра (или акселерометра) и передал их в getRotationMatrix(), чтобы получить матрицу вращения, которая преобразует локальные координаты в мировые координаты. Затем, начиная с этого момента, просто пропускайте выходные данные магнитометра через эту матрицу. - person Edward Falk; 14.11.2012