46 volatile int8 *AccelCalPacketOn)
62 if (*((
uint32 *) pFlash++) == 0x12345678)
66 for (i =
CHX; i <=
CHZ; i++) pthisAccelCal->
fV[i] = *(pFlash++);
67 for (i =
CHX; i <=
CHZ; i++)
68 for (j =
CHX; j <=
CHZ; j++)
69 pthisAccelCal->
finvW[i][j] = *(pFlash++);
70 for (i =
CHX; i <=
CHZ; i++)
71 for (j =
CHX; j <=
CHZ; j++)
72 pthisAccelCal->
fR0[i][j] = *(pFlash++);
79 pthisAccelCal->
fV[
CHX] = pthisAccelCal->
fV[
CHY] = pthisAccelCal->
fV[
CHZ] = 0.0F;
104 for (i =
CHX; i <=
CHZ; i++) pthisAccelBuffer->
fSumGs[i] = 0.0F;
110 for (i =
CHX; i <=
CHZ; i++)
111 pthisAccelBuffer->
fSumGs[i] += pthisAccel->
fGs[i];
119 for (i =
CHX; i <=
CHZ; i++)
122 pthisAccelBuffer->
fSumGs[i] /
152 for (i =
CHX; i <=
CHZ; i++)
153 ftmp[i] = pthisAccel->
fGs[i] - pthisAccelCal->
fV[i];
156 for (i =
CHX; i <=
CHZ; i++)
158 pthisAccel->
fGc[i] = pthisAccelCal->
finvW[i][
CHX] *
167 for (i =
CHX; i <=
CHZ; i++) ftmp[i] = pthisAccel->
fGc[i];
168 for (i =
CHX; i <=
CHZ; i++)
170 pthisAccel->
fGc[i] = pthisAccelCal->
fR0[
CHX][i] *
172 pthisAccelCal->
fR0[
CHY][i] *
174 pthisAccelCal->
fR0[
CHZ][i] *
188 uint8_t iMeasurements;
195 if (pthisAccelBuffer->
iStoreFlags & (1 << i)) iMeasurements++;
199 if (iMeasurements >= 9)
204 else if (iMeasurements >= 6)
209 else if (iMeasurements >= 4)
220 for (i =
CHX; i <=
CHZ; i++)
221 fGc0[i] = pthisAccelBuffer->
fGsStored[0][i] - pthisAccelCal->
fV[i];
226 #if THISCOORDSYSTEM == NED 229 #if THISCOORDSYSTEM == ANDROID 232 #if THISCOORDSYSTEM == WIN8 257 for (i = 0; i < 4; i++)
259 pthisAccelCal->
fvecA[i] = 0.0F;
260 for (j = 0; j < 4; j++)
262 pthisAccelCal->
fmatA[i][j] = 0.0F;
281 pthisAccelCal->
fvecA[3] += ftmp;
305 pthisAccelCal->
fmatA[3][3] += 1.0F;
318 for (i = 0; i < 4; i++)
320 pfRows[i] = pthisAccelCal->
fmatA[i];
326 for (i = 0; i < 4; i++)
328 pthisAccelCal->
fvecB[i] = 0.0F;
329 for (j = 0; j < 4; j++)
331 pthisAccelCal->
fvecB[i] += pthisAccelCal->
fmatA[i][j] * pthisAccelCal->
fvecA[j];
341 ftmp = 1.0F / sqrtf(fabsf(pthisAccelCal->
fvecB[3] + pthisAccelCal->
fV[
CHX] *
342 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fV[
CHY] *
343 pthisAccelCal->
fV[
CHY] + pthisAccelCal->
fV[
CHZ] *
344 pthisAccelCal->
fV[
CHZ]));
368 for (i = 0; i < 7; i++)
369 for (j = i; j < 7; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
372 pthisAccelCal->
fvecA[6] = 1.0F;
389 for (m = 0; m < 7; m++)
390 for (n = m; n < 7; n++)
391 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
396 for (m = 1; m < 7; m++)
397 for (n = 0; n < m; n++)
398 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
402 pthisAccelCal->
fmatB, 7);
406 for (i = 1; i < 7; i++)
407 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j]) j = i;
410 det = pthisAccelCal->
fmatB[0][j] *
411 pthisAccelCal->
fmatB[1][j] *
412 pthisAccelCal->
fmatB[2][j];
415 for (i = 0; i < 7; i++)
417 pthisAccelCal->
fmatB[i][j] = -pthisAccelCal->
fmatB[i][j];
426 pthisAccelCal->
fV[
CHX] = -0.5F *
427 pthisAccelCal->
fmatB[3][j] /
428 pthisAccelCal->
fmatB[0][j];
429 pthisAccelCal->
fV[
CHY] = -0.5F *
430 pthisAccelCal->
fmatB[4][j] /
431 pthisAccelCal->
fmatB[1][j];
432 pthisAccelCal->
fV[
CHZ] = -0.5F *
433 pthisAccelCal->
fmatB[5][j] /
434 pthisAccelCal->
fmatB[2][j];
435 fg0 = sqrtf(fabsf(pthisAccelCal->
fmatB[0][j] * pthisAccelCal->
fV[
CHX] *
436 pthisAccelCal->
fV[
CHX] + pthisAccelCal->
fmatB[1][j] *
437 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] +
438 pthisAccelCal->
fmatB[2][j] * pthisAccelCal->
fV[
CHZ] *
439 pthisAccelCal->
fV[
CHZ] - pthisAccelCal->
fmatB[6][j]));
465 for (i = 0; i < 10; i++)
466 for (j = i; j < 10; j++) pthisAccelCal->
fmatA[i][j] = 0.0F;
469 pthisAccelCal->
fvecA[9] = 1.0F;
481 pthisAccelCal->
fvecA[0] = pthisAccelCal->
fvecA[6] * pthisAccelCal->
fvecA[6];
482 pthisAccelCal->
fvecA[1] = 2.0F *
483 pthisAccelCal->
fvecA[6] *
484 pthisAccelCal->
fvecA[7];
485 pthisAccelCal->
fvecA[2] = 2.0F *
486 pthisAccelCal->
fvecA[6] *
487 pthisAccelCal->
fvecA[8];
488 pthisAccelCal->
fvecA[3] = pthisAccelCal->
fvecA[7] * pthisAccelCal->
fvecA[7];
489 pthisAccelCal->
fvecA[4] = 2.0F *
490 pthisAccelCal->
fvecA[7] *
491 pthisAccelCal->
fvecA[8];
492 pthisAccelCal->
fvecA[5] = pthisAccelCal->
fvecA[8] * pthisAccelCal->
fvecA[8];
495 for (m = 0; m < 10; m++)
497 for (n = m; n < 10; n++)
499 pthisAccelCal->
fmatA[m][n] += pthisAccelCal->
fvecA[m] * pthisAccelCal->
fvecA[n];
506 for (m = 1; m < 10; m++)
507 for (n = 0; n < m; n++)
508 pthisAccelCal->
fmatA[m][n] = pthisAccelCal->
fmatA[n][m];
512 pthisAccelCal->
fmatB, 10);
516 for (i = 1; i < 10; i++)
518 if (pthisAccelCal->
fvecA[i] < pthisAccelCal->
fvecA[j])
524 pthisAccelCal->
fA[0][0] = pthisAccelCal->
fmatB[0][j];
525 pthisAccelCal->
fA[0][1] = pthisAccelCal->
fA[1][0] = pthisAccelCal->
fmatB[1][j];
526 pthisAccelCal->
fA[0][2] = pthisAccelCal->
fA[2][0] = pthisAccelCal->
fmatB[2][j];
527 pthisAccelCal->
fA[1][1] = pthisAccelCal->
fmatB[3][j];
528 pthisAccelCal->
fA[1][2] = pthisAccelCal->
fA[2][1] = pthisAccelCal->
fmatB[4][j];
529 pthisAccelCal->
fA[2][2] = pthisAccelCal->
fmatB[5][j];
536 pthisAccelCal->
fmatB[6][j] = -pthisAccelCal->
fmatB[6][j];
537 pthisAccelCal->
fmatB[7][j] = -pthisAccelCal->
fmatB[7][j];
538 pthisAccelCal->
fmatB[8][j] = -pthisAccelCal->
fmatB[8][j];
539 pthisAccelCal->
fmatB[9][j] = -pthisAccelCal->
fmatB[9][j];
547 for (l =
CHX; l <=
CHZ; l++)
549 pthisAccelCal->
fV[l] = 0.0F;
550 for (m =
CHX; m <=
CHZ; m++)
552 pthisAccelCal->
fV[l] += pthisAccelCal->
finvA[l][m] * pthisAccelCal->
fmatB[m + 6][j];
555 pthisAccelCal->
fV[l] *= -0.5F;
559 fg0 = sqrtf(fabsf(pthisAccelCal->
fA[0][0] * pthisAccelCal->
fV[
CHX] *
560 pthisAccelCal->
fV[
CHX] + 2.0F * pthisAccelCal->
fA[0][1] *
561 pthisAccelCal->
fV[
CHX] * pthisAccelCal->
fV[
CHY] + 2.0F *
562 pthisAccelCal->
fA[0][2] * pthisAccelCal->
fV[
CHX] *
563 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[1][1] *
564 pthisAccelCal->
fV[
CHY] * pthisAccelCal->
fV[
CHY] + 2.0F *
565 pthisAccelCal->
fA[1][2] * pthisAccelCal->
fV[
CHY] *
566 pthisAccelCal->
fV[
CHZ] + pthisAccelCal->
fA[2][2] *
567 pthisAccelCal->
fV[
CHZ] * pthisAccelCal->
fV[
CHZ] -
568 pthisAccelCal->
fmatB[9][j]));
573 for (i = 0; i < 3; i++)
574 for (j = 0; j < 3; j++)
575 pthisAccelCal->
fmatA[i][j] = pthisAccelCal->
fA[i][j];
577 pthisAccelCal->
fmatB, 3);
580 for (j = 0; j < 3; j++)
582 ftmp = sqrtf(sqrtf(fabsf(pthisAccelCal->
fvecA[j])));
583 for (i = 0; i < 3; i++)
585 pthisAccelCal->
fmatB[i][j] *= ftmp;
592 for (i = 0; i < 3; i++)
595 for (j = i; j < 3; j++)
597 pthisAccelCal->
finvW[i][j] = 0.0F;
600 for (k = 0; k < 3; k++)
602 pthisAccelCal->
finvW[i][j] += pthisAccelCal->
fmatB[i][k] * pthisAccelCal->
fmatB[j][k];
606 pthisAccelCal->
finvW[j][i] = pthisAccelCal->
finvW[i][j];
611 for (i =
CHX; i <=
CHZ; i++)
613 for (j =
CHX; j <=
CHZ; j++)
615 pthisAccelCal->
finvW[i][j] /= fg0;
float fGc[3]
averaged precision calibrated measurement (g)
float finvA[3][3]
inverse of the ellipsoid matrix A
int16_t iStoreLocation
-1 for none, 0 to 11 for the 12 storage locations
void fmatrixAeqInvA(float *A[], int8 iColInd[], int8 iRowInd[], int8 iPivot[], int8 isize, int8 *pierror)
float fvecB[4]
scratch 4x1 vector used by calibration algorithms
#define CHY
Used to access Y-channel entries in various data data structures.
void f3DOFTiltNED(float fR[][3], float fGc[])
Aerospace NED accelerometer 3DOF tilt function, computing rotation matrix fR.
#define CALIBRATION_NVM_ADDR
start of final 4K (sector size) of 1M flash
int16_t iGc[3]
averaged precision calibrated measurement (counts)
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
Lower level sensor fusion interface.
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.
void f3x3matrixAeqMinusA(float A[][3])
function negates all elements of 3x3 matrix A
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
int16_t iCountsPerg
counts per g
#define ACCEL_CAL_AVERAGING_SECS
calibration constants
void fComputeAccelCalibration7(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 7 element calibration from the available measurements
float f3x3matrixDetA(float A[][3])
function calculates the determinant of a 3x3 matrix
float fV[3]
offset vector (g)
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
float fSumGs[3]
averaging sum for current storage location
float fvecA[10]
scratch 10x1 vector used by calibration algorithms
float finvW[3][3]
inverse gain matrix
accelerometer measurement buffer
float fmatA[10][10]
scratch 10x10 matrix used by calibration algorithms
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 fComputeAccelCalibration10(struct AccelBuffer *pthisAccelBuffer, struct AccelCalibration *pthisAccelCal, struct AccelSensor *pthisAccel)
calculate the 10 element calibration from the available measurements
float fGs[3]
averaged measurement (g)
int16_t iStoreFlags
denotes which measurements are present
int16_t iStoreCounter
number of remaining iterations at FUSION_HZ to average measurement
The sensor_fusion.h file implements the top level programming interface.
void fVeq3x3AxV(float V[3], float A[][3])
function multiplies the 3x1 vector V by a 3x3 matrix A
#define CHZ
Used to access Z-channel entries in various data data structures.
void f3x3matrixAeqInvSymB(float A[][3], float B[][3])
precision accelerometer calibration structure
void f3DOFTiltAndroid(float fR[][3], float fGc[])
Android accelerometer 3DOF tilt function computing, rotation matrix fR.
#define CHX
Used to access X-channel entries in various data data structures.
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
void fRunAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel)
function runs the precision accelerometer calibration
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
#define MAX_ACCEL_CAL_ORIENTATIONS
number of stored precision accelerometer measurements
float fGsStored[MAX_ACCEL_CAL_ORIENTATIONS][3]
uncalibrated accelerometer measurements (g)
float fmatB[10][10]
scratch 10x10 matrix used by calibration algorithms
void f3x3matrixAeqScalar(float A[][3], float Scalar)
function sets every entry in the 3x3 matrix A to a constant scalar
void f3DOFTiltWin8(float fR[][3], float fGc[])
Windows 8 accelerometer 3DOF tilt function computing, rotation matrix fR.
float fA[3][3]
ellipsoid matrix A
float fR0[3][3]
forward rotation matrix for measurement 0