Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
adafruit_support_bill wrote:We have detailed guides for using this sensor with Arduino, Raspberry Pi and Beagle Bones:
https://learn.adafruit.com/adafruit-bno ... n?view=all
https://learn.adafruit.com/bno055-absol ... e?view=all
imu::Quaternion quat = bno.getQuat();
quat.x() = -quat.x();
quat.y() = -quat.y();
quat.z() = -quat.z();
// fetch linear acceleration (excludes gravity)
imu::Vector<3> linearaccel = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
// compute earth-referenced acceleration (excludes sensor tilt)
acc[0] = (1-2*(quat.y()*quat.y() + quat.z()*quat.z()))*linearaccel[0] + (2*(quat.x()*quat.y() + quat.w()*quat.z()))*linearaccel[1] + (2*(quat.x()*quat.z() - quat.w()*quat.y()))*linearaccel[2]; // rotate linearaccel by quaternion
acc[1] = (2*(quat.x()*quat.y() - quat.w()*quat.z()))*linearaccel[0] + (1-2*(quat.x()*quat.x() + quat.z()*quat.z()))*linearaccel[1] + (2*(quat.y()*quat.z() + quat.w()*quat.x()))*linearaccel[2];
acc[2] = (2*(quat.x()*quat.z() + quat.w()*quat.y()))*linearaccel[0] + (2*(quat.y()*quat.z() - quat.w()*quat.x()))*linearaccel[1] + (1-2*(quat.x()*quat.x() + quat.y()*quat.y()))*linearaccel[2];
Re: Calculate Earth Referenced Acceletation with BNO055
I compared raw acceleration data with quaternion calculated acceleration data. But there are not similar.
Re: Calculate Earth Referenced Acceletation with BNO055
adafruit_support_bill wrote:I compared raw acceleration data with quaternion calculated acceleration data. But there are not similar.
Please post an example of the data you are referring to.
Re: Calculate Earth Referenced Acceletation with BNO055
I want to transform bno055's acceleration data to my coordianate system whichever rotations when my sensors turns. Because ı calculate position with this acceleration data.
Re: Calculate Earth Referenced Acceletation with BNO055
adafruit_support_bill wrote:I want to transform bno055's acceleration data to my coordianate system whichever rotations when my sensors turns. Because ı calculate position with this acceleration data.
Are you trying to calculate position or orientation? The BNO055 can give you orientation directly in Euler or Quaternion form.
If you want to calculate position, you need to do a double integration on the raw data. Due to the double integration, this is subject to cumulative errors and not likely to be accurate over the long-term.
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#define BNO055_SAMPLERATE_PERIOD_MS 10
Adafruit_BNO055 bno = Adafruit_BNO055(55);
unsigned long tnext, tnow;
void setup(void)
{
Serial.begin(115200);
Serial.println("Orientation Sensor Test"); Serial.println("");
/* Initialise the sensor */
if(!bno.begin())
{
Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
while(1);
}
tnext = millis() + 100;
}
void loop(void)
{
// fetch quaternion, negative
imu::Quaternion quat = bno.getQuat();
quat.x() = -quat.x();
quat.y() = -quat.y();
quat.z() = -quat.z();
// fetch linear acceleration (excludes gravity)
imu::Vector<3> linearaccel = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
// compute earth-referenced acceleration (excludes sensor tilt)
imu::Vector<3> acc;
acc[0] = (1-2*(quat.y()*quat.y() + quat.z()*quat.z()))*linearaccel[0] + (2*(quat.x()*quat.y() + quat.w()*quat.z()))*linearaccel[1] + (2*(quat.x()*quat.z() - quat.w()*quat.y()))*linearaccel[2]; // rotate linearaccel by quaternion
acc[1] = (2*(quat.x()*quat.y() - quat.w()*quat.z()))*linearaccel[0] + (1-2*(quat.x()*quat.x() + quat.z()*quat.z()))*linearaccel[1] + (2*(quat.y()*quat.z() + quat.w()*quat.x()))*linearaccel[2];
acc[2] = (2*(quat.x()*quat.z() + quat.w()*quat.y()))*linearaccel[0] + (2*(quat.y()*quat.z() - quat.w()*quat.x()))*linearaccel[1] + (1-2*(quat.x()*quat.x() + quat.y()*quat.y()))*linearaccel[2];
Serial.print("EarthRefAccel:");
for (int n=0; n<3; n++)
{
String s = String(acc[n]);
for (int m=s.length(); m<7; m++)
Serial.print(" ");
Serial.print(s);
}
Serial.println("");
tnow = millis();
delay(tnext - tnow);
tnext += BNO055_SAMPLERATE_PERIOD_MS;
}
Re: Calculate Earth Referenced Acceletation with BNO055
gammaburst wrote:Hi bugratufan,
That looks like a code snippet from one of my examples.
To transform the BNO's sensor-referenced linear acceleration to an earth-referenced linear acceleration, rotate the BNO's linear acceleration by the conjugate of the BNO's normalized quaternion. That's what my code snippet should do.
Here's a working example that outputs earth-referenced linear acceleration:
- With sensor at rest, see zero acceleration.
- Shake sensor east-west, see only X acceleration.
- Shake sensor north-south, see only Y acceleration.
- Shake sensor up-down, see only Z acceleration.
- The output acceleration vector is now unaffected by sensor orientation.
- Tested with Arduino Uno + BNO055.
- Remember to calibrate the sensor.
- My axes names may be arranged differently than yours.If that's not the transformation you want, please explain more clearly.
- Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#define BNO055_SAMPLERATE_PERIOD_MS 10
Adafruit_BNO055 bno = Adafruit_BNO055(55);
unsigned long tnext, tnow;
void setup(void)
{
Serial.begin(115200);
Serial.println("Orientation Sensor Test"); Serial.println("");
/* Initialise the sensor */
if(!bno.begin())
{
Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
while(1);
}
tnext = millis() + 100;
}
void loop(void)
{
// fetch quaternion, negative
imu::Quaternion quat = bno.getQuat();
quat.x() = -quat.x();
quat.y() = -quat.y();
quat.z() = -quat.z();
// fetch linear acceleration (excludes gravity)
imu::Vector<3> linearaccel = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
// compute earth-referenced acceleration (excludes sensor tilt)
imu::Vector<3> acc;
acc[0] = (1-2*(quat.y()*quat.y() + quat.z()*quat.z()))*linearaccel[0] + (2*(quat.x()*quat.y() + quat.w()*quat.z()))*linearaccel[1] + (2*(quat.x()*quat.z() - quat.w()*quat.y()))*linearaccel[2]; // rotate linearaccel by quaternion
acc[1] = (2*(quat.x()*quat.y() - quat.w()*quat.z()))*linearaccel[0] + (1-2*(quat.x()*quat.x() + quat.z()*quat.z()))*linearaccel[1] + (2*(quat.y()*quat.z() + quat.w()*quat.x()))*linearaccel[2];
acc[2] = (2*(quat.x()*quat.z() + quat.w()*quat.y()))*linearaccel[0] + (2*(quat.y()*quat.z() - quat.w()*quat.x()))*linearaccel[1] + (1-2*(quat.x()*quat.x() + quat.y()*quat.y()))*linearaccel[2];
Serial.print("EarthRefAccel:");
for (int n=0; n<3; n++)
{
String s = String(acc[n]);
for (int m=s.length(); m<7; m++)
Serial.print(" ");
Serial.print(s);
}
Serial.println("");
tnow = millis();
delay(tnext - tnow);
tnext += BNO055_SAMPLERATE_PERIOD_MS;
}
Using the BNO055's fusion outputs (such as linear acceleration) to compute velocity or displacement generally gives unsatisfactory results. The BNO is not a precision instrument. If you somehow achieve good results, please share your technique.
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
Re: Calculate Earth Referenced Acceletation with BNO055
void rotate_vector_by_conjugate_quaternion(float *vx, float *vy, float *vz, float qw, float qx, float qy, float qz)
{
float tx = (1-2 * (qy * qy + qz * qz)) * *vx + (2 * (qx * qy - qw * qz)) * *vy + (2 * (qx * qz + qw * qy)) * *vz;
float ty = (2 * (qx * qy + qw * qz)) * *vx + (1-2 * (qx * qx + qz * qz)) * *vy + (2 * (qy * qz - qw * qx)) * *vz;
float tz = (2 * (qx * qz - qw * qy)) * *vx + (2 * (qy * qz + qw * qx)) * *vy + (1-2 * (qx * qx + qy * qy)) * *vz;
*vx = tx;
*vy = ty;
*vz = tz;
}