40 sfg->SV_1DOF_P_BASIC.resetflag =
true;
43 sfg->SV_3DOF_B_BASIC.resetflag =
true;
46 sfg->SV_3DOF_G_BASIC.resetflag =
true;
49 sfg->SV_3DOF_Y_BASIC.resetflag =
true;
52 sfg->SV_6DOF_GB_BASIC.resetflag =
true;
55 sfg->SV_6DOF_GY_KALMAN.resetflag =
true;
58 sfg->SV_9DOF_GBY_KALMAN.resetflag =
true;
81 if (pthisSV_1DOF_P_BASIC)
83 SystickStartCount(&(pthisSV_1DOF_P_BASIC->
systick));
84 fRun_1DOF_P_BASIC(pthisSV_1DOF_P_BASIC, pthisPressure);
85 pthisSV_1DOF_P_BASIC->
systick = SystickElapsedMicros(pthisSV_1DOF_P_BASIC->
systick);
91 if (pthisSV_3DOF_G_BASIC)
93 SystickStartCount(&(pthisSV_3DOF_G_BASIC->
systick));
94 fRun_3DOF_G_BASIC(pthisSV_3DOF_G_BASIC, pthisAccel);
95 pthisSV_3DOF_G_BASIC->
systick = SystickElapsedMicros(pthisSV_3DOF_G_BASIC->
systick);
101 if (pthisSV_3DOF_B_BASIC)
103 SystickStartCount(&(pthisSV_3DOF_B_BASIC->
systick));
104 fRun_3DOF_B_BASIC(pthisSV_3DOF_B_BASIC, pthisMag);
105 pthisSV_3DOF_B_BASIC->
systick = SystickElapsedMicros(pthisSV_3DOF_B_BASIC->
systick);
111 if (pthisSV_3DOF_Y_BASIC)
113 SystickStartCount(&(pthisSV_3DOF_Y_BASIC->
systick));
114 fRun_3DOF_Y_BASIC(pthisSV_3DOF_Y_BASIC, pthisGyro);
115 pthisSV_3DOF_Y_BASIC->
systick = SystickElapsedMicros(pthisSV_3DOF_Y_BASIC->
systick);
121 if (pthisSV_6DOF_GB_BASIC)
123 SystickStartCount(&(pthisSV_6DOF_GB_BASIC->
systick));
124 fRun_6DOF_GB_BASIC(pthisSV_6DOF_GB_BASIC, pthisMag, pthisAccel);
125 pthisSV_6DOF_GB_BASIC->
systick = SystickElapsedMicros(pthisSV_6DOF_GB_BASIC->
systick);
131 if (pthisSV_6DOF_GY_KALMAN)
133 SystickStartCount(&(pthisSV_6DOF_GY_KALMAN->
systick));
134 fRun_6DOF_GY_KALMAN(pthisSV_6DOF_GY_KALMAN, pthisAccel, pthisGyro);
135 pthisSV_6DOF_GY_KALMAN->
systick = SystickElapsedMicros(pthisSV_6DOF_GY_KALMAN->
systick);
141 if (pthisSV_9DOF_GBY_KALMAN)
143 SystickStartCount(&(pthisSV_9DOF_GBY_KALMAN->
systick));
144 fRun_9DOF_GBY_KALMAN(pthisSV_9DOF_GBY_KALMAN, pthisAccel, pthisMag,
145 pthisGyro, pthisMagCal);
146 pthisSV_9DOF_GBY_KALMAN->
systick = SystickElapsedMicros(pthisSV_9DOF_GBY_KALMAN->
systick);
162 if (flpftimesecs > pthisSV->
fdeltat)
165 pthisSV->
flpf = 1.0F;
168 pthisSV->
fLPH = pthisPressure->
fH;
169 pthisSV->
fLPT = pthisPressure->
fT;
178 struct AccelSensor *pthisAccel,
float flpftimesecs)
184 if (flpftimesecs > pthisSV->
fdeltat)
187 pthisSV->
flpf = 1.0F;
190#if THISCOORDSYSTEM == NED
192#elif THISCOORDSYSTEM == ANDROID
206 struct MagSensor *pthisMag,
float flpftimesecs)
212 if (flpftimesecs > pthisSV->
fdeltat)
215 pthisSV->
flpf = 1.0F;
218#if THISCOORDSYSTEM == NED
220#elif THISCOORDSYSTEM == ANDROID
250 struct MagSensor *pthisMag,
float flpftimesecs)
258 if (flpftimesecs > pthisSV->
fdeltat)
261 pthisSV->
flpf = 1.0F;
264#if THISCOORDSYSTEM == NED
266#elif THISCOORDSYSTEM == ANDROID
296 for (i =
CHX; i <=
CHZ; i++)
305 if (GetGyroCalibrationFromNVM(pFlash))
308 for (i =
CHX; i <=
CHZ; i++) pthisSV->
fbPl[i] = pFlash[i];
314 for (i =
CHX; i <=
CHZ; i++)
318 pthisSV->
fbPl[i] = pthisGyro->
fYs[i];
320 pthisSV->
fbPl[i] = 0.0F;
326#if THISCOORDSYSTEM == NED
328#elif THISCOORDSYSTEM == ANDROID
359 for (i =
CHX; i <=
CHZ; i++) {
363 pthisSV->
fVelGl[i] = 0.0F;
364 pthisSV->
fDisGl[i] = 0.0F;
370 if (GetGyroCalibrationFromNVM(pFlash))
373 for (i =
CHX; i <=
CHZ; i++) pthisSV->
fbPl[i] = pFlash[i];
377 for (i =
CHX; i <=
CHZ; i++) {
379 pthisSV->
fbPl[i] = pthisGyro->
fYs[i];
381 pthisSV->
fbPl[i] = 0.0F;
389#if THISCOORDSYSTEM == NED
391 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
392#elif THISCOORDSYSTEM == ANDROID
394 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
397 pthisMag->
fBc, pthisAccel->
fGc, &ftmp, &ftmp);
426 pthisSV->
fLPH += pthisSV->
flpf * (pthisPressure->
fH - pthisSV->
fLPH);
427 pthisSV->
fLPT += pthisSV->
flpf * (pthisPressure->
fT - pthisSV->
fLPT);
444#if THISCOORDSYSTEM == NED
446#elif THISCOORDSYSTEM == ANDROID
462#if THISCOORDSYSTEM == NED
466#elif THISCOORDSYSTEM == ANDROID
493#if THISCOORDSYSTEM == NED
495#elif THISCOORDSYSTEM == ANDROID
511#if THISCOORDSYSTEM == NED
515#elif THISCOORDSYSTEM == ANDROID
537 fInit_3DOF_Y_BASIC(pthisSV);
559#if THISCOORDSYSTEM == NED
562 &(pthisSV->
fRho), &(pthisSV->
fChi));
563#elif THISCOORDSYSTEM == ANDROID
566 &(pthisSV->
fRho), &(pthisSV->
fChi));
570 &(pthisSV->
fRho), &(pthisSV->
fChi));
579 float ftmp1, ftmp2, ftmp3, ftmp4;
584 fInit_6DOF_GB_BASIC(pthisSV, pthisAccel, pthisMag,
585 FLPFSECS_6DOF_GB_BASIC);
590#if THISCOORDSYSTEM == NED
592#elif THISCOORDSYSTEM == ANDROID
608#if THISCOORDSYSTEM == NED
612#elif THISCOORDSYSTEM == ANDROID
635 float ftmp3DOF3x1[3];
636 float ftmpA3x3[3][3];
658 fInit_6DOF_GY_KALMAN(pthisSV, pthisAccel, pthisGyro);
663 for (i =
CHX; i <=
CHZ; i++)
664 pthisSV->
fOmega[i] = (
float) pthisGyro->
iYs[i] *
670 fqMi = pthisSV->
fqPl;
680 for (i =
CHX; i <=
CHZ; i++)
681 ftmpMi3x1[i] = (
float) pthisGyro->
iYsFIFO[j][i] *
700 fmodGc = sqrtf(fabs(pthisAccel->
fGc[
CHX] * pthisAccel->
fGc[
CHX] +
706 ftmp = 1.0F / fmodGc;
707 ftmp3DOF3x1[
CHX] = pthisAccel->
fGc[
CHX] * ftmp;
708 ftmp3DOF3x1[
CHY] = pthisAccel->
fGc[
CHY] * ftmp;
709 ftmp3DOF3x1[
CHZ] = pthisAccel->
fGc[
CHZ] * ftmp;
714 ftmp3DOF3x1[
CHX] = 0.0F;
715 ftmp3DOF3x1[
CHY] = 0.0F;
716 ftmp3DOF3x1[
CHZ] = 1.0F;
720#if THISCOORDSYSTEM == NED
722#elif THISCOORDSYSTEM == ANDROID
724 ftmp3DOF3x1[
CHX] = -ftmp3DOF3x1[
CHX];
725 ftmp3DOF3x1[
CHY] = -ftmp3DOF3x1[
CHY];
726 ftmp3DOF3x1[
CHZ] = -ftmp3DOF3x1[
CHZ];
732 ftmpMi3x1[
CHX] = 2.0F * (fqMi.
q1 * fqMi.
q3 - fqMi.
q0 * fqMi.
q2);
733 ftmpMi3x1[
CHY] = 2.0F * (fqMi.
q2 * fqMi.
q3 + fqMi.
q0 * fqMi.
q1);
734 ftmpMi3x1[
CHZ] = 2.0F * (fqMi.
q0 * fqMi.
q0 + fqMi.
q3 * fqMi.
q3) - 1.0F;
737#if THISCOORDSYSTEM == NED
741 ftmpMi3x1[
CHX] = -ftmpMi3x1[
CHX];
742 ftmpMi3x1[
CHY] = -ftmpMi3x1[
CHY];
743 ftmpMi3x1[
CHZ] = -ftmpMi3x1[
CHZ];
757 for (i = 0; i < 6; i++)
758 for (j = 0; j < 6; j++) pthisSV->
fQw6x6[i][j] = 0.0F;
802 ftmp = fmodGc - 1.0F;
803 fQvGQa = 3.0F * ftmp * ftmp;
809 for (i = 0; i < 6; i++)
811 for (j = 0; j < 3; j++)
816 for (k = 0; k < 6; k++)
820 if (k == j) fC3x6jk = 1.0F;
824 if ((pthisSV->
fQw6x6[i][k] != 0.0F) && (fC3x6jk != 0.0F))
836 for (i = 0; i < 3; i++)
838 for (j = i; j < 3; j++)
842 ftmpA3x3[i][j] = pthisSV->
fQv;
844 ftmpA3x3[i][j] = 0.0F;
847 for (k = 0; k < 6; k++)
851 if (k == i) fC3x6ik = 1.0F;
855 if ((fC3x6ik != 0.0F) && (pthisSV->
fQwCT6x3[k][j] != 0.0F))
858 ftmpA3x3[i][j] += pthisSV->
fQwCT6x3[k][j];
860 ftmpA3x3[i][j] += fC3x6ik * pthisSV->
fQwCT6x3[k][j];
867 ftmpA3x3[1][0] = ftmpA3x3[0][1];
868 ftmpA3x3[2][0] = ftmpA3x3[0][2];
869 ftmpA3x3[2][1] = ftmpA3x3[1][2];
872 for (i = 0; i < 3; i++) pfRows[i] = ftmpA3x3[i];
879 for (i = 0; i < 6; i++)
881 for (j = 0; j < 3; j++)
883 pthisSV->
fK6x3[i][j] = 0.0F;
884 for (k = 0; k < 3; k++)
886 if ((pthisSV->
fQwCT6x3[i][k] != 0.0F) &&
887 (ftmpA3x3[k][j] != 0.0F))
889 pthisSV->
fK6x3[i][j] += pthisSV->
fQwCT6x3[i][k] * ftmpA3x3[k][j];
898 for (i = 0; i < 6; i++)
900 for (j = 0; j < 3; j++)
902 pthisSV->
fK6x3[i][j] = 0.0F;
909 for (i =
CHX; i <=
CHZ; i++)
922 if (pthisSV->
fK6x3[i + 3][
CHX] != 0.0F)
926 if (pthisSV->
fK6x3[i + 3][
CHY] != 0.0F)
928 if (pthisSV->
fK6x3[i + 3][
CHZ] != 0.0F)
936 ftmp = ftmpq.
q1 * ftmpq.
q1 + ftmpq.
q2 * ftmpq.
q2 + ftmpq.
q3 * ftmpq.
q3;
942 ftmpq.
q0 = sqrtf(fabsf(1.0F - ftmp));
947 ftmp = 1.0F / sqrtf(ftmp);
964 for (i =
CHX; i <=
CHZ; i++)
980#if THISCOORDSYSTEM == NED
985#elif THISCOORDSYSTEM == ANDROID
996#if THISCOORDSYSTEM == NED
1000#elif THISCOORDSYSTEM == ANDROID
1011#if F_9DOF_GBY_KALMAN
1020 float ftmpA6x6[6][6];
1027 float ftmpA3x3[3][3];
1037 float fsinDelta6DOF;
1038 float fcosDelta6DOF;
1055 fInit_9DOF_GBY_KALMAN(pthisSV, pthisAccel, pthisMag, pthisGyro, pthisMagCal);
1064 fqMi = pthisSV->
fqPl;
1070 for (j = 0; j < pthisGyro->
iFIFOCount; j++) {
1089#if THISCOORDSYSTEM == NED
1090 feCompassNED(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1091#elif THISCOORDSYSTEM == ANDROID
1092 feCompassAndroid(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1094 feCompassWin8(fR6DOF, &fDelta6DOF, &fsinDelta6DOF, &fcosDelta6DOF, pthisMag->
fBc, pthisAccel->
fGc, &fmodBc, &fmodGc);
1101 ftmp = fmodGc - 1.0F;
1102 fQvGQa = 3.0F * ftmp * ftmp;
1107 ftmp = fmodBc - pthisMagCal->
fB;
1108 fQvBQd = 3.0F * ftmp * ftmp;
1116 fqMi = pthisSV->
fqPl = fq6DOF;
1126#if THISCOORDSYSTEM == NED
1151#if THISCOORDSYSTEM == NED
1152 ftmpA3x1[
CHX] = fR6DOF[
CHX][
CHX] * fcosDelta6DOF + fR6DOF[
CHX][
CHZ] * fsinDelta6DOF;
1153 ftmpA3x1[
CHY] = fR6DOF[
CHY][
CHX] * fcosDelta6DOF + fR6DOF[
CHY][
CHZ] * fsinDelta6DOF;
1154 ftmpA3x1[
CHZ] = fR6DOF[
CHZ][
CHX] * fcosDelta6DOF + fR6DOF[
CHZ][
CHZ] * fsinDelta6DOF;
1159 ftmpA3x1[
CHX] = fR6DOF[
CHX][
CHY] * fcosDelta6DOF - fR6DOF[
CHX][
CHZ] * fsinDelta6DOF;
1160 ftmpA3x1[
CHY] = fR6DOF[
CHY][
CHY] * fcosDelta6DOF - fR6DOF[
CHY][
CHZ] * fsinDelta6DOF;
1161 ftmpA3x1[
CHZ] = fR6DOF[
CHZ][
CHY] * fcosDelta6DOF - fR6DOF[
CHZ][
CHZ] * fsinDelta6DOF;
1178 for (i = 0; i < 9; i++)
1179 for (j = i; j < 9; j++)
1180 pthisSV->
fQw9x9[i][j] = 0.0F;
1214 for (i = 1; i < 9; i++)
1215 for (j = 0; j < i; j++)
1224 for (i = 0; i < 9; i++) {
1225 for (j = 0; j < 6; j++) {
1228 for (k = 0; k < 9; k++) {
1233 if (k == j) fC6x9jk = 1.0F;
1234 if (k == (j + 6)) fC6x9jk = -pthisSV->
fAlphaOver2;
1237 if (k == j) fC6x9jk = 1.0F;
1238 if (k == (j + 3)) fC6x9jk = -pthisSV->
fAlphaOver2;
1242 if ((pthisSV->
fQw9x9[i][k] != 0.0F) && (fC6x9jk != 0.0F)) {
1243 if (fC6x9jk == 1.0F) pthisSV->
fQwCT9x6[i][j] += pthisSV->
fQw9x9[i][k];
1251 for (i = 0; i < 6; i++) {
1252 for (j = i; j < 6; j++) {
1254 if (i == j) ftmpA6x6[i][j] = pthisSV->
fQv6x1[i];
1255 else ftmpA6x6[i][j] = 0.0F;
1257 for (k = 0; k < 9; k++) {
1262 if (k == i) fC6x9ik = 1.0F;
1263 if (k == (i + 6)) fC6x9ik = -pthisSV->
fAlphaOver2;
1266 if (k == i) fC6x9ik = 1.0F;
1267 if (k == (i + 3)) fC6x9ik = -pthisSV->
fAlphaOver2;
1271 if ((fC6x9ik != 0.0F) && (pthisSV->
fQwCT9x6[k][j] != 0.0F)) {
1272 if (fC6x9ik == 1.0F) ftmpA6x6[i][j] += pthisSV->
fQwCT9x6[k][j];
1273 else ftmpA6x6[i][j] += fC6x9ik * pthisSV->
fQwCT9x6[k][j];
1279 for (i = 1; i < 6; i++)
1280 for (j = 0; j < i; j++)
1281 ftmpA6x6[i][j] = ftmpA6x6[j][i];
1284 for (i = 0; i < 6; i++)
1285 pfRows[i] = ftmpA6x6[i];
1291 for (i = 0; i < 9; i++)
1292 for (j = 0; j < 6; j++) {
1293 pthisSV->
fK9x6[i][j] = 0.0F;
1294 for (k = 0; k < 6; k++) {
1295 if ((pthisSV->
fQwCT9x6[i][k] != 0.0F) && (ftmpA6x6[k][j] != 0.0F))
1296 pthisSV->
fK9x6[i][j] += pthisSV->
fQwCT9x6[i][k] * ftmpA6x6[k][j];
1301 for (i = 0; i < 9; i++)
1302 for (j = 0; j < 6; j++)
1303 pthisSV->
fK9x6[i][j] = 0.0F;
1308 for (i =
CHX; i <=
CHZ; i++) {
1310 for (j = 0; j < 6; j++) {
1312 if (pthisSV->
fK9x6[i][j] != 0.0F)
1316 if (pthisSV->
fK9x6[i + 3][j] != 0.0F)
1320 if (pthisSV->
fK9x6[i + 6][j] != 0.0F)
1329 ftmpq.
q0 = sqrtf(fabs(1.0F - ftmpq.
q1 * ftmpq.
q1 - ftmpq.
q2 * ftmpq.
q2 - ftmpq.
q3 * ftmpq.
q3));
1334 fveqRu(fgPl, ftmpA3x3, fgMi, 0);
1340 ftmpq.
q0 = sqrtf(fabs(1.0F - ftmpq.
q1 * ftmpq.
q1 - ftmpq.
q2 * ftmpq.
q2 - ftmpq.
q3 * ftmpq.
q3));
1345 fveqRu(fmPl, ftmpA3x3, fmMi, 0);
1349#if THISCOORDSYSTEM == NED
1351 fmPl, fgPl, &fmodBc, &fmodGc);
1352#elif THISCOORDSYSTEM == ANDROID
1353 ftmpA3x1[
CHX] = -fgPl[
CHX];
1354 ftmpA3x1[
CHY] = -fgPl[
CHY];
1355 ftmpA3x1[
CHZ] = -fgPl[
CHZ];
1357 fmPl, ftmpA3x1, &fmodBc, &fmodGc);
1360 fmPl, fgPl, &fmodBc, &fmodGc);
1368 for (i =
CHX; i <=
CHZ; i++) {
1387#if THISCOORDSYSTEM == NED
1392#elif THISCOORDSYSTEM == ANDROID
1405 for (i =
CHX; i <=
CHZ; i++) {
1413#if THISCOORDSYSTEM == NED
1415#elif THISCOORDSYSTEM == ANDROID
Math approximations file.
#define FUSION_HZ
(int) rate of fusion algorithm execution
Provides functions to store calibration to NVM, which on ESP devices is provided by EEPROM.
Lower level sensor fusion interface.
#define FQVY_6DOF_GY_KALMAN
gyro sensor noise variance units (deg/s)^2
#define FMAX_9DOF_GBY_BPL
maximum permissible power on gyro offsets (deg/s)
#define FMIN_9DOF_GBY_BPL
minimum permissible power on gyro offsets (deg/s)
#define FQWB_9DOF_GBY_KALMAN
gyro offset random walk units (deg/s)^2
#define FQVY_9DOF_GBY_KALMAN
gyro sensor noise variance units (deg/s)^2
#define FQWB_6DOF_GY_KALMAN
gyro offset random walk units (deg/s)^2
#define FLPFSECS_3DOF_B_BASIC
2D eCompass orientation low pass filter time constant (s)
#define FMAX_6DOF_GY_BPL
maximum permissible power on gyro offsets (deg/s)
#define FQVB_9DOF_GBY_KALMAN
magnetometer sensor noise variance units uT^2 defining minimum deviation from geomagnetic sphere.
#define FQVG_6DOF_GY_KALMAN
accelerometer sensor noise variance units g^2
#define FLPFSECS_1DOF_P_BASIC
pressure low pass filter time constant (s)
#define FMIN_6DOF_GY_BPL
minimum permissible power on gyro offsets (deg/s)
#define FQVG_9DOF_GBY_KALMAN
accelerometer sensor noise variance units g^2 defining minimum deviation from 1g sphere
#define FLPFSECS_3DOF_G_BASIC
tilt orientation low pass filter time constant (s)
Wrapper for Hardware Abstraction Layer (HAL) Contains replacements for hardware-specific functions Cu...
void f3x3matrixAeqI(float A[][3])
function sets the 3x3 matrix A to the identity matrix
void fmatrixAeqInvA(float *A[], int8_t iColInd[], int8_t iRowInd[], int8_t iPivot[], int8_t isize, int8_t *pierror)
void f3x3matrixAeqB(float A[][3], float B[][3])
function sets 3x3 matrix A to 3x3 matrix B
void fveqRu(float fv[], float fR[][3], float fu[], int8_t itranspose)
Matrix manipulation functions.
void fQuaternionFromRotationMatrix(float R[][3], Quaternion *pq)
compute the orientation quaternion from a 3x3 rotation matrix
void qAeqBxC(Quaternion *pqA, const Quaternion *pqB, const Quaternion *pqC)
function compute the quaternion product qB * qC
void fWin8AnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the Windows 8 angles in degrees from the Windows 8 rotation matrix
void qAeqAxB(Quaternion *pqA, const Quaternion *pqB)
function compute the quaternion product qA = qA * qB
void f3DOFMagnetometerMatrixNED(float fR[][3], float fBc[])
Aerospace NED magnetometer 3DOF flat eCompass function, computing rotation matrix fR.
void fqAeqNormqA(Quaternion *pqA)
function normalizes a rotation quaternion and ensures q0 is non-negative
void feCompassAndroid(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
Android: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle f...
void fveqconjgquq(Quaternion *pfq, float fu[], float fv[])
void fqAeq1(Quaternion *pqA)
set a quaternion to the unit quaternion
void f3DOFMagnetometerMatrixAndroid(float fR[][3], float fBc[])
Android magnetometer 3DOF flat eCompass function, computing rotation matrix fR.
void fAndroidAnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the Android angles in degrees from the Android rotation matrix
void f3DOFMagnetometerMatrixWin8(float fR[][3], float fBc[])
Windows 8 magnetometer 3DOF flat eCompass function, computing rotation matrix fR.
void fQuaternionFromRotationVectorDeg(Quaternion *pq, const float rvecdeg[], float fscaling)
computes normalized rotation quaternion from a rotation vector (deg)
void fRotationVectorDegFromQuaternion(Quaternion *pq, float rvecdeg[])
computes rotation vector (deg) from rotation quaternion
void fNEDAnglesDegFromRotationMatrix(float R[][3], float *pfPhiDeg, float *pfTheDeg, float *pfPsiDeg, float *pfRhoDeg, float *pfChiDeg)
extract the NED angles in degrees from the NED rotation matrix
void feCompassWin8(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
Win8: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle fDel...
void fRotationMatrixFromQuaternion(float R[][3], const Quaternion *pq)
compute the rotation matrix from an orientation quaternion
void fLPFOrientationQuaternion(Quaternion *pq, Quaternion *pLPq, float flpf, float fdeltat, float fOmega[])
function low pass filters an orientation quaternion and computes virtual gyro rotation rate
void feCompassNED(float fR[][3], float *pfDelta, float *pfsinDelta, float *pfcosDelta, float fBc[], float fGc[], float *pfmodBc, float *pfmodGc)
NED: basic 6DOF e-Compass function, computing rotation matrix fR and magnetic inclination angle fDelt...
Functions to convert between various orientation representations.
void f3DOFTiltWin8(float fR[][3], float fGc[])
Windows 8 accelerometer 3DOF tilt function computing, rotation matrix fR.
void f3DOFTiltAndroid(float fR[][3], float fGc[])
Android accelerometer 3DOF tilt function computing, rotation matrix fR.
void f3DOFTiltNED(float fR[][3], float fGc[])
Aerospace NED accelerometer 3DOF tilt function, computing rotation matrix fR.
The sensor_fusion.h file implements the top level programming interface.
#define CHX
Used to access X-channel entries in various data data structures.
#define GTOMSEC2
standard gravity in m/s2
#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.
#define FPIOVER180
degrees to radians conversion = pi / 180
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
float fGc[3]
averaged precision calibrated measurement (g)
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
int16_t iYs[3]
average measurement (counts)
int16_t iYsFIFO[GYRO_FIFO_SIZE][3]
FIFO measurements (counts)
uint8_t iFIFOCount
number of measurements read from FIFO
float fDegPerSecPerCount
deg/s per count
float fYs[3]
averaged measurement (deg/s)
Magnetic Calibration Structure.
float fB
current geomagnetic field magnitude (uT)
float fBSq
square of fB (uT^2)
int32_t iValidMagCal
solver used: 0 (no calibration) or 4, 7, 10 element
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor.
float fBc[3]
averaged calibrated measurement (uT)
The PressureSensor structure stores raw and processed measurements for an altimeter.
float fT
most recent unaveraged temperature (C)
float fH
most recent unaveraged height (m)
quaternion structure definition
float q3
z vector component
float q1
x vector component
float q2
y vector component
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
float fdeltat
fusion time interval (s)
float flpf
low pass filter coefficient
int8_t resetflag
flag to request re-initialization on next pass
int32_t systick
systick timer
float fLPH
low pass filtered height (m)
float fLPT
low pass filtered temperature (C)
This is the 3DOF basic magnetometer state vector structure/.
float fLPChi
low pass tilt from vertical (deg)
int32_t systick
systick timer
Quaternion fq
unfiltered orientation quaternion
int8_t resetflag
flag to request re-initialization on next pass
float fLPPsi
low pass yaw (deg)
float fOmega[3]
angular velocity (deg/s)
float fR[3][3]
unfiltered orientation matrix
float flpf
low pass filter coefficient
Quaternion fLPq
low pass filtered orientation quaternion
float fdeltat
fusion time interval (s)
float fLPRVec[3]
rotation vector
float fLPThe
low pass pitch (deg)
float fLPRho
low pass compass (deg)
float fLPPhi
low pass roll (deg)
float fLPR[3][3]
low pass filtered orientation matrix
This is the 3DOF basic accelerometer state vector structure.
float fR[3][3]
unfiltered orientation matrix
Quaternion fq
unfiltered orientation quaternion
float fdeltat
fusion time interval (s)
float fLPThe
low pass pitch (deg)
float fLPPsi
low pass yaw (deg)
float fLPR[3][3]
low pass filtered orientation matrix
Quaternion fLPq
low pass filtered orientation quaternion
float fLPRho
low pass compass (deg)
int32_t systick
systick timer
float fLPRVec[3]
rotation vector
float flpf
low pass filter coefficient
float fLPChi
low pass tilt from vertical (deg)
int8_t resetflag
flag to request re-initialization on next pass
float fOmega[3]
angular velocity (deg/s)
float fLPPhi
low pass roll (deg)
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
float fRVec[3]
rotation vector
int32_t systick
systick timer
Quaternion fq
unfiltered orientation quaternion
float fOmega[3]
angular velocity (deg/s)
float fR[3][3]
unfiltered orientation matrix
int8_t resetflag
flag to request re-initialization on next pass
float fChi
tilt from vertical (deg)
float fdeltat
fusion filter sampling interval (s)
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
Quaternion fq
unfiltered orientation quaternion
float fLPPhi
low pass roll (deg)
Quaternion fLPq
low pass filtered orientation quaternion
float fLPR[3][3]
low pass filtered orientation matrix
int8_t resetflag
flag to request re-initialization on next pass
float fLPDelta
low pass filtered inclination angle (deg)
float fdeltat
fusion time interval (s)
float fR[3][3]
unfiltered orientation matrix
float fLPChi
low pass tilt from vertical (deg)
float flpf
low pass filter coefficient
float fDelta
unfiltered inclination angle (deg)
float fOmega[3]
virtual gyro angular velocity (deg/s)
float fLPPsi
low pass yaw (deg)
float fLPThe
low pass pitch (deg)
float fLPRho
low pass compass (deg)
float fLPRVec[3]
rotation vector
int32_t systick
systick timer
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure.
float fQw6x6[6][6]
covariance matrix Qw
float fOmega[3]
average angular velocity (deg/s)
float fAccGl[3]
linear acceleration (g) in global frame
float fAlphaOver2
PI / 180 * fdeltat / 2.
float fqgErrPl[3]
gravity vector tilt orientation quaternion error (dimensionless)
float fbPl[3]
gyro offset (deg/s)
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
float fQwCT6x3[6][3]
Qw.C^T matrix.
float fRPl[3][3]
a posteriori orientation matrix
float fK6x3[6][3]
kalman filter gain matrix K
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
float fRhoPl
compass (deg)
Quaternion fqPl
a posteriori orientation quaternion
float fdeltat
sensor fusion interval (s)
float fChiPl
tilt from vertical (deg)
float fZErr[3]
measurement error vector
int32_t systick
systick timer;
float fbErrPl[3]
gyro offset error (deg/s)
int8_t resetflag
flag to request re-initialization on next pass
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
float fQv
measurement noise covariance matrix leading diagonal
float fRVecPl[3]
rotation vector
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
int32_t systick
systick timer;
float fAlphaOver2
PI / 180 * fdeltat / 2.
float fChiPl
tilt from vertical (deg)
float fDeltaPl
a posteriori inclination angle from Kalman filter (deg)
float fqmErrPl[3]
geomagnetic vector tilt orientation quaternion error (dimensionless)
float fqgErrPl[3]
gravity vector tilt orientation quaternion error (dimensionless)
float fbErrPl[3]
gyro offset error (deg/s)
float fcosDeltaPl
cos(fDeltaPl)
float fsinDeltaPl
sin(fDeltaPl)
float fRhoPl
compass (deg)
float fK9x6[9][6]
kalman filter gain matrix K
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
float fQw9x9[9][9]
covariance matrix Qw
Quaternion fqPl
a posteriori orientation quaternion
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
float fRVecPl[3]
rotation vector
float fgdeltat
g (m/s2) * fdeltat
float fVelGl[3]
velocity (m/s) in global frame
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
float fDisGl[3]
displacement (m) in global frame
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
float fOmega[3]
average angular velocity (deg/s)
int8_t resetflag
flag to request re-initialization on next pass
float fAccGl[3]
linear acceleration (g) in global frame
float fbPl[3]
gyro offset (deg/s)
float fZErr[6]
measurement error vector
float fRPl[3][3]
a posteriori orientation matrix
float fdeltat
sensor fusion interval (s)
float fQwCT9x6[9][6]
Qw.C^T matrix.
float fQv6x1[6]
measurement noise covariance matrix leading diagonal
int8_t iFirstAccelMagLock
denotes that 9DOF orientation has locked to 6DOF eCompass
The top level fusion structure.
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)