Захват данных imu с помощью датчика абсолютной ориентации bno055

Захват данных imu с помощью датчика абсолютной ориентации bno055
Захват данных imu с помощью датчика абсолютной ориентации bno055
Anonim

Захват данных ИДУ с помощью абсолютного датчика ориентации BNO055

Bosch BNO055 сочетает в себе трехходовые акселерометры, гироскопы и магнитометры для обеспечения ориентации на пользователей.

О датчике

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

Чип также имеет прерывание, которое может уведомить микроконтроллер хоста, когда произошло определенное движение (изменение ориентации, внезапное ускорение и т. Д.).

Image
Image
Восстановленная блок-схема из таблицы данных

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

См. Видео ниже, чтобы узнать, как откалибровать датчик.

Спецификация UART InterfaceHandling для пайки Спецификация

Хост-микроконтроллер может запросить любые или все данные с датчиков (акселерометр, гироскоп и / или магнитометр) в режиме без термоядерки и может запросить абсолютную и относительную ориентацию (углы или кватернионы) в режиме сварки.

Датчик может возвращать ускорение в м / с² или мг ($$ 1 mg = 9.81 \ frac {m} {s ^ 2} times 10 ^ {- 3} $$); напряженность магнитного поля в мТл; данные гироскопа в градусах или радианах в секунду (соответственно DPS и RPS), углы Эйлера в градусах или радианах или кватернионы; и температуры в ° C или ° F. Все параметры задаются в регистре unit_selection (таблица 3-11 в техническом описании, стр. 30).

Уголки Эйлера против кватернионов

Если вы разрабатываете решение датчика для системы с ограниченным диапазоном движения, вы можете использовать углы Эйлера. Но если вы проектируете датчик, который может быть ориентирован в любом месте в пространстве, вы должны использовать кватернионы.

Уголки Эйлера

Углы Эйлера позволяют просто визуализировать объекты, повернутые три раза вокруг перпендикулярных осей (xyx, xzx, yxy, yzy, zxz, zyz, xyz, xzy, yxz, yzx, zxy, zyx).

Image
Image
xyz вращения от Wolfram.com

Пока оси остаются хотя бы частично перпендикулярными, их достаточно. Однако, когда оси вращаются, существует угол, в котором две оси могут описывать одно и то же вращение, создающее условие, известное как карданный замок. Когда происходит блокировка карданного вала, невозможно переориентироваться без внешней ссылки. См. Мою статью «Не теряйся в глубоком пространстве: понимание кватернионов», чтобы узнать больше о блокировке карданных.

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

Проблема использования карданного замка не существует при использовании кватернионов.

Кватернионы

Кватернионы были изобретены Уильямом Гамильтоном в 1843 году как способ умножить и разделить три числа. В течение многих десятилетий они медленно выходили из моды и видели оживление в ядерной эпохе и снова с современным программированием компьютерной графики. Кватернион состоит из четырех чисел: скалярного и трехкомпонентного вектора.

Image
Image

, где w, x, y и z - все вещественные числа, а i, j и k - кватернионные единицы.

Обычно w, x, y и z сохраняются в диапазоне от -1 до 1, а $$ \ sqrt {w ^ 2 + x ^ 2 + y ^ 2 + z ^ 2} = 1 $$.

Эти четыре числа лаконично переориентируют векторы за один оборот с изменениями длины или без них.

Image
Image
Синий и красный векторы имеют единичную длину. Оранжевый - это поворот, необходимый для поворота синего вектора в красный цвет

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

Image
Image
Метод преобразования кватерниона в матрицу ортогонального вращения 3 × 3

Нижеследующие фрагменты кода демонстрируют, как создать матрицу преобразования 3 × 3 и углы поворота, высоты тона и угла поворота от кватерниона.


/* Create Rotation Matrix rm from Quaternion */ double rm(3)(3); rm(1)(1) = quat.w()*quat.w() + quat.x()*quat.x() - quat.y()*quat.y() - quat.z()*quat.z(); rm(1)(2) = 2*quat.x()*quat.y() - 2*quat.w()*quat.z(); rm(1)(3) = 2*quat.x()*quat.z() + 2*quat.w()*quat.y(); rm(2)(1) = 2*quat.x()*quat.y() + 2*quat.w()*quat.z(); rm(2)(2) = quat.w()*quat.w() - quat.x()*quat.x() + quat.y()*quat.y() - quat.z()*quat.z(); rm(2)(3) = 2*quat.y()*quat.z() - 2*quat.w()*quat.x(); rm(3)(1) = 2*quat.x()*quat.z() - 2*quat.w()*quat.y(); rm(3)(2) = 2*quat.y()*quat.z() + 2*quat.w()*quat.x(); rm(3)(3) = quat.w()*quat.w() - quat.x()*quat.x() - quat.y()*quat.y() + quat.z()*quat.z(); /* Display Rotation Matrix */ Serial.print(rm(1)(1), 5);Serial.print(" \t"); Serial.print(rm(1)(2), 5);Serial.print(" \t"); Serial.println(rm(1)(3), 5); Serial.print(rm(2)(1), 5);Serial.print(" \t"); Serial.print(rm(2)(2), 5);Serial.print(" \t"); Serial.println(rm(2)(3), 5); Serial.print(rm(3)(1), 5);Serial.print(" \t"); Serial.print(rm(3)(2), 5);Serial.print(" \t"); Serial.println(rm(3)(3), 5); /* Create Roll Pitch Yaw Angles from Quaternions */ double yy = quat.y() * quat.y(); // 2 Uses below double roll = atan2(2 * (quat.w() * quat.x() + quat.y() * quat.z()), 1 - 2*(quat.x() * quat.x() + yy)); double pitch = asin(2 * quat.w() * quat.y() - quat.x() * quat.z()); double yaw = atan2(2 * (quat.w() * quat.z() + quat.x() * quat.y()), 1 - 2*(yy+quat.z() * quat.z())); /* Convert Radians to Degrees */ float rollDeg = 57.2958 * roll; float pitchDeg = 57.2958 * pitch; float yawDeg = 57.2958 * yaw; /* Display Roll, Pitch, and Yaw in Radians and Degrees*/ Serial.print("Roll:"); Serial.print(roll, 5); Serial.print(" Radians \t"); Serial.print(rollDeg, 2); Serial.println(" Degrees"); Serial.print("Pitch:"); Serial.print(pitch, 5); Serial.print(" Radians \t"); Serial.print(pitchDeg, 2); Serial.println(" Degrees"); Serial.print("Yaw:"); Serial.print(yaw, 5); Serial.print(" Radians \t"); Serial.print(yawDeg, 2); Serial.println(" Degrees");

Взаимодействие датчика с Arduino

Я приобрел датчик BNO055, прикрепленный к доске разработки с компонентами поддержки от Adafruit. Вы можете сэкономить немного денег, купив BNO055 от Digi-Key или Mouser и припаяв его к 28-контактному LGA-каналу 7, 5 × 4, 4 мм в DIP-конвертер для прототипирования на паяльной макете. Но для предельной экономии затрат после отгрузки я бы не рекомендовал ее.

Чтобы начать взаимодействие с BNO055 с помощью Arduino, выполните следующие действия:

  1. Подключите питание, землю, SDA и SCL
  2. Откройте среду разработки Arduino и нажмите «Эскиз» → «Включить библиотеку» → «Управление библиотеками»
  3. Найдите и установите «Adafruit BNO055» и «Adafruit Sensor»
  4. Откройте и отредактируйте Файл → Примеры → Adafruit BNO055 → Raw Data, чтобы прокомментировать секцию угла Эйлера и раскомментировать раздел Quaternion, или скопируйте и вставьте сокращенный код ниже.

#include#include#include#include/* This program is an abridged version of Adafruit BNO055 rawdata.ino available after installing the Adafruit BNO055 library File→Examples→Adafruit BNO055→Raw Data Connections on Arduino Uno ========================================================================= SCL to analog 5 | SDA to analog 4 | VDD to 3.3V DC | GND to common ground */ #define BNO055_SAMPLERATE_DELAY_MS (100) // Delay between data requests Adafruit_BNO055 bno = Adafruit_BNO055(); // Create sensor object bno based on Adafruit_BNO055 library void setup(void) { Serial.begin(115200); // Begin serial port communication if(!bno.begin()) // Initialize sensor communication { Serial.print("Ooops, no BNO055 detected … Check your wiring or I2C ADDR!"); } delay(1000); bno.setExtCrystalUse(true); // Use the crystal on the development board } void loop(void) { imu::Quaternion quat = bno.getQuat(); // Request quaternion data from BNO055 Serial.print(quat.w(), 4); Serial.print("\t"); // Print quaternion w Serial.print(quat.x(), 4); Serial.print("\t"); // Print quaternion x Serial.print(quat.y(), 4); Serial.print("\t"); // Print quaternion y Serial.print(quat.z(), 4); Serial.println(); // Print quaternion z delay(BNO055_SAMPLERATE_DELAY_MS); // Pause before capturing new data }

Программа просто связывается с BNO055 по I²C и передает данные обратно на компьютер через порт UART. Данные Quaternion отправляются обратно в виде данных с разделителями-разделителями с новыми символами после каждого кватерниона.

Имейте в виду, что пока ваш датчик не будет откалиброван, ваши данные недействительны.

Примеры данных кватерниона

В следующем примере я запросил данные о кватернионе из BNO055, когда я разместил его в случайной ориентации возле моего стола. Вы можете интерпретировать данные вручную на WolframAlpha.com, введя его как значения, разделенные запятыми, заключенные в круглые скобки после слова quaternion (например, «Quaternion» (0, 403, 0, 414, 0, 085, 0, 812) »)

W Икс Y Z
0.40344238 0.41363525 0.08508301 0.81176757
Цифры выше представляют собой кватернион, который описывает текущую ориентацию датчика относительно эталонной ориентации
Image
Image
Изображение от WolframAlpha.com показывает дефолт и фактическую ориентацию объекта
Image
Image
Изображение от WolframAlpha.com показывает ось вращения и количество оборотов, необходимое для достижения текущей позиции из положения по умолчанию

Хотя, конечно, нет необходимости смотреть в Интернет для обработки ваших данных кватерниона, приятно иметь возможность дважды проверить вашу работу.

Захват данных с помощью Mathematica

Mathematica - это универсальная компьютерная программа, которая может обрабатывать практически любые данные, которые вы можете себе представить. Для тех, кого это интересует, я собрал несколько строк кода, которые демонстрируют, как получать данные с устройства и как использовать Mathematica для оценки данных с помощью нескольких функций на основе кватернионов. Код ниже был написан для Windows, поэтому пользователям Linux и Mac, возможно, придется изменить строку устройства ввода (строка, начинающаяся bConnect).

Image
Image
Снимок экрана из ноутбука Mathematica, доступный с помощью кнопки загрузки ниже

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

Начните с нажатия «Подключить Arduino», а затем «Данные из буфера». Я не включал проверку данных или проверку ошибок, поэтому, если область данных пуста или неправильно определена, единственный вариант - вспомнить данные.

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

Image
Image
Данные, отправленные из BNO055, анализируются в Mathematica и используются для переориентации стрелки в ссылочной сфере

Кватернион с математикой

Управление двухосным карданом

BNO055 хорошо подходит для использования в робототехнике. В качестве примера приложения я буду использовать BNO055 для управления лазером, установленным на двухосном кардане на сервоприводе. Код должен допускать беспрепятственное введение третьей оси вращения для любого читателя, достаточно удачного, чтобы иметь его.

Подключите BNO055 по-прежнему и добавьте сервоприводы, подключенные к цифровым контактам 9-11. Если вы используете карданы для крепления камеры, подумайте о переходе на плату Alorium XLR8. Servos полагаются на точное время, и если Arduino обрабатывает конкурирующие задачи, это может привести к дрожанию. XLR8 является заменой Arduino, сделанной из FPGA. Он имеет библиотеку, которая может управлять сервомашинами из отдельного блока «XLR8tor» (ускоритель) для устойчивого и плавного перемещения сервопривода.

Image
Image
Обзор схемы подключения
Image
Image
Замена Arduino Uno R3: XLR8 против Sparkfun «Redboard» Arduino Uno R3

//---- Included Libraries ----// #include// I²C library #include// trig functions #include// Base library for sensors #include// BNO055 specific library #include// Vector, Matrix, and IMUMath library //#include// Standard Servo library #include// XLR8 servo library #include// XLR8 accelerated floating point math #define BNO055_SAMPLERATE_DELAY_MS (50) // Set pause between samples //---- Variable Declaration ----// boolean debug = true; // true/false = extra/no information over serial int rollPin = 9; // Digital pin for roll int yawPin = 10; // Digital pin for yaw int pitchPin = 11; // Digital pin for pitch float roll, pitch, yaw; // Variable to hold roll, pitch, yaw information Adafruit_BNO055 bno = Adafruit_BNO055(); // Use object bno to hold information Servo rollServo; // Create servo rollServo Servo pitchServo; // Create servo pitchServo Servo yawServo; // Create servo yawServo void setup(void) { rollServo.attach(rollPin); // The rollServo is connected at rollPin pitchServo.attach(pitchPin); // The pitchServo is connected at pitchPin yawServo.attach(yawPin); // The yawServo is connected at yawPin Serial.begin(115200); // Create serial connection at 115, 000 Baud if (!bno.begin()) // Attempt communication with sensor { Serial.print("Ooops, no BNO055 detected … Check your wiring or I2C ADDR!"); } delay(100); // Wait 0.1 seconds to allow it to initialize bno.setExtCrystalUse(true); // Tell sensor to use external crystal } //---- Main Program Loop ----// void loop() { //---- Request Euler Angles from Sensor ----// imu::Vector euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER); if (debug) { // If debug is true, send information over serial Serial.print("Measured Euler Roll-Pitch-Yaw"); Serial.print("\t yaw: "); Serial.print(euler.x()); Serial.print("\t"); Serial.print("\t pitch: "); Serial.print(euler.z()); Serial.print("\t"); Serial.print("\t roll: "); Serial.print(euler.y()); Serial.println(); } /* Remap information from the sensor over the 0° - 180° range of the servo The Yaw values are between 0° to +360° The Roll values are between -90° and +90° The Pitch values are between -180° and +180° */ int servoYaw = map(euler.x(), 0, 360, 0, 180); int servoRoll = map(euler.y(), -90, 90, 0, 180); int servoPitch = map(euler.z(), -180, 180, 0, 180); if (debug) { // If debug is true, send information over serial Serial.print("Measured Euler Roll-Pitch-Yaw"); Serial.print("\t Yaw Servo: "); Serial.print(servoYaw); Serial.print("\t"); Serial.print("\t Pitch Servo: "); Serial.print(servoPitch); Serial.print("\t"); Serial.print("\t Roll Servo: "); Serial.print(servoRoll); Serial.println(); } // If debug is true, send information over serial if (debug) { Serial.println("Calculated Servo Roll-Pitch-Yaw"); Serial.print("\t roll:"); Serial.print(servoRoll, DEC); Serial.print("\t"); Serial.print("\t pitch:"); Serial.print(servoPitch, DEC); Serial.print("\t"); Serial.print("\t yaw:"); Serial.print(servoYaw, DEC); Serial.println(); } rollServo.write(servoRoll); // Send mapped value to rollServo pitchServo.write(servoPitch); // Send mapped value to rollServo yawServo.write(servoYaw); // Send mapped value to rollServo delay(BNO055_SAMPLERATE_DELAY_MS); // Wait before rerunning loop }

Эскизы Ардуино для BNO055

Посмотрите мой проект в действии ниже:

Вывод

BNO055 представляет собой простую в использовании инерциальную измерительную установку, которая может быть включена в широкий спектр применений - от стабилизации робота (quadcopter, перевернутый маятник и т. Д.) До стабилизации и навигации камеры (включая мертвую расчёт).

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

Читатели - если вы хотите увидеть проект или статью, в которой более подробно используются кватернионы, пожалуйста, сообщите нам в разделе комментариев ниже.

Рекомендуемое изображение любезно предоставлено Adafruit.

Попробуйте этот проект сами! Получить спецификацию.