20 volatile int8 *AccelCalPacketOn)
36 if (*((
uint32 *) pFlash++) == 0x12345678)
40 for (i =
CHX; i <=
CHZ; i++) pthisAccelCal->
fV[i] = *(pFlash++);
41 for (i =
CHX; i <=
CHZ; i++)
42 for (j =
CHX; j <=
CHZ; j++)
43 pthisAccelCal->
finvW[i][j] = *(pFlash++);
44 for (i =
CHX; i <=
CHZ; i++)
45 for (j =
CHX; j <=
CHZ; j++)
46 pthisAccelCal->
fR0[i][j] = *(pFlash++);
53 pthisAccelCal->
fV[
CHX] = pthisAccelCal->
fV[
CHY] = pthisAccelCal->
fV[
CHZ] = 0.0F;
78 for (i =
CHX; i <=
CHZ; i++) pthisAccelBuffer->
fSumGs[i] = 0.0F;
84 for (i =
CHX; i <=
CHZ; i++)
85 pthisAccelBuffer->
fSumGs[i] += pthisAccel->
fGs[i];
93 for (i =
CHX; i <=
CHZ; i++)
96 pthisAccelBuffer->
fSumGs[i] /
126 for (i =
CHX; i <=
CHZ; i++)
127 ftmp[i] = pthisAccel->
fGs[i] - pthisAccelCal->
fV[i];
130 for (i =
CHX; i <=
CHZ; i++)
132 pthisAccel->
fGc[i] = pthisAccelCal->
finvW[i][
CHX] *
141 for (i =
CHX; i <=
CHZ; i++) ftmp[i] = pthisAccel->
fGc[i];
142 for (i =
CHX; i <=
CHZ; i++)
144 pthisAccel->
fGc[i] = pthisAccelCal->
fR0[
CHX][i] *
146 pthisAccelCal->
fR0[
CHY][i] *
148 pthisAccelCal->
fR0[
CHZ][i] *
162 uint8_t iMeasurements;
169 if (pthisAccelBuffer->
iStoreFlags & (1 << i)) iMeasurements++;
173 if (iMeasurements >= 9)
178 else if (iMeasurements >= 6)
183 else if (iMeasurements >= 4)
194 for (i =
CHX; i <=
CHZ; i++)
195 fGc0[i] = pthisAccelBuffer->
fGsStored[0][i] - pthisAccelCal->
fV[i];
200 #if THISCOORDSYSTEM == NED 203 #if THISCOORDSYSTEM == ANDROID 206 #if THISCOORDSYSTEM == WIN8 231 for (i = 0; i < 4; i++)
233 pthisAccelCal->
fvecA[i] = 0.0F;
234 for (j = 0; j < 4; j++)
236 pthisAccelCal->
fmatA[i][j] = 0.0F;
255 pthisAccelCal->
fvecA[3] += ftmp;
279 pthisAccelCal->
fmatA[3][3] += 1.0F;
292 for (i = 0; i < 4; i++)
294 pfRows[i] = pthisAccelCal->
fmatA[i];
300 for (i = 0; i < 4; i++)
302 pthisAccelCal->
fvecB[i] = 0.0F;
303 for (j = 0; j < 4; j++)
305 pthisAccelCal->
fvecB[i] += pthisAccelCal->
fmatA[i][j] * pthisAccelCal->
fvecA[j];
315 ftmp = 1.0F / sqrtf(fabsf(pthisAccelCal->
fvecB[3] + pthisAccelCal->
fV[
CHX] *
316 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fV[
CHY] *
317 pthisAccelCal->
fV[
CHY] + pthisAccelCal->
fV[
CHZ] *
318 pthisAccelCal->
fV[
CHZ]));
342 for (i = 0; i < 7; i++)
343 for (j = i; j < 7; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
346 pthisAccelCal->
fvecA[6] = 1.0F;
363 for (m = 0; m < 7; m++)
364 for (n = m; n < 7; n++)
365 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
370 for (m = 1; m < 7; m++)
371 for (n = 0; n < m; n++)
372 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
376 pthisAccelCal->
fmatB, 7);
380 for (i = 1; i < 7; i++)
381 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j]) j = i;
384 det = pthisAccelCal->
fmatB[0][j] *
385 pthisAccelCal->
fmatB[1][j] *
386 pthisAccelCal->
fmatB[2][j];
389 for (i = 0; i < 7; i++)
391 pthisAccelCal->
fmatB[i][j] = -pthisAccelCal->
fmatB[i][j];
400 pthisAccelCal->
fV[
CHX] = -0.5F *
401 pthisAccelCal->
fmatB[3][j] /
402 pthisAccelCal->
fmatB[0][j];
403 pthisAccelCal->
fV[
CHY] = -0.5F *
404 pthisAccelCal->
fmatB[4][j] /
405 pthisAccelCal->
fmatB[1][j];
406 pthisAccelCal->
fV[
CHZ] = -0.5F *
407 pthisAccelCal->
fmatB[5][j] /
408 pthisAccelCal->
fmatB[2][j];
409 fg0 = sqrtf(fabsf(pthisAccelCal->
fmatB[0][j] * pthisAccelCal->
fV[
CHX] *
410 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fmatB[1][j] *
411 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] +
412 pthisAccelCal->
fmatB[2][j] * pthisAccelCal->
fV[
CHZ] *
413 pthisAccelCal->
fV[
CHZ] - pthisAccelCal->
fmatB[6][j]));
439 for (i = 0; i < 10; i++)
440 for (j = i; j < 10; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
443 pthisAccelCal->
fvecA[9] = 1.0F;
455 pthisAccelCal->
fvecA[0] = pthisAccelCal->
fvecA[6] * pthisAccelCal->
fvecA[6];
456 pthisAccelCal->
fvecA[1] = 2.0F *
457 pthisAccelCal->
fvecA[6] *
458 pthisAccelCal->
fvecA[7];
459 pthisAccelCal->
fvecA[2] = 2.0F *
460 pthisAccelCal->
fvecA[6] *
461 pthisAccelCal->
fvecA[8];
462 pthisAccelCal->
fvecA[3] = pthisAccelCal->
fvecA[7] * pthisAccelCal->
fvecA[7];
463 pthisAccelCal->
fvecA[4] = 2.0F *
464 pthisAccelCal->
fvecA[7] *
465 pthisAccelCal->
fvecA[8];
466 pthisAccelCal->
fvecA[5] = pthisAccelCal->
fvecA[8] * pthisAccelCal->
fvecA[8];
469 for (m = 0; m < 10; m++)
471 for (n = m; n < 10; n++)
473 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
480 for (m = 1; m < 10; m++)
481 for (n = 0; n < m; n++)
482 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
486 pthisAccelCal->
fmatB, 10);
490 for (i = 1; i < 10; i++)
492 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j])
498 pthisAccelCal->
fA[0][0] = pthisAccelCal->
fmatB[0][j];
499 pthisAccelCal->
fA[0][1] = pthisAccelCal->
fA[1][0] = pthisAccelCal->
fmatB[1][j];
500 pthisAccelCal->
fA[0][2] = pthisAccelCal->
fA[2][0] = pthisAccelCal->
fmatB[2][j];
501 pthisAccelCal->
fA[1][1] = pthisAccelCal->
fmatB[3][j];
502 pthisAccelCal->
fA[1][2] = pthisAccelCal->
fA[2][1] = pthisAccelCal->
fmatB[4][j];
503 pthisAccelCal->
fA[2][2] = pthisAccelCal->
fmatB[5][j];
510 pthisAccelCal->
fmatB[6][j] = -pthisAccelCal->
fmatB[6][j];
511 pthisAccelCal->
fmatB[7][j] = -pthisAccelCal->
fmatB[7][j];
512 pthisAccelCal->
fmatB[8][j] = -pthisAccelCal->
fmatB[8][j];
513 pthisAccelCal->
fmatB[9][j] = -pthisAccelCal->
fmatB[9][j];
521 for (l =
CHX; l <=
CHZ; l++)
523 pthisAccelCal->
fV[l] = 0.0F;
524 for (m =
CHX; m <=
CHZ; m++)
526 pthisAccelCal->
fV[l] += pthisAccelCal->
finvA[l][m] * pthisAccelCal->
fmatB[m + 6][j];
529 pthisAccelCal->
fV[l] *= -0.5F;
533 fg0 = sqrtf(fabsf(pthisAccelCal->
fA[0][0] * pthisAccelCal->
fV[
CHX] *
534 pthisAccelCal->
fV[
CHX] + 2.0F * pthisAccelCal->
fA[0][1] *
535 pthisAccelCal->
fV[
CHX] * pthisAccelCal->
fV[
CHY] + 2.0F *
536 pthisAccelCal->
fA[0][2] * pthisAccelCal->
fV[
CHX] *
537 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[1][1] *
538 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] + 2.0F *
539 pthisAccelCal->
fA[1][2] * pthisAccelCal->
fV[
CHY] *
540 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[2][2] *
541 pthisAccelCal->
fV[
CHZ] * pthisAccelCal->
fV[
CHZ] -
542 pthisAccelCal->
fmatB[9][j]));
547 for (i = 0; i < 3; i++)
548 for (j = 0; j < 3; j++)
549 pthisAccelCal->
fmatA[i][j] = pthisAccelCal->
fA[i][j];
551 pthisAccelCal->
fmatB, 3);
554 for (j = 0; j < 3; j++)
556 ftmp = sqrtf(sqrtf(fabsf(pthisAccelCal->
fvecA[j])));
557 for (i = 0; i < 3; i++)
559 pthisAccelCal->
fmatB[i][j] *= ftmp;
566 for (i = 0; i < 3; i++)
569 for (j = i; j < 3; j++)
571 pthisAccelCal->
finvW[i][j] = 0.0F;
574 for (k = 0; k < 3; k++)
576 pthisAccelCal->
finvW[i][j] += pthisAccelCal->
fmatB[i][k] * pthisAccelCal->
fmatB[j][k];
580 pthisAccelCal->
finvW[j][i] = pthisAccelCal->
finvW[i][j];
585 for (i =
CHX; i <=
CHZ; i++)
587 for (j =
CHX; j <=
CHZ; j++)
589 pthisAccelCal->
finvW[i][j] /= fg0;
void fRunAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel)
function runs the precision accelerometer calibration
float fvecA[10]
scratch 10x1 vector used by calibration algorithms
float fV[3]
offset vector (g)
int16_t iGc[3]
averaged precision calibrated measurement (counts)
void fComputeAccelCalibration7(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 7 element calibration from the available measurements
void f3x3matrixAeqScalar(float A[][3], float Scalar)
function sets every entry in the 3x3 matrix A to a constant scalar
float fGs[3]
averaged measurement (g)
int16_t iStoreCounter
number of remaining iterations at FUSION_HZ to average measurement
#define CALIBRATION_NVM_ADDR
start of final 4K (sector size) of 1M flash
void f3DOFTiltAndroid(float fR[][3], float fGc[])
Android accelerometer 3DOF tilt function computing, rotation matrix fR.
int16_t iCountsPerg
counts per g
void fVeq3x3AxV(float V[3], float A[][3])
function multiplies the 3x1 vector V by a 3x3 matrix A
void f3x3matrixAeqMinusA(float A[][3])
function negates all elements of 3x3 matrix A
void fmatrixAeqInvA(float *A[], int8 iColInd[], int8 iRowInd[], int8 iPivot[], int8 isize, int8 *pierror)
void f3DOFTiltWin8(float fR[][3], float fGc[])
Windows 8 accelerometer 3DOF tilt function computing, rotation matrix fR.
#define ACCEL_CAL_AVERAGING_SECS
calibration constants
#define CHZ
Used to access Z-channel entries in various data data structures.
void fEigenCompute10(float A[][10], float eigval[], float eigvec[][10], int8 n)
void fComputeAccelCalibration4(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 4 element calibration from the available measurements
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
#define CHY
Used to access Y-channel entries in various data data structures.
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
precision accelerometer calibration structure
The sensor_fusion.h file implements the top level programming interface.
float finvA[3][3]
inverse of the ellipsoid matrix A
int16_t iStoreFlags
denotes which measurements are present
float fmatB[10][10]
scratch 10x10 matrix used by calibration algorithms
float fvecB[4]
scratch 4x1 vector used by calibration algorithms
float fA[3][3]
ellipsoid matrix A
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
float fR0[3][3]
forward rotation matrix for measurement 0
accelerometer measurement buffer
void f3DOFTiltNED(float fR[][3], float fGc[])
Aerospace NED accelerometer 3DOF tilt function, computing rotation matrix fR.
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
void fComputeAccelCalibration10(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 10 element calibration from the available measurements
float fGsStored[MAX_ACCEL_CAL_ORIENTATIONS][3]
uncalibrated accelerometer measurements (g)
void fUpdateAccelBuffer(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel, volatile int8 *AccelCalPacketOn)
Update the buffer used to store samples used for accelerometer calibration.
#define CHX
Used to access X-channel entries in various data data structures.
float fSumGs[3]
averaging sum for current storage location
float fmatA[10][10]
scratch 10x10 matrix used by calibration algorithms
float f3x3matrixDetA(float A[][3])
function calculates the determinant of a 3x3 matrix
float fGc[3]
averaged precision calibrated measurement (g)
int16_t iStoreLocation
-1 for none, 0 to 11 for the 12 storage locations
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
#define MAX_ACCEL_CAL_ORIENTATIONS
number of stored precision accelerometer measurements
float finvW[3][3]
inverse gain matrix
Lower level sensor fusion interface.
void f3x3matrixAeqInvSymB(float A[][3], float B[][3])