BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
StefanBonhof wrote:I wrote a short python script in Blender to visualise the angles in one object, but I see the same behavior there.
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
import serial
import time
import bpy
import math
ser = serial.Serial('COM11','115200')
cube = bpy.context.selected_objects[0]
for x in range(100):
s = ser.readline()
o = s.split()
yaw = -math.pi/180 * float(o[0])
roll = -math.pi/180 * float(o[1])
pitch = math.pi/180 * float(o[2])
cube.rotation_euler = [roll, pitch, yaw]
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
ser.close()
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
But, it is impossible to calculate a unique set of Euler angles to represent any given orientation, which vastly reduces their usefulness, and in cases where the singularities arise, the calculation fails completely. This thread is in fact a good example of the basic problem.Euler angles can accurately describe any 3D orientation,
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
gammaburst wrote:I figured out Blender, Python, and serial communication.
As I rotate my BNO085, Blender rotates its default cube the same way. It works fine.
My Arduino reads the BNO085 ten times per second, and outputs serial text messages containing yaw roll pitch in degrees using aerospace conventions: positive yaw is nose right, positive roll is left wing up, positive pitch is nose up. Here's some example data:
20.82 -14.69 6.11
21.91 -12.11 6.44
23.52 -8.76 8.39
24.64 -6.72 10.25
25.33 -5.87 10.57
26.12 -3.64 12.21
25.89 -3.82 15.02
On my Windows 7 machine I installed pyserial 3.5 into Blender 2.92, and then ran this Python script. It runs for 100 messages (ten seconds) and then exits:Maybe that will help you.
- Code: Select all | TOGGLE FULL SIZE
import serial
import time
import bpy
import math
ser = serial.Serial('COM11','115200')
cube = bpy.context.selected_objects[0]
for x in range(100):
s = ser.readline()
o = s.split()
yaw = -math.pi/180 * float(o[0])
roll = -math.pi/180 * float(o[1])
pitch = math.pi/180 * float(o[2])
cube.rotation_euler = [roll, pitch, yaw]
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
ser.close()
cube = bpy.context.selected_objects[0]
cube.rotation_mode = 'QUATERNION'
for x in range(10000):
s = ser.readline()
o = s.split()
x = float(o[0])
y = float(o[1])
z = float(o[2])
w = float(o[3])
cube.rotation_quaternion = [w, x, y, z] // Not sure yet if this is the order blender takes quaternion values but this works as a test setup nonetheless.
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
time.sleep(0.10)
ser.close()
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
I did however try to use quaternions instead of euler angles and that fixed the issue.
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
#include <SPI.h>
#include <I2C.h>
#include <Wire.h>
#include <Adafruit_BNO08x.h>
#define BNO08X_RESET -1
EasyTransferI2C RX_I2C;
float angles[3];
// IMU setup
Adafruit_BNO08x bno08x(BNO08X_RESET);
sh2_SensorValue_t sensorValue;
struct euler_t {
float yaw;
float pitch;
float roll;
} ypr;
#ifdef FAST_MODE
// Top frequency is reported to be 1000Hz (but freq is somewhat variable)
sh2_SensorId_t reportType = SH2_GYRO_INTEGRATED_RV;
long reportIntervalUs = 2000;
#else
// Top frequency is about 250Hz but this report is more accurate
sh2_SensorId_t reportType = SH2_ROTATION_VECTOR;
long reportIntervalUs = 5000;
#endif
void setReports(sh2_SensorId_t reportType, long report_interval) {
//Serial.println("Setting desired reports");
if (! bno08x.enableReport(reportType, report_interval)) {
//Serial.println("Could not enable stabilized remote vector");
}
}
void setup() {
// Begin I2C communications:
Wire.begin();
delay(50);
// IMU init:
bno08x.begin_I2C();
delay(10);
setReports(reportType, reportIntervalUs);
// Serial for testing
Serial.begin(115200);
delay(1000);
}
void quaternionToEuler(float qr, float qi, float qj, float qk, euler_t* ypr, bool degrees = false) {
float sqr = sq(qr);
float sqi = sq(qi);
float sqj = sq(qj);
float sqk = sq(qk);
ypr->yaw = atan2(2.0 * (qi * qj + qk * qr), (sqi - sqj - sqk + sqr));
ypr->pitch = asin(-2.0 * (qi * qk - qj * qr) / (sqi + sqj + sqk + sqr));
ypr->roll = atan2(2.0 * (qj * qk + qi * qr), (-sqi - sqj + sqk + sqr));
if (degrees) {
ypr->yaw *= RAD_TO_DEG;
ypr->pitch *= RAD_TO_DEG;
ypr->roll *= RAD_TO_DEG;
}
}
void quaternionToEulerGRV(sh2_RotationVector* rotational_vector, euler_t* ypr, bool degrees = false) {
quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}
void quaternionToEulerRV(sh2_RotationVectorWAcc_t* rotational_vector, euler_t* ypr, bool degrees = false) {
quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}
void quaternionToEulerGI(sh2_GyroIntegratedRV_t* rotational_vector, euler_t* ypr, bool degrees = false) {
quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}
void loop() {
delay(10);
// Read IMU.
if (bno08x.getSensorEvent(&sensorValue)) {
// in this demo only one report type will be received depending on FAST_MODE define (above)
switch (sensorValue.sensorId) {
case SH2_GAME_ROTATION_VECTOR:
quaternionToEulerGRV(&sensorValue.un.gameRotationVector, &ypr, true);
case SH2_GYRO_INTEGRATED_RV:
// faster (more noise?)
quaternionToEulerGI(&sensorValue.un.gyroIntegratedRV, &ypr, true);
case SH2_ROTATION_VECTOR:
quaternionToEulerRV(&sensorValue.un.rotationVector, &ypr, true);
break;
}
}
Serial.print(ypr.yaw);
Serial.print(" ");
Serial.print(ypr.pitch);
Serial.print(" ");
Serial.println(ypr.roll);
}
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
In addition to all the ambiguities associated with the various Euler angle definitions, the equations you posted to calculate the angles do not take proper care with the special positions where singularities cause the calculation to go awry. Extra steps need to be added to correct for those occurrences.so I don't know where I am going wrong.
Alternative Euler Angle Sequences
I am trying to make this site consistant and therefore I have standarised on one Euler angle sequence as defined on this page. However there are often reasons to use different Euler angle sequences:
You may be working with a program which uses a different Euler angle sequence.
You may need the singularities to be at different angles so they are less likely to cause problems.
The objects that you are modelling may just favor a different set of angles
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg
Re: BNO085 Roll and yaw buggy when pith + or - 90 deg