Hi everyone, I'm working on a project that involves 2 BNO055 sensors for getting the angle of one sensor relative to the other. Indeed, the project consist in understanding if the bow used by the cellist is in in the correct position (that should be always perpendicular to the strings).
Specifically for this project I'm using Teensy 3.6, but I think it shouldn't be an issue. Each sensor is connected to a different I2C port of the Teensy.
The 2 sensors are used in the following way:
- sensor 1 is ideally mounted on the instrument body;
- sensor 2 is ideally mounted on the bow.
I'm having some issues regarding the "roll" angle data that I get. I don't know why sometimes the "roll" value (that is the one I'm using for getting the angle among sensors) change "scale", turning from 0° to something else without actually changing its inclination in that axis.
So, for example, at the beginning the "roll" value in a certain position is 0°:
Then, I start using it, it displays correct data, for instance here it's correctly displaying 45° (more or less):
But then, it becomes 100° when I perform broad movements (especially on the pitch) and it "decides" that the "new value" in that same specific position is 100°:
Since I'm not very familiar with quaternions calculation, I suspect it might be something related to the translation process (quaternions -> degrees) but I'm not sure.
If you could help me, it would be super nice! Thank you
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
Adafruit_BNO055 bno1 = Adafruit_BNO055(55, 0x28, &Wire);
Adafruit_BNO055 bno2 = Adafruit_BNO055(55, 0x28, &Wire1);
//original quaternions obtained from the sensor
imu::Quaternion quaternion1;
imu::Quaternion quaternion2;
//reference quaternions, for setting the "0"
imu::Quaternion quaternion_reference_1;
imu::Quaternion quaternion_reference_2;
//actual quaternion zero
imu::Quaternion quaternion_zero_1;
imu::Quaternion quaternion_zero_2;
void setup() {
Serial.begin(9600);
Wire.begin();
Wire1.begin();
//control if everything is well connected
if (!bno1.begin()) {
Serial.println("Failed to initialize BNO055 sensor 1. Check your wiring!");
while (1)
;
}
if (!bno2.begin()) {
Serial.println("Failed to initialize BNO055 sensor 2. Check your wiring!");
while (1)
;
}
/* Use external crystal for better accuracy */
bno1.setExtCrystalUse(true);
bno2.setExtCrystalUse(true);
delay(1000);
}
void loop() {
sensors_event_t event1;
sensors_event_t event2;
// Get the first quaternion orientation from BNO055 sensor 1
bno1.getEvent(&event1);
imu::Quaternion quaternion_1 = bno1.getQuat();
// Get the second quaternion orientation from BNO055 sensor 2
bno2.getEvent(&event2);
imu::Quaternion quaternion_2 = bno2.getQuat();
// set "0" during the first 5 seconds of activity
if (millis() < 5000) {
quaternion_reference_1 = bno1.getQuat();
quaternion_reference_2 = bno2.getQuat();
}
// Set the zero-point quaternion
quaternion_zero_1 = quaternion_reference_1.conjugate();
quaternion_zero_2 = quaternion_reference_2.conjugate();
// Set zero for quaternion 1 and 2
imu::Quaternion quaternion_relative_1 = quaternion_1 * quaternion_zero_1;
imu::Quaternion quaternion_relative_2 = quaternion_2 * quaternion_zero_2;
// Calculate the angular difference between relative quaternions
imu::Quaternion quaternion_difference = quaternion_relative_1 * quaternion_relative_2.conjugate();
// Convert quaternion to Euler angles
imu::Vector<3> eul = quaternion_difference.toEuler();
double roll = eul.x();
double pitch = eul.y();
double yaw = eul.z();
//from rad to deg
roll = roll * (180 / 3.1415);
pitch = pitch * (180 / 3.1415);
yaw = yaw * (180 / 3.1415);
// Print the Euler angles in degrees
Serial.print("Roll: ");
Serial.print(roll);
Serial.print(" degrees\tPitch: ");
Serial.print(pitch);
Serial.print(" degrees\tYaw: ");
Serial.print(yaw);
Serial.println(" degrees");
delay(100);
}