Лучший способ получить угловую скорость от датчика 9 DoF

Я использую датчик BNO055 (9° dof IMU) для проекта, который будет использовать угловую скорость курсора мыши на экране.

До сих пор я получал выход кватерниона от датчика и мог преобразовать его в угловую скорость несколькими способами. Первый, умножение 1 образца кватерниона на его конъюгат в следующем образце, а затем преобразование дельты кватерниона в углы Эйлера. Во-вторых, преобразование кватернионов в углы Эйлера, а затем нахождение их изменения между выборками.

Оба метода приводят к измерению угловой скорости, но каждый из них имеет свои преимущества и недостатки: Например, Дельта кватерниона между образцами не страдает от карданной блокировки, но трудно изолировать ось y от движения оси z.

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

Есть ли лучший способ сделать это?

Мой код включен ниже для справки с 2 подходами на случай, если он будет полезен/интересен. Он использует репозиторий Adafruit, выполняя стандартные действия в функции setup, а затем вызывая функцию ниже в цикле.

void quaternion_Delta () {
  // Quaternion data 1
  imu::Quaternion quat = bno.getQuat();
  // Euler 1
  imu::Vector<3> euler_one = quat.toEuler();
  //delay between samples
  delay(BNO055_SAMPLERATE_DELAY_MS);
  // Quaternion data 2
  imu::Quaternion quat_two = bno.getQuat();
  // Euler 2
  imu::Vector<3> euler_two = quat_two.toEuler();
  // quaternion comparison
  imu::Quaternion quatDelta = quat_two * quat.conjugate ();
  imu::Vector<3> euler = quatDelta.toEuler();
  Serial.print(" X: ");
  Serial.print(euler.x()*radius_to_degrees, 2);
  Serial.print(" Y: ");
  Serial.print(euler.y()*radius_to_degrees, 2);
  Serial.print(" Z: ");
  Serial.print(euler.z()*radius_to_degrees, 2);
  Serial.print("\t\t");
  // Euler comparison
  imu::Vector<3> euler_comparison = euler_two - euler_one;
  Serial.print(" x: ");
  Serial.print(euler_comparison.x()*radius_to_degrees, 2);
  Serial.print(" y: ");
  Serial.print(euler_comparison.y()*radius_to_degrees, 2);
  Serial.print(" z: ");
  Serial.print(euler_comparison.z()*radius_to_degrees, 2);
  Serial.print("\n");
  }

, 👍0

Обсуждение

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


1 ответ


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

1

Подумайте о том, чтобы опираться на исследования Себастьяна Мэджвика PhD IMU. Проект GitHub Arduino, основанный на работе Мэджвика, можно найти здесь.

,

Спасибо за ваш ответ. Датчик BNO использует запатентованный алгоритм слияния, но я видел эту реализацию на другом датчике. Я думаю, что мой вопрос сводится к тому, будет ли более точным опросить датчик на наличие кватернионов, по которым можно рассчитать угловую скорость, или опросить только гироскоп. Есть ли единственная разница в том, что один не ориентирован, а другой абсолютен?, @Zhelyazko Grudov

Я не уверен. Я не работал с чипами IMU, которые создают кватернионы. Только с чипами IMU,которые обеспечивают значения X, Y и Z от акселерометров и гироскопов., @st2000

Существует также библиотека Adafruit для этого и других алгосов fusion., @Zhelyazko Grudov