49 if (GetMagCalibrationFromNVM(cal_vals))
55 for (i =
CHX; i <=
CHZ; i++) pthisMagCal->
fV[i] = *(pFlash++);
56 for (i =
CHX; i <=
CHZ; i++)
57 for (j =
CHX; j <=
CHZ; j++) pthisMagCal->
finvW[i][j] = *(pFlash++);
58 pthisMagCal->
fB = *(pFlash++);
59 pthisMagCal->
fBSq = *(pFlash++);
68 pthisMagCal->
fV[
CHX] = pthisMagCal->
fV[
CHY] = pthisMagCal->
fV[
CHZ] = 0.0F;
107 if (pthisMag->
iBc[
CHZ] == 0)
return;
108 itanj = (100 * (int32_t) pthisMag->
iBc[
CHX]) / ((int32_t) pthisMag->
iBc[
CHZ]);
109 itank = (100 * (int32_t) pthisMag->
iBc[
CHY]) / ((int32_t) pthisMag->
iBc[
CHZ]);
124 (pthisMagBuffer->
index[j][k] != -1))
127 for (i =
CHX; i <=
CHZ; i++)
129 pthisMagBuffer->
iBs[i][j][k] = pthisMag->
iBs[i];
132 pthisMagBuffer->
index[j][k] = loopcounter;
139 (pthisMagBuffer->
index[j][k] == -1))
142 for (i =
CHX; i <=
CHZ; i++)
144 pthisMagBuffer->
iBs[i][j][k] = pthisMag->
iBs[i];
147 pthisMagBuffer->
index[j][k] = loopcounter;
157 if (pthisMagBuffer->
index[j][k] < i)
160 if (pthisMagBuffer->
index[j][k] != -1)
167 i = pthisMagBuffer->
index[l][m];
174 pthisMagBuffer->
index[l][m] = -1;
180 (pthisMagBuffer->
index[j][k] == -1))
183 for (i =
CHX; i <=
CHZ; i++)
185 pthisMagBuffer->
iBs[i][j][k] = pthisMag->
iBs[i];
188 pthisMagBuffer->
index[j][k] = loopcounter;
196 (pthisMagBuffer->
index[j][k] != -1))
200 for (i =
CHX; i <=
CHZ; i++)
202 idelta += abs((int32_t) pthisMag->
iBs[i] -
203 (int32_t) pthisMagBuffer->
iBs[i][j][k]);
210 for (i =
CHX; i <=
CHZ; i++)
212 pthisMagBuffer->
iBs[i][j][k] = pthisMag->
iBs[i];
215 pthisMagBuffer->
index[j][k] = loopcounter;
234 if (pthisMagBuffer->
index[j][k] != -1)
238 for (i =
CHX; i <=
CHZ; i++)
240 idelta += abs((int32_t) pthisMag->
iBs[i] -
241 (int32_t) pthisMagBuffer->
iBs[i][j][k]);
268 for (i =
CHX; i <=
CHZ; i++)
270 pthisMagBuffer->
iBs[i][l][m] = pthisMag->
iBs[i];
273 pthisMagBuffer->
index[l][m] = loopcounter;
293 for (i =
CHX; i <=
CHZ; i++)
295 ftmp[i] = pthisMag->
fBs[i] - pthisMagCal->
fV[i];
299 for (i =
CHX; i <=
CHZ; i++)
353 struct MagSensor *pthisMag, int32_t loopcounter)
417 fUpdateMagCalibration4Slice(pthisMagCal, pthisMagBuffer, pthisMag);
421 fUpdateMagCalibration7Slice(pthisMagCal, pthisMagBuffer, pthisMag);
425 fUpdateMagCalibration10Slice(pthisMagCal, pthisMagBuffer, pthisMag);
447 pthisMagCal->
fB = pthisMagCal->
ftrB;
448 pthisMagCal->
fBSq = pthisMagCal->
fB * pthisMagCal->
fB;
449 for (i =
CHX; i <=
CHZ; i++)
451 pthisMagCal->
fV[i] = pthisMagCal->
ftrV[i];
452 for (j =
CHX; j <=
CHZ; j++)
463 pthisMagBuffer->
index[i][j] = -1;
482void fUpdateMagCalibration4Slice(
struct MagCalibration *pthisMagCal,
511 pthisMagCal->
fYTY = 0.0F;
512 for (i = 0; i < 4; i++)
514 pthisMagCal->
fvecA[i] = 0.0F;
515 for (j = i; j < 4; j++) pthisMagCal->
fmatA[i][j] = 0.0F;
520 for (i = 0; i < 3; i++) pthisMagCal->
iSumBs[i] = 0;
527 if (pthisMagBuffer->
index[i][j] != -1)
530 for (k = 0; k < 3; k++)
531 pthisMagCal->
iSumBs[k] += (int32_t) pthisMagBuffer->
iBs[k][i][j];
537 for (i = 0; i < 3; i++)
539 if (pthisMagCal->
iSumBs[i] >= 0)
568 int32_t iBsZeroMean[3];
574 if (pthisMagBuffer->
index[i][j] != -1)
577 for (k = 0; k < 3; k++)
578 iBsZeroMean[k] = (int32_t) pthisMagBuffer->
iBs[k][i][j] - (int32_t) pthisMagCal->
iMeanBs[k];
581 pthisMagCal->
fmatA[0][0] += (float) (iBsZeroMean[0] * iBsZeroMean[0]);
582 pthisMagCal->
fmatA[0][1] += (float) (iBsZeroMean[0] * iBsZeroMean[1]);
583 pthisMagCal->
fmatA[0][2] += (float) (iBsZeroMean[0] * iBsZeroMean[2]);
584 pthisMagCal->
fmatA[1][1] += (float) (iBsZeroMean[1] * iBsZeroMean[1]);
585 pthisMagCal->
fmatA[1][2] += (float) (iBsZeroMean[1] * iBsZeroMean[2]);
586 pthisMagCal->
fmatA[2][2] += (float) (iBsZeroMean[2] * iBsZeroMean[2]);
589 fBsZeroMeanSq = (float)
598 for (k = 0; k < 3; k++)
599 pthisMagCal->
fvecA[k] += (
float) iBsZeroMean[k] * fBsZeroMeanSq;
600 pthisMagCal->
fvecA[3] += fBsZeroMeanSq;
603 pthisMagCal->
fYTY += fBsZeroMeanSq * fBsZeroMeanSq;
624 for (i = 0; i < 4; i++)
626 for (j = 0; j <= i; j++)
627 pthisMagCal->
fmatB[i][j] = pthisMagCal->
fmatB[j][i] = pthisMagCal->
fmatA[i][j] = pthisMagCal->
fmatA[j][i];
631 for (i = 0; i < 4; i++) pfRows[i] = pthisMagCal->
fmatB[i];
649 for (i = 0; i < 4; i++)
651 pthisMagCal->
fvecB[i] = pthisMagCal->
fmatB[i][0] * pthisMagCal->
fvecA[0];
652 for (j = 1; j < 4; j++)
653 pthisMagCal->
fvecB[i] += pthisMagCal->
fmatB[i][j] * pthisMagCal->
fvecA[j];
658 for (i =
CHX; i <=
CHZ; i++)
659 pthisMagCal->
ftrV[i] = ftmp * pthisMagCal->
fvecB[i];
662 pthisMagCal->
ftrB = pthisMagCal->
fvecB[3] *
665 for (i =
CHX; i <=
CHZ; i++)
666 pthisMagCal->
ftrB += pthisMagCal->
ftrV[i] * pthisMagCal->
ftrV[i];
667 pthisMagCal->
ftrB = sqrtf(fabs(pthisMagCal->
ftrB));
671 for (i =
CHX; i <=
CHZ; i++)
672 pthisMagCal->
ftrV[i] += (
float) pthisMagCal->
iSumBs[i] * ftmp;
676 fE = pthisMagCal->
fvecB[0] * pthisMagCal->
fvecA[0];
677 for (i = 1; i < 4; i++)
678 fE += pthisMagCal->
fvecB[i] * pthisMagCal->
fvecA[i];
681 fE = pthisMagCal->
fYTY - 2.0F * fE;
684 for (i = 0; i < 4; i++)
686 pthisMagCal->
fvecA[i] = pthisMagCal->
fmatA[i][0] * pthisMagCal->
fvecB[0];
687 for (j = 1; j < 4; j++)
688 pthisMagCal->
fvecA[i] += pthisMagCal->
fmatA[i][j] * pthisMagCal->
fvecB[j];
692 for (i = 0; i < 4; i++)
693 fE += pthisMagCal->
fvecB[i] * pthisMagCal->
fvecA[i];
713void fUpdateMagCalibration7Slice(
struct MagCalibration *pthisMagCal,
723#define MATRIX_7_SIZE 7
739 for (i = 0; i < MATRIX_7_SIZE; i++)
740 for (j = i; j < MATRIX_7_SIZE; j++)
741 pthisMagCal->
fmatA[i][j] = 0.0F;
745 for (i = 0; i < 3; i++) pthisMagCal->
iSumBs[i] = 0;
750 if (pthisMagBuffer->
index[i][j] != -1)
753 for (k = 0; k < 3; k++)
754 pthisMagCal->
iSumBs[k] += (int32_t) pthisMagBuffer->
iBs[k][i][j];
760 for (i = 0; i < 3; i++)
762 if (pthisMagCal->
iSumBs[i] >= 0)
792 if (pthisMagBuffer->
index[i][j] != -1)
795 for (k = 0; k < 3; k++)
797 pthisMagCal->
fvecA[k + 3] = (float)
799 (int32_t) pthisMagBuffer->
iBs[k][i][j] -
800 (int32_t) pthisMagCal->
iMeanBs[k]
802 pthisMagCal->
fvecA[k] = pthisMagCal->
fvecA[k + 3] * pthisMagCal->
fvecA[k + 3];
807 for (k = 0; k < 3; k++)
808 pthisMagCal->
fmatA[k][6] += pthisMagCal->
fvecA[k];
811 for (k = 0; k < (MATRIX_7_SIZE - 1); k++)
813 for (l = k; l < (MATRIX_7_SIZE - 1); l++)
814 pthisMagCal->
fmatA[k][l] += pthisMagCal->
fvecA[k] * pthisMagCal->
fvecA[l];
827 pthisMagCal->
fmatA[MATRIX_7_SIZE - 1][MATRIX_7_SIZE - 1] = (float) pthisMagBuffer->
iMagBufferCount;
833 for (i = 1; i < MATRIX_7_SIZE; i++)
834 for (j = 0; j < i; j++)
835 pthisMagCal->
fmatA[i][j] = pthisMagCal->
fmatA[j][i];
838 for (i = 0; i < MATRIX_7_SIZE; i++)
840 for (j = 0; j < MATRIX_7_SIZE; j++)
841 pthisMagCal->
fmatB[i][j] = 0.0F;
842 pthisMagCal->
fmatB[i][i] = 1.0F;
843 pthisMagCal->
fvecA[i] = pthisMagCal->
fmatA[i][i];
891 if (fabsf(pthisMagCal->
fmatA[i][j]) > 0.0F)
892 fComputeEigSlice(pthisMagCal->
fmatA, pthisMagCal->
fmatB,
893 pthisMagCal->
fvecA, i, j, MATRIX_7_SIZE);
905 for (i = 0; i < MATRIX_7_SIZE; i++)
906 for (j = i + 1; j < MATRIX_7_SIZE; j++)
907 fresidue += fabsf(pthisMagCal->
fmatA[i][j]);
927 for (i = 1; i < MATRIX_7_SIZE; i++)
928 if (pthisMagCal->
fvecA[i] < pthisMagCal->
fvecA[imin]) imin = i;
933 fdetA = pthisMagCal->
fmatB[
CHX][imin] *
939 for (i = 0; i < MATRIX_7_SIZE; i++)
940 pthisMagCal->
fmatB[i][imin] = -pthisMagCal->
fmatB[i][imin];
946 for (i =
CHX; i <=
CHZ; i++)
947 pthisMagCal->
ftrV[i] = -0.5F *
948 pthisMagCal->
fmatB[i + 3][imin] /
949 pthisMagCal->
fmatB[i][imin];
952 ftmp = -pthisMagCal->
fmatB[6][imin];
953 for (i =
CHX; i <=
CHZ; i++)
954 ftmp += pthisMagCal->
fmatB[i][imin] *
955 pthisMagCal->
ftrV[i] *
956 pthisMagCal->
ftrV[i];
966 ftmp = powf(fabs(fdetA), -(
ONETHIRD));
967 for (i =
CHX; i <=
CHZ; i++)
969 pthisMagCal->
fA[i][i] = pthisMagCal->
fmatB[i][imin] * ftmp;
970 pthisMagCal->
ftrinvW[i][i] = sqrtf(fabsf(pthisMagCal->
fA[i][i]));
979 pthisMagCal->
ftrB *= sqrt(fabs(ftmp));
982 for (i =
CHX; i <=
CHZ; i++)
983 pthisMagCal->
ftrV[i] =
985 pthisMagCal->
ftrV[i] +
986 (
float) pthisMagCal->
iMeanBs[i]
1000void fUpdateMagCalibration10Slice(
struct MagCalibration *pthisMagCal,
1010#define MATRIX_10_SIZE 10
1026 for (i = 0; i < MATRIX_10_SIZE; i++)
1027 for (j = i; j < MATRIX_10_SIZE; j++)
1028 pthisMagCal->
fmatA[i][j] = 0.0F;
1032 for (i = 0; i < 3; i++) pthisMagCal->
iSumBs[i] = 0;
1037 if (pthisMagBuffer->
index[i][j] != -1)
1040 for (k = 0; k < 3; k++)
1041 pthisMagCal->
iSumBs[k] += (int32_t) pthisMagBuffer->
iBs[k][i][j];
1047 for (i = 0; i < 3; i++)
1049 if (pthisMagCal->
iSumBs[i] >= 0)
1080 if (pthisMagBuffer->
index[i][j] != -1)
1083 for (k = 0; k < 3; k++)
1084 pthisMagCal->
fvecA[k + 6] = (
float)
1086 (int32_t) pthisMagBuffer->
iBs[k][i][j] -
1087 (int32_t) pthisMagCal->
iMeanBs[k]
1091 pthisMagCal->
fvecA[0] = pthisMagCal->
fvecA[6] * pthisMagCal->
fvecA[6];
1092 pthisMagCal->
fvecA[1] = 2.0F *
1093 pthisMagCal->
fvecA[6] *
1094 pthisMagCal->
fvecA[7];
1095 pthisMagCal->
fvecA[2] = 2.0F *
1096 pthisMagCal->
fvecA[6] *
1097 pthisMagCal->
fvecA[8];
1098 pthisMagCal->
fvecA[3] = pthisMagCal->
fvecA[7] * pthisMagCal->
fvecA[7];
1099 pthisMagCal->
fvecA[4] = 2.0F *
1100 pthisMagCal->
fvecA[7] *
1101 pthisMagCal->
fvecA[8];
1102 pthisMagCal->
fvecA[5] = pthisMagCal->
fvecA[8] * pthisMagCal->
fvecA[8];
1106 for (k = 0; k < 6; k++)
1107 pthisMagCal->
fmatA[k][9] += pthisMagCal->
fvecA[k];
1110 for (k = 0; k < (MATRIX_10_SIZE - 1); k++)
1112 for (l = k; l < (MATRIX_10_SIZE - 1); l++)
1113 pthisMagCal->
fmatA[k][l] += pthisMagCal->
fvecA[k] * pthisMagCal->
fvecA[l];
1126 pthisMagCal->
fmatA[MATRIX_10_SIZE - 1][MATRIX_10_SIZE - 1] = (float) pthisMagBuffer->
iMagBufferCount;
1132 for (i = 1; i < MATRIX_10_SIZE; i++)
1133 for (j = 0; j < i; j++)
1134 pthisMagCal->
fmatA[i][j] = pthisMagCal->
fmatA[j][i];
1137 for (i = 0; i < MATRIX_10_SIZE; i++)
1139 for (j = 0; j < MATRIX_10_SIZE; j++)
1140 pthisMagCal->
fmatB[i][j] = 0.0F;
1141 pthisMagCal->
fmatB[i][i] = 1.0F;
1142 pthisMagCal->
fvecA[i] = pthisMagCal->
fmatA[i][i];
1205 if (fabsf(pthisMagCal->
fmatA[i][j]) > 0.0F)
1206 fComputeEigSlice(pthisMagCal->
fmatA, pthisMagCal->
fmatB,
1207 pthisMagCal->
fvecA, i, j, MATRIX_10_SIZE);
1219 for (i = 0; i < MATRIX_10_SIZE; i++)
1220 for (j = i + 1; j < MATRIX_10_SIZE; j++)
1221 fresidue += fabsf(pthisMagCal->
fmatA[i][j]);
1224 if (fresidue > 0.0F)
1241 for (i = 1; i < MATRIX_10_SIZE; i++)
1242 if (pthisMagCal->
fvecA[i] < pthisMagCal->
fvecA[imin]) imin = i;
1257 fdetA = fabs(fdetA);
1258 for (i = 0; i < MATRIX_10_SIZE; i++)
1259 pthisMagCal->
fmatB[i][imin] = -pthisMagCal->
fmatB[i][imin];
1266 for (i =
CHX; i <=
CHZ; i++)
1268 pthisMagCal->
ftrV[i] = pthisMagCal->
finvA[i][0] *
1269 pthisMagCal->
fmatB[6][imin] +
1270 pthisMagCal->
finvA[i][1] *
1271 pthisMagCal->
fmatB[7][imin] +
1272 pthisMagCal->
finvA[i][2] *
1273 pthisMagCal->
fmatB[8][imin];
1274 pthisMagCal->
ftrV[i] *= -0.5F;
1288 ftmp -= pthisMagCal->
fmatB[9][imin];
1289 ftmp += pthisMagCal->
fA[
CHX][
CHX] *
1292 ftmp += pthisMagCal->
fA[
CHY][
CHY] *
1295 ftmp += pthisMagCal->
fA[
CHZ][
CHZ] *
1298 pthisMagCal->
ftrB = sqrtf(fabsf(ftmp));
1302 pthisMagCal->
fvecA[imin] /
1304 )) / (pthisMagCal->
ftrB * pthisMagCal->
ftrB);
1310 for (i =
CHX; i <=
CHZ; i++)
1311 pthisMagCal->
ftrV[i] =
1313 pthisMagCal->
ftrV[i] +
1314 (
float) pthisMagCal->
iMeanBs[i]
1319 ftmp = powf(fabs(fdetA), -(
ONETHIRD));
1325 pthisMagCal->
ftrB *= sqrt(fabs(ftmp));
1330 for (i = 0; i < 3; i++)
1332 for (j = 0; j < 3; j++)
1334 pthisMagCal->
fmatA[i][j] = pthisMagCal->
fA[i][j];
1335 pthisMagCal->
fmatB[i][j] = 0.0F;
1338 pthisMagCal->
fmatB[i][i] = 1.0F;
1339 pthisMagCal->
fvecA[i] = pthisMagCal->
fmatA[i][i];
1371 if (fabsf(pthisMagCal->
fmatA[i][j]) > 0.0F)
1372 fComputeEigSlice(pthisMagCal->
fmatA, pthisMagCal->
fmatB,
1373 pthisMagCal->
fvecA, i, j, 3);
1385 fresidue = fabsf(pthisMagCal->
fmatA[0][1]) + fabsf(pthisMagCal->
fmatA[0][2]) + fabsf(pthisMagCal->
fmatA[1][2]);
1386 if (fresidue > 0.0F)
1399 for (j = 0; j < 3; j++)
1401 ftmp = sqrtf(sqrtf(fabsf(pthisMagCal->
fvecA[j])));
1402 for (i = 0; i < 3; i++)
1403 pthisMagCal->
fmatB[i][j] *= ftmp;
1409 for (i = 0; i < 3; i++)
1411 for (j = i; j < 3; j++)
1414 pthisMagCal->
fmatB[i][0] *
1415 pthisMagCal->
fmatB[j][0] +
1416 pthisMagCal->
fmatB[i][1] *
1417 pthisMagCal->
fmatB[j][1] +
1418 pthisMagCal->
fmatB[i][2] *
1419 pthisMagCal->
fmatB[j][2];
1463 for (i = 0; i < 4; i++)
1465 pthisMagCal->
fvecB[i] = 0.0F;
1466 for (j = i; j < 4; j++)
1468 pthisMagCal->
fmatA[i][j] = 0.0F;
1473 iOffset[
CHX] = iOffset[
CHY] = iOffset[
CHZ] = 0;
1481 if (pthisMagBuffer->
index[j][k] != -1)
1486 for (l =
CHX; l <=
CHZ; l++)
1488 iOffset[l] = pthisMagBuffer->
iBs[l][j][k];
1493 for (l =
CHX; l <=
CHZ; l++)
1495 pthisMagCal->
fvecA[l] = (float)
1497 (int32_t) pthisMagBuffer->
iBs[l][j][k] -
1498 (int32_t) iOffset[l]
1500 pthisMagCal->
fvecA[l + 3] = pthisMagCal->
fvecA[l] * pthisMagCal->
fvecA[l];
1504 fBs2 = pthisMagCal->
fvecA[3] +
1505 pthisMagCal->
fvecA[4] +
1506 pthisMagCal->
fvecA[5];
1509 fSumBs4 += fBs2 * fBs2;
1512 for (l =
CHX; l <=
CHZ; l++)
1514 pthisMagCal->
fvecB[l] += pthisMagCal->
fvecA[l] * fBs2;
1518 pthisMagCal->
fvecB[3] += fBs2;
1538 pthisMagCal->
fmatA[3][3] = (float) iCount;
1544 for (i = 0; i < 4; i++)
1546 for (j = i; j < 4; j++)
1548 pthisMagCal->
fmatB[i][j] = pthisMagCal->
fmatB[j][i] = pthisMagCal->
fmatA[j][i] = pthisMagCal->
fmatA[i][j];
1553 for (i = 0; i < 4; i++)
1555 pfRows[i] = pthisMagCal->
fmatB[i];
1561 for (i = 0; i < 4; i++)
1563 pthisMagCal->
fvecA[i] = 0.0F;
1564 for (k = 0; k < 4; k++)
1566 pthisMagCal->
fvecA[i] += pthisMagCal->
fmatB[i][k] * pthisMagCal->
fvecB[k];
1574 for (i = 0; i < 4; i++)
1576 fE += pthisMagCal->
fvecA[i] * pthisMagCal->
fvecB[i];
1579 fE = fSumBs4 - 2.0F * fE;
1582 for (i = 0; i < 4; i++)
1584 pthisMagCal->
fvecB[i] = 0.0F;
1585 for (k = 0; k < 4; k++)
1587 pthisMagCal->
fvecB[i] += pthisMagCal->
fmatA[i][k] * pthisMagCal->
fvecA[k];
1592 for (i = 0; i < 4; i++)
1594 fE += pthisMagCal->
fvecB[i] * pthisMagCal->
fvecA[i];
1598 for (l =
CHX; l <=
CHZ; l++)
1600 pthisMagCal->
ftrV[l] = 0.5F * pthisMagCal->
fvecA[l];
1613 for (l =
CHX; l <=
CHZ; l++)
1615 pthisMagCal->
ftrV[l] = pthisMagCal->
ftrV[l] *
1617 (float) iOffset[l] *
1648 iOffset[
CHX] = iOffset[
CHY] = iOffset[
CHZ] = 0;
1651 for (m = 0; m < 7; m++)
1653 for (n = m; n < 7; n++)
1655 pthisMagCal->
fmatA[m][n] = 0.0F;
1665 if (pthisMagBuffer->
index[j][k] != -1)
1670 for (l =
CHX; l <=
CHZ; l++)
1672 iOffset[l] = pthisMagBuffer->
iBs[l][j][k];
1677 for (l =
CHX; l <=
CHZ; l++)
1679 pthisMagCal->
fvecA[l + 3] = (float)
1681 (int32_t) pthisMagBuffer->
iBs[l][j][k] -
1682 (int32_t) iOffset[l]
1684 pthisMagCal->
fvecA[l] = pthisMagCal->
fvecA[l + 3] * pthisMagCal->
fvecA[l + 3];
1691 for (m = 0; m < 6; m++)
1693 pthisMagCal->
fmatA[m][6] += pthisMagCal->
fvecA[m];
1697 for (m = 0; m < 6; m++)
1699 for (n = m; n < 6; n++)
1701 pthisMagCal->
fmatA[m][n] += pthisMagCal->
fvecA[m] * pthisMagCal->
fvecA[n];
1712 pthisMagCal->
fmatA[6][6] = (float) iCount;
1718 for (m = 1; m < 7; m++)
1720 for (n = 0; n < m; n++)
1722 pthisMagCal->
fmatA[m][n] = pthisMagCal->
fmatA[n][m];
1732 for (i = 1; i < 7; i++)
1734 if (pthisMagCal->
fvecA[i] < pthisMagCal->
fvecA[j])
1744 for (l =
CHX; l <=
CHZ; l++)
1746 pthisMagCal->
fA[l][l] = pthisMagCal->
fmatB[l][j];
1747 det *= pthisMagCal->
fA[l][l];
1748 pthisMagCal->
ftrV[l] = -0.5F *
1749 pthisMagCal->
fmatB[l + 3][j] /
1750 pthisMagCal->
fA[l][l];
1757 pthisMagCal->
fmatB[6][j] = -pthisMagCal->
fmatB[6][j];
1762 ftmp = -pthisMagCal->
fmatB[6][j];
1763 for (l =
CHX; l <=
CHZ; l++)
1765 ftmp += pthisMagCal->
fA[l][l] *
1766 pthisMagCal->
ftrV[l] *
1767 pthisMagCal->
ftrV[l];
1778 for (l =
CHX; l <=
CHZ; l++)
1780 pthisMagCal->
ftrinvW[l][l] = sqrtf(fabsf(pthisMagCal->
fA[l][l]));
1781 pthisMagCal->
ftrV[l] = pthisMagCal->
ftrV[l] *
1783 (float) iOffset[l] *
1811 iOffset[
CHX] = iOffset[
CHY] = iOffset[
CHZ] = 0;
1814 for (m = 0; m < 10; m++)
1816 for (n = m; n < 10; n++)
1818 pthisMagCal->
fmatA[m][n] = 0.0F;
1828 if (pthisMagBuffer->
index[j][k] != -1)
1833 for (l =
CHX; l <=
CHZ; l++)
1835 iOffset[l] = pthisMagBuffer->
iBs[l][j][k];
1840 for (l =
CHX; l <=
CHZ; l++)
1842 pthisMagCal->
fvecA[l + 6] = (float)
1844 (int32_t) pthisMagBuffer->
iBs[l][j][k] -
1845 (int32_t) iOffset[l]
1850 pthisMagCal->
fvecA[0] = pthisMagCal->
fvecA[6] * pthisMagCal->
fvecA[6];
1851 pthisMagCal->
fvecA[1] = 2.0F *
1852 pthisMagCal->
fvecA[6] *
1853 pthisMagCal->
fvecA[7];
1854 pthisMagCal->
fvecA[2] = 2.0F *
1855 pthisMagCal->
fvecA[6] *
1856 pthisMagCal->
fvecA[8];
1857 pthisMagCal->
fvecA[3] = pthisMagCal->
fvecA[7] * pthisMagCal->
fvecA[7];
1858 pthisMagCal->
fvecA[4] = 2.0F *
1859 pthisMagCal->
fvecA[7] *
1860 pthisMagCal->
fvecA[8];
1861 pthisMagCal->
fvecA[5] = pthisMagCal->
fvecA[8] * pthisMagCal->
fvecA[8];
1866 for (m = 0; m < 9; m++)
1868 pthisMagCal->
fmatA[m][9] += pthisMagCal->
fvecA[m];
1872 for (m = 0; m < 9; m++)
1874 for (n = m; n < 9; n++)
1876 pthisMagCal->
fmatA[m][n] += pthisMagCal->
fvecA[m] * pthisMagCal->
fvecA[n];
1887 pthisMagCal->
fmatA[9][9] = (float) iCount;
1893 for (m = 1; m < 10; m++)
1895 for (n = 0; n < m; n++)
1897 pthisMagCal->
fmatA[m][n] = pthisMagCal->
fmatA[n][m];
1907 for (i = 1; i < 10; i++)
1909 if (pthisMagCal->
fvecA[i] < pthisMagCal->
fvecA[j])
1915 pthisMagCal->
fA[0][0] = pthisMagCal->
fmatB[0][j];
1916 pthisMagCal->
fA[0][1] = pthisMagCal->
fA[1][0] = pthisMagCal->
fmatB[1][j];
1917 pthisMagCal->
fA[0][2] = pthisMagCal->
fA[2][0] = pthisMagCal->
fmatB[2][j];
1918 pthisMagCal->
fA[1][1] = pthisMagCal->
fmatB[3][j];
1919 pthisMagCal->
fA[1][2] = pthisMagCal->
fA[2][1] = pthisMagCal->
fmatB[4][j];
1920 pthisMagCal->
fA[2][2] = pthisMagCal->
fmatB[5][j];
1927 pthisMagCal->
fmatB[6][j] = -pthisMagCal->
fmatB[6][j];
1928 pthisMagCal->
fmatB[7][j] = -pthisMagCal->
fmatB[7][j];
1929 pthisMagCal->
fmatB[8][j] = -pthisMagCal->
fmatB[8][j];
1930 pthisMagCal->
fmatB[9][j] = -pthisMagCal->
fmatB[9][j];
1938 for (l =
CHX; l <=
CHZ; l++)
1940 pthisMagCal->
ftrV[l] = 0.0F;
1941 for (m =
CHX; m <=
CHZ; m++)
1943 pthisMagCal->
ftrV[l] += pthisMagCal->
finvA[l][m] * pthisMagCal->
fmatB[m + 6][j];
1946 pthisMagCal->
ftrV[l] *= -0.5F;
1950 pthisMagCal->
ftrB = sqrtf(fabsf(pthisMagCal->
fA[0][0] *
1952 2.0F * pthisMagCal->
fA[0][1] *
1954 2.0F * pthisMagCal->
fA[0][2] *
1956 pthisMagCal->
fA[1][1] * pthisMagCal->
ftrV[
CHY] *
1957 pthisMagCal->
ftrV[
CHY] + 2.0F *
1958 pthisMagCal->
fA[1][2] * pthisMagCal->
ftrV[
CHY] *
1959 pthisMagCal->
ftrV[
CHZ] + pthisMagCal->
fA[2][2] *
1961 pthisMagCal->
fmatB[9][j]));
1968 for (l =
CHX; l <=
CHZ; l++)
1970 pthisMagCal->
ftrV[l] = pthisMagCal->
ftrV[l] *
1972 (float) iOffset[l] *
1986 for (i = 0; i < 3; i++)
1988 for (j = 0; j < 3; j++)
1990 pthisMagCal->
fmatA[i][j] = pthisMagCal->
fA[i][j];
1998 for (j = 0; j < 3; j++)
2000 ftmp = sqrtf(sqrtf(fabsf(pthisMagCal->
fvecA[j])));
2001 for (i = 0; i < 3; i++)
2003 pthisMagCal->
fmatB[i][j] *= ftmp;
2010 for (i = 0; i < 3; i++)
2013 for (j = i; j < 3; j++)
2015 pthisMagCal->
ftrinvW[i][j] = 0.0F;
2018 for (k = 0; k < 3; k++)
2020 pthisMagCal->
ftrinvW[i][j] += pthisMagCal->
fmatB[i][k] * pthisMagCal->
fmatB[j][k];
#define FUSION_HZ
(int) rate of fusion algorithm execution
Provides functions to store calibration to NVM, which on ESP devices is provided by EEPROM.
void fRunMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32_t loopcounter)
Run the magnetic calibration. Calibration is done in time-slices, to avoid excessive CPU load during ...
Lower level magnetic calibration interface.
#define MAGBUFFSIZEX
x dimension in magnetometer buffer (14x28 equals 392 elements)
#define MAXMEASUREMENTS
maximum number of measurements used for calibration
#define MINMEASUREMENTS10CAL
minimum number of measurements for 10 element calibration
#define CAL_INTERVAL_SECS
300s or 5min interval for regular calibration checks
#define MINMEASUREMENTS7CAL
minimum number of measurements for 7 element calibration
#define DEFAULTB
default geomagnetic field (uT)
#define MINMEASUREMENTS4CAL
minimum number of measurements for 4 element calibration
#define MAGBUFFSIZEY
y dimension in magnetometer buffer (14x28 equals 392 elements)
#define MINBFITUT
minimum acceptable geomagnetic field B (uT) for valid calibration
#define MESHDELTACOUNTS
magnetic buffer mesh spacing in counts (here 5uT)
#define MAXBFITUT
maximum acceptable geomagnetic field B (uT) for valid calibration
#define FITERRORAGINGSECS
24 hours: time (s) for fit error to increase (age) by e=2.718
void fEigenCompute10(float A[][10], float eigval[], float eigvec[][10], int8_t n)
void f3x3matrixAeqAxScalar(float A[][3], float Scalar)
function multiplies all elements of 3x3 matrix A by the specified scalar
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
float f3x3matrixDetA(float A[][3])
function calculates the determinant of a 3x3 matrix
void f3x3matrixAeqMinusA(float A[][3])
function negates all elements of 3x3 matrix A
void f3x3matrixAeqInvSymB(float A[][3], float B[][3])
void fmatrixAeqInvA(float *A[], int8_t iColInd[], int8_t iRowInd[], int8_t iPivot[], int8_t isize, int8_t *pierror)
void f3x3matrixAeqScalar(float A[][3], float Scalar)
function sets every entry in the 3x3 matrix A to a constant scalar
The sensor_fusion.h file implements the top level programming interface.
#define ONESIXTH
one sixth
#define ONETHIRD
one third
#define CHX
Used to access X-channel entries in various data data structures.
#define PI
pi (it is also defined in Arduino.h)
#define CHY
Used to access Y-channel entries in various data data structures.
#define CHZ
Used to access Z-channel entries in various data data structures.
int16_t tanarray[MAGBUFFSIZEX - 1]
array of tangents of (100 * angle)
int32_t index[MAGBUFFSIZEX][MAGBUFFSIZEY]
array of time indices
int16_t iMagBufferCount
number of magnetometer readings
int16_t iBs[3][MAGBUFFSIZEX][MAGBUFFSIZEY]
uncalibrated magnetometer readings
Magnetic Calibration Structure.
float finvA[3][3]
inverse of ellipsoid matrix A
float ftrFitErrorpc
trial value of fit error %
float fB
current geomagnetic field magnitude (uT)
int8_t iInitiateMagCal
flag to start a new magnetic calibration
float fFitErrorpc
current fit error %
float fA[3][3]
ellipsoid matrix A
int8_t i4ElementSolverTried
flag to denote at least one attempt made with 4 element calibration
int8_t i10ElementSolverTried
flag to denote at least one attempt made with 10 element calibration
float ftrV[3]
trial value of hard iron offset z, y, z (uT)
float ftrB
trial value of geomagnetic field magnitude in uT
float fV[3]
current hard iron offset x, y, z, (uT)
float fvecA[10]
scratch 10x1 vector used by calibration algorithms
float fmatB[10][10]
scratch 10x10 float matrix used by calibration algorithms
float finvW[3][3]
current inverse soft iron matrix
int32_t iSumBs[3]
sum of measurements in buffer (counts)
float ftrinvW[3][3]
trial inverse soft iron matrix size
int32_t iMeanBs[3]
average magnetic measurement (counts)
int8_t i7ElementSolverTried
flag to denote at least one attempt made with 7 element calibration
int8_t iNewCalibrationAvailable
flag denoting that a new calibration has been computed
float fBSq
square of fB (uT^2)
float fYTY
Y^T.Y for 4 element calibration = (iB^2)^2.
int8_t iCalInProgress
flag denoting that a calibration is in progress
int32_t itimeslice
counter for tine slicing magnetic calibration calculations
int32_t iValidMagCal
solver used: 0 (no calibration) or 4, 7, 10 element
int8_t iMagBufferReadOnly
flag to denote that the magnetic measurement buffer is temporarily read only
float fvecB[4]
scratch 4x1 vector used by calibration algorithms
float fmatA[10][10]
scratch 10x10 float matrix used by calibration algorithms
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor.
int16_t iBc[3]
averaged calibrated measurement (counts)
float fCountsPeruT
counts per uT
float fuTPerCount
uT per count
float fBs[3]
averaged un-calibrated measurement (uT)
float fBc[3]
averaged calibrated measurement (uT)
int16_t iBs[3]
averaged uncalibrated measurement (counts)