Почему неправильно указывает направление компаса, используя показания магнитометра?

arduino-uno imu magnetometer

Я пытался рассчитать курс по компасу с помощью магнитометра в датчике MPU9250. Но результат для меня не имеет смысла. Я совершенно новичок в этом и не очень понимаю, как работают магнитометры, и просто пытаюсь найти в Интернете ресурсы, чтобы заставить их работать. Я вычисляю atan2 показаний датчика по осям y и x, чтобы определить угол:

float mx = imu.mag_x_ut();
float my = imu.mag_y_ut();
float mz = imu.mag_z_ut();

float heading = atan2(my, mx) * 180 / PI;

Serial.print(mx);
Serial.print(",");
Serial.print(my);
Serial.print(",");
Serial.print(mz);
Serial.print(",");
Serial.println(heading);

Насколько я понимаю, когда ось x моего магнитометра направлена на север, значение heading должно быть 0, для востока 90, юга 180 и затем для запада 270. Но мои расчеты далеки от ожидаемых результатов. Я даже не получаю нулевых показаний ни в одном направлении. Скриншоты с указанием направления прилагаю:

Это когда ось X указывает на север. x указывает на север

Ось X повернута на восток. x указывает на восток

x на юг. x указывает на юг

x в сторону запада. x указывает на запад

Я также добавил необработанные показания магнитометра, представленные mx, my и mz. Что-то не так с моим сенсором или с моей стороны произошло какое-то недопонимание.

РЕДАКТИРОВАНИЕ: Показания после компенсации смещения жесткого железа.

после жесткого смещения железа

, 👍2

Обсуждение

Отображаемый заголовок соответствует измеренным значениям «mx» и «my». Однако эти значения кажутся неверными: модуль магнитного поля меняется при повороте устройства. Это не должно быть так. Либо вы делаете что-то не так при снятии показаний, либо рядом с вашим устройством (или на нем) есть что-то магнитное, которое влияет на локальное поле., @Edgar Bonet

@EdgarBonet, привет, не могли бы вы немного подробнее рассказать о своем утверждении «модуль магнитного поля меняется при повороте устройства», извините, если это новый вопрос. Я использовал эту библиотеку для mpu9250 https://github.com/bolderflight/invensense-imu и просто вызывал методы для получения данных., @Sayantan Das

1. Я имею в виду [норму вектора](https://en.w ikipedia.org/wiki/Norm_(mathematics)). Вы можете построить график: это не должно зависеть от ориентации датчика. 2. По поводу «_просто вызова методов_»: можете ли вы опубликовать полный код?, @Edgar Bonet


1 ответ


Лучший ответ:

3

Рассмотрите возможность калибровки магнитометра. Практически все имеющиеся в наличии магнитометры требуют калибровки перед использованием их данных. Смещение (обычно называемое «жестким железом») и величина (обычно называемое «мягким железом») необходимо найти для каждого из трех датчиков (X, Y и Z) для отдельных магнитометров.

Поскольку в этой конструкции нет акселерометра, давайте упростим задачу и предположим, что магнитометр всегда будет использоваться на плоской поверхности с осью Z, перпендикулярной поверхности Земли. Предположим также, что датчики X и Y в магнитометре совершенно ортогональны друг другу.

Для калибровки магнитометра удалите металлические предметы из окрестностей и избегайте крупных металлических объектов, таких как автомобили, на расстоянии 10 метров. Снимайте показания датчиков X и Y несколько раз, пока эти датчики указывают на север и от него. Найдите максимальное и минимальное значения X и Y.

Определите значение калибровки смещения, сложив минимальное и максимальное значения, а затем разделив их на 2. Найдите значение калибровки величины, произвольно выбрав одну ось и отрегулировав величину другой для соответствия. Выбрав X, мы вычитаем минимум X из максимума X, чтобы найти диапазон X. Мы делаем то же самое для Y, чтобы найти диапазон Y. Затем мы предполагаем, что калибровочное значение величины X равно 1, а значение калибровки величины Y равно X-диапазону, делённому на Y-диапазон.

После завершения калибровки, чтобы получить калиброванные значения X и Y, мы вычитаем смещение X и Y соответственно. Затем мы умножаем значение Y с поправкой на смещение на значение калибровки величины Y.

Обратите внимание: этот тип калиброванного компаса трудно носить с собой в руках, поскольку его нельзя удерживать на уровне поверхности земли. Кроме того, поскольку по мере удаления от экватора наклон магнитного поля тем глубже погружается в землю, при путешествии на другую широту потребуется повторная калибровка.

Калибровочные расчеты на основе рассматриваемых данных:

X max to min is 42 to -22 so offset is 10 and range is 64
Y max to min is 120 to 48 so offset is 84 and range is 72
So Y magnitude calibration is 64/72 or 0.889

Данные, когда датчики направлены на восток:

Y ~48 & X ~11 
bearing = atan2(((48 - Y_offset) * Y_magnitude), ((11 - X_offset) * X_magnitude)) 
bearing = atan2(((48 - 84) * 0.889), ((11 - 10) * 1))
bearing = atan2(((-36) * 0.889), (1 * 1))
bearing = atan2(-32.004, 1)
bearing = -1.540 rad = -88.236 degrees

Если вместо -88,236 градусов желательно значение примерно 90 градусов, измените знак датчика Y в рамках процесса калибровки.

Функция программирования C atan2 представляет собой расширенную форму математической операции arc tan. Функция программирования C atan2 вычисляет полный круг 2-Пи. Чтобы проверить, как это работает, используйте этот онлайн-калькулятор atan2.

,

Вы почти можете получить значения калибровки смещения и величины на основе опубликованных данных. Но было бы лучше, если бы вы вращали датчик до упора и наблюдали за максимальными и минимальными значениями. Потому что они могут оказаться не там, где вы их ожидаете. [Магнитное склонение](https://www.ncei.noaa.gov/sites/default/files/2022-02/Miller%20Projection%20Main%20Field-%20Annual%20Change%20Declination%20%28D%29.jpg) изменения (по случайной закономерности) по всему миру., @st2000

Привет, спасибо за ответ, попробую откалибровать. Однако есть ли способ узнать, точны ли показания датчика? Например, в случае акселерометра я могу использовать вектор силы тяжести в качестве эталона. @st2000, @Sayantan Das

Вам не нужно менять значения X и Y в соответствии с любым из десятков различных магнитных стандартов измерения! Вас интересует только взаимосвязь между датчиками X и Y. Поскольку функция программирования C atan2 по существу делит одно на другое, вы сведете на нет любые усилия, которые вы затрачиваете на вычисление данного стандарта магнитных размеров. Кстати, я думаю, что данные ваших датчиков X и Y выглядят хорошо. Я думаю, вам просто нужно откалибровать и применить эту калибровку перед использованием функции atan2., @st2000

Хорошо, спасибо, я поработаю над калибровкой и вернусь сюда. @st2000, @Sayantan Das

Спасибо за ваши рекомендации, я откалибровал датчик на предмет смещения твердого железа, и теперь он работает достаточно хорошо. Только один быстрый вопрос, даже когда я держал датчик неподвижно, курс не фиксируется, он постоянно меняется в диапазоне 5-6 градусов, как мне сделать это стабильным?, @Sayantan Das

@SayantanDas: сгладьте показания с помощью цифрового фильтра нижних частот, например [экспоненциально взвешенного скользящего среднего](https://en.wikipedia.org/wiki/Exponential_smoothing). Однако будьте осторожны, вам придется обрабатывать углы, охватывающие 0°/360°. Я предлагаю вам попробовать [библиотеку runningAngle](https://github.com/RobTillaart/runningAngle), которая позаботится о правильной обработке упаковки за вас., @Edgar Bonet