BNO055 Problem with full 360 degree in pitch

Hello there,

i am currently very helpless with getting the BNO055 to work correctly.
What i am trying to do is to connect the BNO055 to “vvvv” and map the roll pitch yaw to a 3d object like shown in the bunny example sketch with processing.
The mapping is no problem but the data which the BNO055 provides is not working in one axis.
The data in the first Axis (when i rotate (“Yaw”)) is displayed in full 360 degre. everythings fine there :wink:
Roll displays data from -180 to 0 to +180 degree. I got that to work for me with this litte line of code:

z = euler.z();

if (z < 0){
z = z + 360;
}

works also fine.

but in the pitch axis displays the data like this:

The first 180 degrees are from 0 to 90 and back to 0. that means when i am at 100 degrees in real life the BNO055 displays only 80… it counts back again after reaching 90 degree.
Same goes for the other half. from 0 to -90 back to 0.

The examplecode i am using most of the time is the “rawdata” from the BNO055 library.

Searching the internet provided me with the solution to work with quaternions and converting them back to euler.

“imu::Vector<3> euler = quat.toEuler();”

didnt work… same counting back and forth at 90 and -90 degree in pitch…

right now i am trying to fuse the the gravity and accelerometer data with the euler angles to display the right data from this function:

// Possible vector values can be:
// - VECTOR_ACCELEROMETER - m/s^2
// - VECTOR_MAGNETOMETER - uT
// - VECTOR_GYROSCOPE - rad/s
// - VECTOR_EULER - degrees
// - VECTOR_LINEARACCEL - m/s^2
// - VECTOR_GRAVITY - m/s^2
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_GRAVITY);

The problem to me seems that it can output only one kind of data.
Meaning that i cant display acceleration, gravity and euler at the same time…

i looked in the BNO055 library and there is only one possible case at a time:

imu::Vector<3> Adafruit_BNO055::getVector(adafruit_vector_type_t vector_type)
{
imu::Vector<3> xyz;
uint8_t buffer[6];
memset (buffer, 0, 6);

int16_t x, y, z;
x = y = z = 0;

/* Read vector data (6 bytes) */
readLen((adafruit_bno055_reg_t)vector_type, buffer, 6);

x = ((int16_t)buffer[0]) | (((int16_t)buffer[1]) << 8);
y = ((int16_t)buffer[2]) | (((int16_t)buffer[3]) << 8);
z = ((int16_t)buffer[4]) | (((int16_t)buffer[5]) << 8);

/* Convert the value to an appropriate range (section 3.6.4) /
/
and assign the value to the Vector type /
switch(vector_type)
{
case VECTOR_MAGNETOMETER:
/
1uT = 16 LSB /
xyz[0] = ((double)x)/16.0;
xyz[1] = ((double)y)/16.0;
xyz[2] = ((double)z)/16.0;
break;
case VECTOR_GYROSCOPE:
/
1rps = 900 LSB /
xyz[0] = ((double)x)/900.0;
xyz[1] = ((double)y)/900.0;
xyz[2] = ((double)z)/900.0;
break;
case VECTOR_EULER:
/
1 degree = 16 LSB /
xyz[0] = ((double)x)/16.0;
xyz[1] = ((double)y)/16.0;
xyz[2] = ((double)z)/16.0;
break;
case VECTOR_ACCELEROMETER:
case VECTOR_LINEARACCEL:
case VECTOR_GRAVITY:
/
1m/s^2 = 100 LSB */
xyz[0] = ((double)x)/100.0;
xyz[1] = ((double)y)/100.0;
xyz[2] = ((double)z)/100.0;
break;
}

return xyz;
}

Or am i totaly wrong?

Is anyone here knowing a suitable solution to my problem?
Or is there a understandable tutorial on how to achieve the goal on the 360 degree in the pitch axis?!

I would be glad for any kind of help… i am a little desperate at this moment…

Another probleme is that i only understand a little when it comes to writing code in arduino.

Thanks for your help

knoeterich

With Euler angles, you cannot use 360 degree ranges for more than two axes, because if you do, several different sets of angles correspond to the [u]same orientation[/u].

Typically, only yaw is represented as 0-360. Learn to live with the default Euler angle ranges, as that works "correctly" (provided you have properly calibrated the BNO055).

See this reference: http://www.chrobotics.com/library/understanding-euler-angles

here shes getting 360 in every angle: i2cdevlib "Teapot" Demo with an MPU-6050 IMU - YouTube

I have tried the mpu6050 too but i cant use the data (when uncommenting //#define OUTPUT_TEAPOT) that processing is using which is coming from the serial port.

does anybody have an idea how to make the data usable/readable for “vvvv” ?

here shes getting 360 in every angle

No, she is not. She is using a quaternion to represent the orientation, which avoids the singularities with Euler angle representations of an orientation.

More than 9 degrees pitch does not make sense, since it can be represented by heading inversion of 180 degrees.

As far as not being able to get more that one type of data at the time, did you modify the code of the Wire library to allow for a faster i2c transactions ?

Default i2c speed of 100kHz is not enough for the amount of data generated by the BNO055.

Hi, according to my experience it is possible to rotate freely only in such axis that is not affected by gimbal lock. It should work. But it works untill I stop rotation (fix actual angle) and rotate in another axis. For example: I rotate in X axis, stop in 30°, start rotation in Z and unfortunatelly (X) 30° flips to another angle and back in one moment (in certain range Z angles). Is there any way how to rotate (only) in one chosen axis (X,Y or Z) in full angles range and without the effects caused by other axes rotation? Other axes angles I don't need to use.