Visualize IMU data sent over BLE on a computer
Fork of LSM9DS1_Library by
Revision 3:fd549671e512, committed 2016-03-13
- Comitter:
- cvmp94
- Date:
- Sun Mar 13 21:40:10 2016 +0000
- Parent:
- 2:e8c2301f7523
- Commit message:
- initial commit
Changed in this revision
MadgwickUpdate.h | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r e8c2301f7523 -r fd549671e512 MadgwickUpdate.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MadgwickUpdate.h Sun Mar 13 21:40:10 2016 +0000 @@ -0,0 +1,98 @@ +#include "mbed.h" +#include "math.h" + +float deltat = 0.0f; +int lastUpdate = 0, firstUpdate = 0, Now = 0; +float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + +float PI = 3.14159265358979323846f; +float GyroMeasError = PI * (60.0f / 180.0f); // gyroscope measurement error in rads/s (start at 60 deg/s), then reduce after ~10 s to 3 +float beta = sqrt(3.0f / 4.0f) * GyroMeasError; // compute beta +float GyroMeasDrift = PI * (1.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s) +float zeta = sqrt(3.0f / 4.0f) * GyroMeasDrift; + +void MadgwickQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz) { + float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3]; // short name local variable for readability + float norm; // vector norm + float f1, f2, f3; // objective funcyion elements + float J_11or24, J_12or23, J_13or22, J_14or21, J_32, J_33; // objective function Jacobian elements + float qDot1, qDot2, qDot3, qDot4; + float hatDot1, hatDot2, hatDot3, hatDot4; + float gerrx, gerry, gerrz, gbiasx, gbiasy, gbiasz; // gyro bias error + + // Auxiliary variables to avoid repeated arithmetic + float _halfq1 = 0.5f * q1; + float _halfq2 = 0.5f * q2; + float _halfq3 = 0.5f * q3; + float _halfq4 = 0.5f * q4; + float _2q1 = 2.0f * q1; + float _2q2 = 2.0f * q2; + float _2q3 = 2.0f * q3; + float _2q4 = 2.0f * q4; + + // Normalise accelerometer measurement + norm = sqrt(ax * ax + ay * ay + az * az); + if (norm == 0.0f) return; // handle NaN + norm = 1.0f/norm; + ax *= norm; + ay *= norm; + az *= norm; + + // Compute the objective function and Jacobian + f1 = _2q2 * q4 - _2q1 * q3 - ax; + f2 = _2q1 * q2 + _2q3 * q4 - ay; + f3 = 1.0f - _2q2 * q2 - _2q3 * q3 - az; + J_11or24 = _2q3; + J_12or23 = _2q4; + J_13or22 = _2q1; + J_14or21 = _2q2; + J_32 = 2.0f * J_14or21; + J_33 = 2.0f * J_11or24; + + // Compute the gradient (matrix multiplication) + hatDot1 = J_14or21 * f2 - J_11or24 * f1; + hatDot2 = J_12or23 * f1 + J_13or22 * f2 - J_32 * f3; + hatDot3 = J_12or23 * f2 - J_33 *f3 - J_13or22 * f1; + hatDot4 = J_14or21 * f1 + J_11or24 * f2; + + // Normalize the gradient + norm = sqrt(hatDot1 * hatDot1 + hatDot2 * hatDot2 + hatDot3 * hatDot3 + hatDot4 * hatDot4); + hatDot1 /= norm; + hatDot2 /= norm; + hatDot3 /= norm; + hatDot4 /= norm; + + // Compute estimated gyroscope biases + gerrx = _2q1 * hatDot2 - _2q2 * hatDot1 - _2q3 * hatDot4 + _2q4 * hatDot3; + gerry = _2q1 * hatDot3 + _2q2 * hatDot4 - _2q3 * hatDot1 - _2q4 * hatDot2; + gerrz = _2q1 * hatDot4 - _2q2 * hatDot3 + _2q3 * hatDot2 - _2q4 * hatDot1; + + // Compute and remove gyroscope biases + gbiasx += gerrx * deltat * zeta; + gbiasy += gerry * deltat * zeta; + gbiasz += gerrz * deltat * zeta; +// gx -= gbiasx; +// gy -= gbiasy; +// gz -= gbiasz; + + // Compute the quaternion derivative + qDot1 = -_halfq2 * gx - _halfq3 * gy - _halfq4 * gz; + qDot2 = _halfq1 * gx + _halfq3 * gz - _halfq4 * gy; + qDot3 = _halfq1 * gy - _halfq2 * gz + _halfq4 * gx; + qDot4 = _halfq1 * gz + _halfq2 * gy - _halfq3 * gx; + + // Compute then integrate estimated quaternion derivative + q1 += (qDot1 -(beta * hatDot1)) * deltat; + q2 += (qDot2 -(beta * hatDot2)) * deltat; + q3 += (qDot3 -(beta * hatDot3)) * deltat; + q4 += (qDot4 -(beta * hatDot4)) * deltat; + + // Normalize the quaternion + norm = sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4); // normalise quaternion + norm = 1.0f/norm; + q[0] = q1 * norm; + q[1] = q2 * norm; + q[2] = q3 * norm; + q[3] = q4 * norm; + +} \ No newline at end of file
diff -r e8c2301f7523 -r fd549671e512 main.cpp --- a/main.cpp Wed Feb 03 18:24:29 2016 +0000 +++ b/main.cpp Sun Mar 13 21:40:10 2016 +0000 @@ -1,29 +1,84 @@ #include "LSM9DS1.h" +#include "MadgwickUpdate.h" -DigitalOut myled(LED1); Serial pc(USBTX, USBRX); +Timer t; +int lastPrint = 0; +int printInterval = 500; + +RawSerial dev( p13, p14 ); + +int calibrate = 1; + +void dev_recv() +{ + while(dev.readable()) { + if ( dev.getc() == 'r' ){ + calibrate = 1; + } + } +} + int main() { - //LSM9DS1 lol(p9, p10, 0x6B, 0x1E); - LSM9DS1 lol(p9, p10, 0xD6, 0x3C); + + LSM9DS1 lol(p28, p27, 0xD6, 0x3C); + + t.start(); + + dev.baud(9600); + dev.attach(&dev_recv, Serial::RxIrq); + lol.begin(); if (!lol.begin()) { pc.printf("Failed to communicate with LSM9DS1.\n"); } - lol.calibrate(); + while(1) { - lol.readTemp(); - lol.readMag(); - lol.readGyro(); + + if( calibrate ){ + lol.calibrate(); + firstUpdate = t.read_us(); + lastUpdate = firstUpdate; + q[0] = 1.0f; q[1] = 0.0f; q[2] = 0.0f; q[3] = 0.0f; + calibrate = 0; + } - //pc.printf("%d %d %d %d %d %d %d %d %d\n\r", lol.calcGyro(lol.gx), lol.calcGyro(lol.gy), lol.calcGyro(lol.gz), lol.ax, lol.ay, lol.az, lol.mx, lol.my, lol.mz); - //pc.printf("%d %d %d\n\r", lol.calcGyro(lol.gx), lol.calcGyro(lol.gy), lol.calcGyro(lol.gz)); - pc.printf("gyro: %d %d %d\n\r", lol.gx, lol.gy, lol.gz); - pc.printf("accel: %d %d %d\n\r", lol.ax, lol.ay, lol.az); - pc.printf("mag: %d %d %d\n\n\r", lol.mx, lol.my, lol.mz); - myled = 1; - wait(2); - myled = 0; - wait(2); + if ( lol.accelAvailable() || lol.gyroAvailable() ) { + + lol.readAccel(); + lol.readGyro(); + + Now = t.read_us(); + deltat = (float)((Now - lastUpdate)/1000000.0f); + lastUpdate = Now; + + float ax = lol.calcAccel(lol.ax); + float ay = lol.calcAccel(lol.ay); + float az = lol.calcAccel(lol.az); + + float gx = lol.calcGyro(lol.gx); + float gy = lol.calcGyro(lol.gy); + float gz = lol.calcGyro(lol.gz); + + + // switch x and y to convert to right handed coordinate system + MadgwickQuaternionUpdate( ay, ax, az, gy*PI/180.0f, gx*PI/180.0f, gz*PI/180.0f ); + + int nowMs = t.read_ms(); + if( nowMs - lastPrint > printInterval ){ + lastPrint = nowMs; + pc.printf("gyro: %f %f %f\n\r", gx, gy, gz); + pc.printf("accel: %f %f %f\n\r", ax, ay, az); + pc.printf("quat: %f %f %f %f\n\r", q[0], q[1], q[2], q[3]); + char* str = (char*) &q; + int i = 0; + while (i < 16){ + dev.putc( str[i] ); + i += 1; + } + } + + } } }