3 #if HAL_CPU_CLASS >= HAL_CPU_CLASS_150 35 bool flightResetAllowed =
false;
36 bool initialResetAllowed =
false;
46 bool angRateOK = deltaRotVecTemp.
length() < 0.1745f;
48 initialResetAllowed = angRateOK;
49 flightResetAllowed = angRateOK && !
onGround;
54 bool finalResetRequest =
false;
55 bool interimResetRequest =
false;
66 bool yawInnovIncreasing = yawInnovIncrease > 0.25f;
71 bool largeAngleChange = deltaRotVecTemp.
length() > yawInnovIncrease;
75 interimResetRequest = hgtIncreasing && yawInnovIncreasing && !largeAngleChange;
83 initialResetRequest ||
84 interimResetRequest ||
126 if (finalResetRequest) {
127 gcs().
send_text(MAV_SEVERITY_INFO,
"EKF3 IMU%u in-flight yaw alignment complete",(
unsigned)
imu_index);
128 }
else if (interimResetRequest) {
129 gcs().
send_text(MAV_SEVERITY_WARNING,
"EKF3 IMU%u ground mag anomaly, yaw re-aligned",(
unsigned)
imu_index);
140 if (interimResetRequest) {
164 float yawErr =
MAX(fabsf(
wrap_PI(gpsYaw - velYaw)),fabsf(
wrap_PI(gpsYaw - eulerAngles.
z)));
360 DCM[0][0] = q0*q0 + q1*q1 - q2*q2 - q3*
q3;
361 DCM[0][1] = 2.0f*(q1*q2 + q0*
q3);
362 DCM[0][2] = 2.0f*(q1*q3-q0*
q2);
363 DCM[1][0] = 2.0f*(q1*q2 - q0*
q3);
364 DCM[1][1] = q0*q0 - q1*q1 + q2*q2 - q3*
q3;
365 DCM[1][2] = 2.0f*(q2*q3 + q0*
q1);
366 DCM[2][0] = 2.0f*(q1*q3 + q0*
q2);
367 DCM[2][1] = 2.0f*(q2*q3 - q0*
q1);
368 DCM[2][2] = q0*q0 - q1*q1 - q2*q2 + q3*
q3;
369 MagPred[0] = DCM[0][0]*magN + DCM[0][1]*magE + DCM[0][2]*magD +
magXbias;
370 MagPred[1] = DCM[1][0]*magN + DCM[1][1]*magE + DCM[1][2]*magD +
magYbias;
371 MagPred[2] = DCM[2][0]*magN + DCM[2][1]*magE + DCM[2][2]*magD +
magZbias;
374 for (uint8_t i = 0; i<=2; i++) {
382 SH_MAG[0] = 2.0f*magD*q3 + 2.0f*magE*q2 + 2.0f*magN*
q1;
383 SH_MAG[1] = 2.0f*magD*q0 - 2.0f*magE*q1 + 2.0f*magN*
q2;
384 SH_MAG[2] = 2.0f*magD*q1 + 2.0f*magE*q0 - 2.0f*magN*
q3;
389 SH_MAG[7] = 2.0f*magN*
q0;
390 SH_MAG[8] = 2.0f*magE*
q3;
394 varInnovMag[0] = (
P[19][19] + R_MAG +
P[1][19]*SH_MAG[0] -
P[2][19]*SH_MAG[1] +
P[3][19]*SH_MAG[2] -
P[16][19]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) + (2.0
f*q0*q3 + 2.0
f*q1*q2)*(
P[19][17] +
P[1][17]*SH_MAG[0] -
P[2][17]*SH_MAG[1] +
P[3][17]*SH_MAG[2] -
P[16][17]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][17]*(2.0
f*q0*q3 + 2.0
f*q1*q2) -
P[18][17]*(2.0f*q0*q2 - 2.0f*q1*
q3) +
P[0][17]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) - (2.0
f*q0*q2 - 2.0
f*q1*q3)*(
P[19][18] +
P[1][18]*SH_MAG[0] -
P[2][18]*SH_MAG[1] +
P[3][18]*SH_MAG[2] -
P[16][18]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][18]*(2.0
f*q0*q3 + 2.0
f*q1*q2) -
P[18][18]*(2.0f*q0*q2 - 2.0f*q1*
q3) +
P[0][18]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)*(
P[19][0] +
P[1][0]*SH_MAG[0] -
P[2][0]*SH_MAG[1] +
P[3][0]*SH_MAG[2] -
P[16][0]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][0]*(2.0
f*q0*q3 + 2.0
f*q1*q2) -
P[18][0]*(2.0f*q0*q2 - 2.0f*q1*
q3) +
P[0][0]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) +
P[17][19]*(2.0
f*q0*q3 + 2.0
f*q1*q2) -
P[18][19]*(2.0f*q0*q2 - 2.0f*q1*
q3) + SH_MAG[0]*(
P[19][1] +
P[1][1]*SH_MAG[0] -
P[2][1]*SH_MAG[1] +
P[3][1]*SH_MAG[2] -
P[16][1]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][1]*(2.0f*q0*q3 + 2.0f*q1*
q2) -
P[18][1]*(2.0
f*q0*q2 - 2.0
f*q1*q3) +
P[0][1]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) - SH_MAG[1]*(
P[19][2] +
P[1][2]*SH_MAG[0] -
P[2][2]*SH_MAG[1] +
P[3][2]*SH_MAG[2] -
P[16][2]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][2]*(2.0
f*q0*q3 + 2.0
f*q1*q2) -
P[18][2]*(2.0f*q0*q2 - 2.0f*q1*
q3) +
P[0][2]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + SH_MAG[2]*(
P[19][3] +
P[1][3]*SH_MAG[0] -
P[2][3]*SH_MAG[1] +
P[3][3]*SH_MAG[2] -
P[16][3]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][3]*(2.0f*q0*q3 + 2.0f*q1*
q2) -
P[18][3]*(2.0
f*q0*q2 - 2.0
f*q1*q3) +
P[0][3]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) - (SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6])*(
P[19][16] +
P[1][16]*SH_MAG[0] -
P[2][16]*SH_MAG[1] +
P[3][16]*SH_MAG[2] -
P[16][16]*(SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6]) +
P[17][16]*(2.0f*q0*q3 + 2.0f*q1*
q2) -
P[18][16]*(2.0
f*q0*q2 - 2.0
f*q1*q3) +
P[0][16]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) +
P[0][19]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2));
406 varInnovMag[1] = (
P[20][20] + R_MAG +
P[0][20]*SH_MAG[2] +
P[1][20]*SH_MAG[1] +
P[2][20]*SH_MAG[0] -
P[17][20]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) - (2.0
f*q0*q3 - 2.0
f*q1*q2)*(
P[20][16] +
P[0][16]*SH_MAG[2] +
P[1][16]*SH_MAG[1] +
P[2][16]*SH_MAG[0] -
P[17][16]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][16]*(2.0
f*q0*q3 - 2.0
f*q1*q2) +
P[18][16]*(2.0f*q0*q1 + 2.0f*q2*
q3) -
P[3][16]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + (2.0
f*q0*q1 + 2.0
f*q2*q3)*(
P[20][18] +
P[0][18]*SH_MAG[2] +
P[1][18]*SH_MAG[1] +
P[2][18]*SH_MAG[0] -
P[17][18]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][18]*(2.0
f*q0*q3 - 2.0
f*q1*q2) +
P[18][18]*(2.0f*q0*q1 + 2.0f*q2*
q3) -
P[3][18]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) - (SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)*(
P[20][3] +
P[0][3]*SH_MAG[2] +
P[1][3]*SH_MAG[1] +
P[2][3]*SH_MAG[0] -
P[17][3]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][3]*(2.0
f*q0*q3 - 2.0
f*q1*q2) +
P[18][3]*(2.0f*q0*q1 + 2.0f*q2*
q3) -
P[3][3]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) -
P[16][20]*(2.0
f*q0*q3 - 2.0
f*q1*q2) +
P[18][20]*(2.0f*q0*q1 + 2.0f*q2*
q3) + SH_MAG[2]*(
P[20][0] +
P[0][0]*SH_MAG[2] +
P[1][0]*SH_MAG[1] +
P[2][0]*SH_MAG[0] -
P[17][0]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][0]*(2.0f*q0*q3 - 2.0f*q1*
q2) +
P[18][0]*(2.0
f*q0*q1 + 2.0
f*q2*q3) -
P[3][0]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) + SH_MAG[1]*(
P[20][1] +
P[0][1]*SH_MAG[2] +
P[1][1]*SH_MAG[1] +
P[2][1]*SH_MAG[0] -
P[17][1]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][1]*(2.0
f*q0*q3 - 2.0
f*q1*q2) +
P[18][1]*(2.0f*q0*q1 + 2.0f*q2*
q3) -
P[3][1]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + SH_MAG[0]*(
P[20][2] +
P[0][2]*SH_MAG[2] +
P[1][2]*SH_MAG[1] +
P[2][2]*SH_MAG[0] -
P[17][2]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][2]*(2.0f*q0*q3 - 2.0f*q1*
q2) +
P[18][2]*(2.0
f*q0*q1 + 2.0
f*q2*q3) -
P[3][2]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) - (SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6])*(
P[20][17] +
P[0][17]*SH_MAG[2] +
P[1][17]*SH_MAG[1] +
P[2][17]*SH_MAG[0] -
P[17][17]*(SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6]) -
P[16][17]*(2.0f*q0*q3 - 2.0f*q1*
q2) +
P[18][17]*(2.0
f*q0*q1 + 2.0
f*q2*q3) -
P[3][17]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) -
P[3][20]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2));
418 varInnovMag[2] = (
P[21][21] + R_MAG +
P[0][21]*SH_MAG[1] -
P[1][21]*SH_MAG[2] +
P[3][21]*SH_MAG[0] +
P[18][21]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) + (2.0
f*q0*q2 + 2.0
f*q1*q3)*(
P[21][16] +
P[0][16]*SH_MAG[1] -
P[1][16]*SH_MAG[2] +
P[3][16]*SH_MAG[0] +
P[18][16]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][16]*(2.0
f*q0*q2 + 2.0
f*q1*q3) -
P[17][16]*(2.0f*q0*q1 - 2.0f*q2*
q3) +
P[2][16]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) - (2.0
f*q0*q1 - 2.0
f*q2*q3)*(
P[21][17] +
P[0][17]*SH_MAG[1] -
P[1][17]*SH_MAG[2] +
P[3][17]*SH_MAG[0] +
P[18][17]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][17]*(2.0
f*q0*q2 + 2.0
f*q1*q3) -
P[17][17]*(2.0f*q0*q1 - 2.0f*q2*
q3) +
P[2][17]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + (SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)*(
P[21][2] +
P[0][2]*SH_MAG[1] -
P[1][2]*SH_MAG[2] +
P[3][2]*SH_MAG[0] +
P[18][2]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][2]*(2.0
f*q0*q2 + 2.0
f*q1*q3) -
P[17][2]*(2.0f*q0*q1 - 2.0f*q2*
q3) +
P[2][2]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) +
P[16][21]*(2.0
f*q0*q2 + 2.0
f*q1*q3) -
P[17][21]*(2.0f*q0*q1 - 2.0f*q2*
q3) + SH_MAG[1]*(
P[21][0] +
P[0][0]*SH_MAG[1] -
P[1][0]*SH_MAG[2] +
P[3][0]*SH_MAG[0] +
P[18][0]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][0]*(2.0f*q0*q2 + 2.0f*q1*
q3) -
P[17][0]*(2.0
f*q0*q1 - 2.0
f*q2*q3) +
P[2][0]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) - SH_MAG[2]*(
P[21][1] +
P[0][1]*SH_MAG[1] -
P[1][1]*SH_MAG[2] +
P[3][1]*SH_MAG[0] +
P[18][1]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][1]*(2.0
f*q0*q2 + 2.0
f*q1*q3) -
P[17][1]*(2.0f*q0*q1 - 2.0f*q2*
q3) +
P[2][1]*(SH_MAG[7] + SH_MAG[8] - 2.0
f*magD*q2)) + SH_MAG[0]*(
P[21][3] +
P[0][3]*SH_MAG[1] -
P[1][3]*SH_MAG[2] +
P[3][3]*SH_MAG[0] +
P[18][3]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][3]*(2.0f*q0*q2 + 2.0f*q1*
q3) -
P[17][3]*(2.0
f*q0*q1 - 2.0
f*q2*q3) +
P[2][3]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) + (SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6])*(
P[21][18] +
P[0][18]*SH_MAG[1] -
P[1][18]*SH_MAG[2] +
P[3][18]*SH_MAG[0] +
P[18][18]*(SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6]) +
P[16][18]*(2.0f*q0*q2 + 2.0f*q1*
q3) -
P[17][18]*(2.0
f*q0*q1 - 2.0
f*q2*q3) +
P[2][18]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2)) +
P[2][21]*(SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2));
430 for (uint8_t i = 0; i<=2; i++) {
442 for (obsIndex = 0; obsIndex <= 2; obsIndex++) {
447 H_MAG[0] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2;
448 H_MAG[1] = SH_MAG[0];
449 H_MAG[2] = -SH_MAG[1];
450 H_MAG[3] = SH_MAG[2];
451 H_MAG[16] = SH_MAG[5] - SH_MAG[4] - SH_MAG[3] + SH_MAG[6];
452 H_MAG[17] = 2.0f*q0*q3 + 2.0f*q1*
q2;
453 H_MAG[18] = 2.0f*q1*q3 - 2.0f*q0*
q2;
458 SK_MX[1] = SH_MAG[3] + SH_MAG[4] - SH_MAG[5] - SH_MAG[6];
459 SK_MX[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2;
460 SK_MX[3] = 2.0f*q0*q2 - 2.0f*q1*
q3;
461 SK_MX[4] = 2.0f*q0*q3 + 2.0f*q1*
q2;
463 Kfusion[0] = SK_MX[0]*(
P[0][19] +
P[0][1]*SH_MAG[0] -
P[0][2]*SH_MAG[1] +
P[0][3]*SH_MAG[2] +
P[0][0]*SK_MX[2] -
P[0][16]*SK_MX[1] +
P[0][17]*SK_MX[4] -
P[0][18]*SK_MX[3]);
464 Kfusion[1] = SK_MX[0]*(
P[1][19] +
P[1][1]*SH_MAG[0] -
P[1][2]*SH_MAG[1] +
P[1][3]*SH_MAG[2] +
P[1][0]*SK_MX[2] -
P[1][16]*SK_MX[1] +
P[1][17]*SK_MX[4] -
P[1][18]*SK_MX[3]);
465 Kfusion[2] = SK_MX[0]*(
P[2][19] +
P[2][1]*SH_MAG[0] -
P[2][2]*SH_MAG[1] +
P[2][3]*SH_MAG[2] +
P[2][0]*SK_MX[2] -
P[2][16]*SK_MX[1] +
P[2][17]*SK_MX[4] -
P[2][18]*SK_MX[3]);
466 Kfusion[3] = SK_MX[0]*(
P[3][19] +
P[3][1]*SH_MAG[0] -
P[3][2]*SH_MAG[1] +
P[3][3]*SH_MAG[2] +
P[3][0]*SK_MX[2] -
P[3][16]*SK_MX[1] +
P[3][17]*SK_MX[4] -
P[3][18]*SK_MX[3]);
467 Kfusion[4] = SK_MX[0]*(
P[4][19] +
P[4][1]*SH_MAG[0] -
P[4][2]*SH_MAG[1] +
P[4][3]*SH_MAG[2] +
P[4][0]*SK_MX[2] -
P[4][16]*SK_MX[1] +
P[4][17]*SK_MX[4] -
P[4][18]*SK_MX[3]);
468 Kfusion[5] = SK_MX[0]*(
P[5][19] +
P[5][1]*SH_MAG[0] -
P[5][2]*SH_MAG[1] +
P[5][3]*SH_MAG[2] +
P[5][0]*SK_MX[2] -
P[5][16]*SK_MX[1] +
P[5][17]*SK_MX[4] -
P[5][18]*SK_MX[3]);
469 Kfusion[6] = SK_MX[0]*(
P[6][19] +
P[6][1]*SH_MAG[0] -
P[6][2]*SH_MAG[1] +
P[6][3]*SH_MAG[2] +
P[6][0]*SK_MX[2] -
P[6][16]*SK_MX[1] +
P[6][17]*SK_MX[4] -
P[6][18]*SK_MX[3]);
470 Kfusion[7] = SK_MX[0]*(
P[7][19] +
P[7][1]*SH_MAG[0] -
P[7][2]*SH_MAG[1] +
P[7][3]*SH_MAG[2] +
P[7][0]*SK_MX[2] -
P[7][16]*SK_MX[1] +
P[7][17]*SK_MX[4] -
P[7][18]*SK_MX[3]);
471 Kfusion[8] = SK_MX[0]*(
P[8][19] +
P[8][1]*SH_MAG[0] -
P[8][2]*SH_MAG[1] +
P[8][3]*SH_MAG[2] +
P[8][0]*SK_MX[2] -
P[8][16]*SK_MX[1] +
P[8][17]*SK_MX[4] -
P[8][18]*SK_MX[3]);
472 Kfusion[9] = SK_MX[0]*(
P[9][19] +
P[9][1]*SH_MAG[0] -
P[9][2]*SH_MAG[1] +
P[9][3]*SH_MAG[2] +
P[9][0]*SK_MX[2] -
P[9][16]*SK_MX[1] +
P[9][17]*SK_MX[4] -
P[9][18]*SK_MX[3]);
475 Kfusion[10] = SK_MX[0]*(
P[10][19] +
P[10][1]*SH_MAG[0] -
P[10][2]*SH_MAG[1] +
P[10][3]*SH_MAG[2] +
P[10][0]*SK_MX[2] -
P[10][16]*SK_MX[1] +
P[10][17]*SK_MX[4] -
P[10][18]*SK_MX[3]);
476 Kfusion[11] = SK_MX[0]*(
P[11][19] +
P[11][1]*SH_MAG[0] -
P[11][2]*SH_MAG[1] +
P[11][3]*SH_MAG[2] +
P[11][0]*SK_MX[2] -
P[11][16]*SK_MX[1] +
P[11][17]*SK_MX[4] -
P[11][18]*SK_MX[3]);
477 Kfusion[12] = SK_MX[0]*(
P[12][19] +
P[12][1]*SH_MAG[0] -
P[12][2]*SH_MAG[1] +
P[12][3]*SH_MAG[2] +
P[12][0]*SK_MX[2] -
P[12][16]*SK_MX[1] +
P[12][17]*SK_MX[4] -
P[12][18]*SK_MX[3]);
480 memset(&Kfusion[10], 0, 12);
484 Kfusion[13] = SK_MX[0]*(
P[13][19] +
P[13][1]*SH_MAG[0] -
P[13][2]*SH_MAG[1] +
P[13][3]*SH_MAG[2] +
P[13][0]*SK_MX[2] -
P[13][16]*SK_MX[1] +
P[13][17]*SK_MX[4] -
P[13][18]*SK_MX[3]);
485 Kfusion[14] = SK_MX[0]*(
P[14][19] +
P[14][1]*SH_MAG[0] -
P[14][2]*SH_MAG[1] +
P[14][3]*SH_MAG[2] +
P[14][0]*SK_MX[2] -
P[14][16]*SK_MX[1] +
P[14][17]*SK_MX[4] -
P[14][18]*SK_MX[3]);
486 Kfusion[15] = SK_MX[0]*(
P[15][19] +
P[15][1]*SH_MAG[0] -
P[15][2]*SH_MAG[1] +
P[15][3]*SH_MAG[2] +
P[15][0]*SK_MX[2] -
P[15][16]*SK_MX[1] +
P[15][17]*SK_MX[4] -
P[15][18]*SK_MX[3]);
489 memset(&Kfusion[13], 0, 12);
493 Kfusion[16] = SK_MX[0]*(
P[16][19] +
P[16][1]*SH_MAG[0] -
P[16][2]*SH_MAG[1] +
P[16][3]*SH_MAG[2] +
P[16][0]*SK_MX[2] -
P[16][16]*SK_MX[1] +
P[16][17]*SK_MX[4] -
P[16][18]*SK_MX[3]);
494 Kfusion[17] = SK_MX[0]*(
P[17][19] +
P[17][1]*SH_MAG[0] -
P[17][2]*SH_MAG[1] +
P[17][3]*SH_MAG[2] +
P[17][0]*SK_MX[2] -
P[17][16]*SK_MX[1] +
P[17][17]*SK_MX[4] -
P[17][18]*SK_MX[3]);
495 Kfusion[18] = SK_MX[0]*(
P[18][19] +
P[18][1]*SH_MAG[0] -
P[18][2]*SH_MAG[1] +
P[18][3]*SH_MAG[2] +
P[18][0]*SK_MX[2] -
P[18][16]*SK_MX[1] +
P[18][17]*SK_MX[4] -
P[18][18]*SK_MX[3]);
496 Kfusion[19] = SK_MX[0]*(
P[19][19] +
P[19][1]*SH_MAG[0] -
P[19][2]*SH_MAG[1] +
P[19][3]*SH_MAG[2] +
P[19][0]*SK_MX[2] -
P[19][16]*SK_MX[1] +
P[19][17]*SK_MX[4] -
P[19][18]*SK_MX[3]);
497 Kfusion[20] = SK_MX[0]*(
P[20][19] +
P[20][1]*SH_MAG[0] -
P[20][2]*SH_MAG[1] +
P[20][3]*SH_MAG[2] +
P[20][0]*SK_MX[2] -
P[20][16]*SK_MX[1] +
P[20][17]*SK_MX[4] -
P[20][18]*SK_MX[3]);
498 Kfusion[21] = SK_MX[0]*(
P[21][19] +
P[21][1]*SH_MAG[0] -
P[21][2]*SH_MAG[1] +
P[21][3]*SH_MAG[2] +
P[21][0]*SK_MX[2] -
P[21][16]*SK_MX[1] +
P[21][17]*SK_MX[4] -
P[21][18]*SK_MX[3]);
501 memset(&Kfusion[16], 0, 24);
506 Kfusion[22] = SK_MX[0]*(
P[22][19] +
P[22][1]*SH_MAG[0] -
P[22][2]*SH_MAG[1] +
P[22][3]*SH_MAG[2] +
P[22][0]*SK_MX[2] -
P[22][16]*SK_MX[1] +
P[22][17]*SK_MX[4] -
P[22][18]*SK_MX[3]);
507 Kfusion[23] = SK_MX[0]*(
P[23][19] +
P[23][1]*SH_MAG[0] -
P[23][2]*SH_MAG[1] +
P[23][3]*SH_MAG[2] +
P[23][0]*SK_MX[2] -
P[23][16]*SK_MX[1] +
P[23][17]*SK_MX[4] -
P[23][18]*SK_MX[3]);
510 memset(&Kfusion[22], 0, 8);
518 }
else if (obsIndex == 1) {
522 H_MAG[0] = SH_MAG[2];
523 H_MAG[1] = SH_MAG[1];
524 H_MAG[2] = SH_MAG[0];
525 H_MAG[3] = 2.0f*magD*q2 - SH_MAG[8] - SH_MAG[7];
526 H_MAG[16] = 2.0f*q1*q2 - 2.0f*q0*
q3;
527 H_MAG[17] = SH_MAG[4] - SH_MAG[3] - SH_MAG[5] + SH_MAG[6];
528 H_MAG[18] = 2.0f*q0*q1 + 2.0f*q2*
q3;
533 SK_MY[1] = SH_MAG[3] - SH_MAG[4] + SH_MAG[5] - SH_MAG[6];
534 SK_MY[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2;
535 SK_MY[3] = 2.0f*q0*q3 - 2.0f*q1*
q2;
536 SK_MY[4] = 2.0f*q0*q1 + 2.0f*q2*
q3;
538 Kfusion[0] = SK_MY[0]*(
P[0][20] +
P[0][0]*SH_MAG[2] +
P[0][1]*SH_MAG[1] +
P[0][2]*SH_MAG[0] -
P[0][3]*SK_MY[2] -
P[0][17]*SK_MY[1] -
P[0][16]*SK_MY[3] +
P[0][18]*SK_MY[4]);
539 Kfusion[1] = SK_MY[0]*(
P[1][20] +
P[1][0]*SH_MAG[2] +
P[1][1]*SH_MAG[1] +
P[1][2]*SH_MAG[0] -
P[1][3]*SK_MY[2] -
P[1][17]*SK_MY[1] -
P[1][16]*SK_MY[3] +
P[1][18]*SK_MY[4]);
540 Kfusion[2] = SK_MY[0]*(
P[2][20] +
P[2][0]*SH_MAG[2] +
P[2][1]*SH_MAG[1] +
P[2][2]*SH_MAG[0] -
P[2][3]*SK_MY[2] -
P[2][17]*SK_MY[1] -
P[2][16]*SK_MY[3] +
P[2][18]*SK_MY[4]);
541 Kfusion[3] = SK_MY[0]*(
P[3][20] +
P[3][0]*SH_MAG[2] +
P[3][1]*SH_MAG[1] +
P[3][2]*SH_MAG[0] -
P[3][3]*SK_MY[2] -
P[3][17]*SK_MY[1] -
P[3][16]*SK_MY[3] +
P[3][18]*SK_MY[4]);
542 Kfusion[4] = SK_MY[0]*(
P[4][20] +
P[4][0]*SH_MAG[2] +
P[4][1]*SH_MAG[1] +
P[4][2]*SH_MAG[0] -
P[4][3]*SK_MY[2] -
P[4][17]*SK_MY[1] -
P[4][16]*SK_MY[3] +
P[4][18]*SK_MY[4]);
543 Kfusion[5] = SK_MY[0]*(
P[5][20] +
P[5][0]*SH_MAG[2] +
P[5][1]*SH_MAG[1] +
P[5][2]*SH_MAG[0] -
P[5][3]*SK_MY[2] -
P[5][17]*SK_MY[1] -
P[5][16]*SK_MY[3] +
P[5][18]*SK_MY[4]);
544 Kfusion[6] = SK_MY[0]*(
P[6][20] +
P[6][0]*SH_MAG[2] +
P[6][1]*SH_MAG[1] +
P[6][2]*SH_MAG[0] -
P[6][3]*SK_MY[2] -
P[6][17]*SK_MY[1] -
P[6][16]*SK_MY[3] +
P[6][18]*SK_MY[4]);
545 Kfusion[7] = SK_MY[0]*(
P[7][20] +
P[7][0]*SH_MAG[2] +
P[7][1]*SH_MAG[1] +
P[7][2]*SH_MAG[0] -
P[7][3]*SK_MY[2] -
P[7][17]*SK_MY[1] -
P[7][16]*SK_MY[3] +
P[7][18]*SK_MY[4]);
546 Kfusion[8] = SK_MY[0]*(
P[8][20] +
P[8][0]*SH_MAG[2] +
P[8][1]*SH_MAG[1] +
P[8][2]*SH_MAG[0] -
P[8][3]*SK_MY[2] -
P[8][17]*SK_MY[1] -
P[8][16]*SK_MY[3] +
P[8][18]*SK_MY[4]);
547 Kfusion[9] = SK_MY[0]*(
P[9][20] +
P[9][0]*SH_MAG[2] +
P[9][1]*SH_MAG[1] +
P[9][2]*SH_MAG[0] -
P[9][3]*SK_MY[2] -
P[9][17]*SK_MY[1] -
P[9][16]*SK_MY[3] +
P[9][18]*SK_MY[4]);
550 Kfusion[10] = SK_MY[0]*(
P[10][20] +
P[10][0]*SH_MAG[2] +
P[10][1]*SH_MAG[1] +
P[10][2]*SH_MAG[0] -
P[10][3]*SK_MY[2] -
P[10][17]*SK_MY[1] -
P[10][16]*SK_MY[3] +
P[10][18]*SK_MY[4]);
551 Kfusion[11] = SK_MY[0]*(
P[11][20] +
P[11][0]*SH_MAG[2] +
P[11][1]*SH_MAG[1] +
P[11][2]*SH_MAG[0] -
P[11][3]*SK_MY[2] -
P[11][17]*SK_MY[1] -
P[11][16]*SK_MY[3] +
P[11][18]*SK_MY[4]);
552 Kfusion[12] = SK_MY[0]*(
P[12][20] +
P[12][0]*SH_MAG[2] +
P[12][1]*SH_MAG[1] +
P[12][2]*SH_MAG[0] -
P[12][3]*SK_MY[2] -
P[12][17]*SK_MY[1] -
P[12][16]*SK_MY[3] +
P[12][18]*SK_MY[4]);
555 memset(&Kfusion[10], 0, 12);
559 Kfusion[13] = SK_MY[0]*(
P[13][20] +
P[13][0]*SH_MAG[2] +
P[13][1]*SH_MAG[1] +
P[13][2]*SH_MAG[0] -
P[13][3]*SK_MY[2] -
P[13][17]*SK_MY[1] -
P[13][16]*SK_MY[3] +
P[13][18]*SK_MY[4]);
560 Kfusion[14] = SK_MY[0]*(
P[14][20] +
P[14][0]*SH_MAG[2] +
P[14][1]*SH_MAG[1] +
P[14][2]*SH_MAG[0] -
P[14][3]*SK_MY[2] -
P[14][17]*SK_MY[1] -
P[14][16]*SK_MY[3] +
P[14][18]*SK_MY[4]);
561 Kfusion[15] = SK_MY[0]*(
P[15][20] +
P[15][0]*SH_MAG[2] +
P[15][1]*SH_MAG[1] +
P[15][2]*SH_MAG[0] -
P[15][3]*SK_MY[2] -
P[15][17]*SK_MY[1] -
P[15][16]*SK_MY[3] +
P[15][18]*SK_MY[4]);
564 memset(&Kfusion[13], 0, 12);
569 Kfusion[16] = SK_MY[0]*(
P[16][20] +
P[16][0]*SH_MAG[2] +
P[16][1]*SH_MAG[1] +
P[16][2]*SH_MAG[0] -
P[16][3]*SK_MY[2] -
P[16][17]*SK_MY[1] -
P[16][16]*SK_MY[3] +
P[16][18]*SK_MY[4]);
570 Kfusion[17] = SK_MY[0]*(
P[17][20] +
P[17][0]*SH_MAG[2] +
P[17][1]*SH_MAG[1] +
P[17][2]*SH_MAG[0] -
P[17][3]*SK_MY[2] -
P[17][17]*SK_MY[1] -
P[17][16]*SK_MY[3] +
P[17][18]*SK_MY[4]);
571 Kfusion[18] = SK_MY[0]*(
P[18][20] +
P[18][0]*SH_MAG[2] +
P[18][1]*SH_MAG[1] +
P[18][2]*SH_MAG[0] -
P[18][3]*SK_MY[2] -
P[18][17]*SK_MY[1] -
P[18][16]*SK_MY[3] +
P[18][18]*SK_MY[4]);
572 Kfusion[19] = SK_MY[0]*(
P[19][20] +
P[19][0]*SH_MAG[2] +
P[19][1]*SH_MAG[1] +
P[19][2]*SH_MAG[0] -
P[19][3]*SK_MY[2] -
P[19][17]*SK_MY[1] -
P[19][16]*SK_MY[3] +
P[19][18]*SK_MY[4]);
573 Kfusion[20] = SK_MY[0]*(
P[20][20] +
P[20][0]*SH_MAG[2] +
P[20][1]*SH_MAG[1] +
P[20][2]*SH_MAG[0] -
P[20][3]*SK_MY[2] -
P[20][17]*SK_MY[1] -
P[20][16]*SK_MY[3] +
P[20][18]*SK_MY[4]);
574 Kfusion[21] = SK_MY[0]*(
P[21][20] +
P[21][0]*SH_MAG[2] +
P[21][1]*SH_MAG[1] +
P[21][2]*SH_MAG[0] -
P[21][3]*SK_MY[2] -
P[21][17]*SK_MY[1] -
P[21][16]*SK_MY[3] +
P[21][18]*SK_MY[4]);
577 memset(&Kfusion[16], 0, 24);
582 Kfusion[22] = SK_MY[0]*(
P[22][20] +
P[22][0]*SH_MAG[2] +
P[22][1]*SH_MAG[1] +
P[22][2]*SH_MAG[0] -
P[22][3]*SK_MY[2] -
P[22][17]*SK_MY[1] -
P[22][16]*SK_MY[3] +
P[22][18]*SK_MY[4]);
583 Kfusion[23] = SK_MY[0]*(
P[23][20] +
P[23][0]*SH_MAG[2] +
P[23][1]*SH_MAG[1] +
P[23][2]*SH_MAG[0] -
P[23][3]*SK_MY[2] -
P[23][17]*SK_MY[1] -
P[23][16]*SK_MY[3] +
P[23][18]*SK_MY[4]);
586 memset(&Kfusion[22], 0, 8);
594 else if (obsIndex == 2)
598 H_MAG[0] = SH_MAG[1];
599 H_MAG[1] = -SH_MAG[2];
600 H_MAG[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2;
601 H_MAG[3] = SH_MAG[0];
602 H_MAG[16] = 2.0f*q0*q2 + 2.0f*q1*
q3;
603 H_MAG[17] = 2.0f*q2*q3 - 2.0f*q0*
q1;
604 H_MAG[18] = SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6];
609 SK_MZ[1] = SH_MAG[3] - SH_MAG[4] - SH_MAG[5] + SH_MAG[6];
610 SK_MZ[2] = SH_MAG[7] + SH_MAG[8] - 2.0f*magD*
q2;
611 SK_MZ[3] = 2.0f*q0*q1 - 2.0f*q2*
q3;
612 SK_MZ[4] = 2.0f*q0*q2 + 2.0f*q1*
q3;
614 Kfusion[0] = SK_MZ[0]*(
P[0][21] +
P[0][0]*SH_MAG[1] -
P[0][1]*SH_MAG[2] +
P[0][3]*SH_MAG[0] +
P[0][2]*SK_MZ[2] +
P[0][18]*SK_MZ[1] +
P[0][16]*SK_MZ[4] -
P[0][17]*SK_MZ[3]);
615 Kfusion[1] = SK_MZ[0]*(
P[1][21] +
P[1][0]*SH_MAG[1] -
P[1][1]*SH_MAG[2] +
P[1][3]*SH_MAG[0] +
P[1][2]*SK_MZ[2] +
P[1][18]*SK_MZ[1] +
P[1][16]*SK_MZ[4] -
P[1][17]*SK_MZ[3]);
616 Kfusion[2] = SK_MZ[0]*(
P[2][21] +
P[2][0]*SH_MAG[1] -
P[2][1]*SH_MAG[2] +
P[2][3]*SH_MAG[0] +
P[2][2]*SK_MZ[2] +
P[2][18]*SK_MZ[1] +
P[2][16]*SK_MZ[4] -
P[2][17]*SK_MZ[3]);
617 Kfusion[3] = SK_MZ[0]*(
P[3][21] +
P[3][0]*SH_MAG[1] -
P[3][1]*SH_MAG[2] +
P[3][3]*SH_MAG[0] +
P[3][2]*SK_MZ[2] +
P[3][18]*SK_MZ[1] +
P[3][16]*SK_MZ[4] -
P[3][17]*SK_MZ[3]);
618 Kfusion[4] = SK_MZ[0]*(
P[4][21] +
P[4][0]*SH_MAG[1] -
P[4][1]*SH_MAG[2] +
P[4][3]*SH_MAG[0] +
P[4][2]*SK_MZ[2] +
P[4][18]*SK_MZ[1] +
P[4][16]*SK_MZ[4] -
P[4][17]*SK_MZ[3]);
619 Kfusion[5] = SK_MZ[0]*(
P[5][21] +
P[5][0]*SH_MAG[1] -
P[5][1]*SH_MAG[2] +
P[5][3]*SH_MAG[0] +
P[5][2]*SK_MZ[2] +
P[5][18]*SK_MZ[1] +
P[5][16]*SK_MZ[4] -
P[5][17]*SK_MZ[3]);
620 Kfusion[6] = SK_MZ[0]*(
P[6][21] +
P[6][0]*SH_MAG[1] -
P[6][1]*SH_MAG[2] +
P[6][3]*SH_MAG[0] +
P[6][2]*SK_MZ[2] +
P[6][18]*SK_MZ[1] +
P[6][16]*SK_MZ[4] -
P[6][17]*SK_MZ[3]);
621 Kfusion[7] = SK_MZ[0]*(
P[7][21] +
P[7][0]*SH_MAG[1] -
P[7][1]*SH_MAG[2] +
P[7][3]*SH_MAG[0] +
P[7][2]*SK_MZ[2] +
P[7][18]*SK_MZ[1] +
P[7][16]*SK_MZ[4] -
P[7][17]*SK_MZ[3]);
622 Kfusion[8] = SK_MZ[0]*(
P[8][21] +
P[8][0]*SH_MAG[1] -
P[8][1]*SH_MAG[2] +
P[8][3]*SH_MAG[0] +
P[8][2]*SK_MZ[2] +
P[8][18]*SK_MZ[1] +
P[8][16]*SK_MZ[4] -
P[8][17]*SK_MZ[3]);
623 Kfusion[9] = SK_MZ[0]*(
P[9][21] +
P[9][0]*SH_MAG[1] -
P[9][1]*SH_MAG[2] +
P[9][3]*SH_MAG[0] +
P[9][2]*SK_MZ[2] +
P[9][18]*SK_MZ[1] +
P[9][16]*SK_MZ[4] -
P[9][17]*SK_MZ[3]);
626 Kfusion[10] = SK_MZ[0]*(
P[10][21] +
P[10][0]*SH_MAG[1] -
P[10][1]*SH_MAG[2] +
P[10][3]*SH_MAG[0] +
P[10][2]*SK_MZ[2] +
P[10][18]*SK_MZ[1] +
P[10][16]*SK_MZ[4] -
P[10][17]*SK_MZ[3]);
627 Kfusion[11] = SK_MZ[0]*(
P[11][21] +
P[11][0]*SH_MAG[1] -
P[11][1]*SH_MAG[2] +
P[11][3]*SH_MAG[0] +
P[11][2]*SK_MZ[2] +
P[11][18]*SK_MZ[1] +
P[11][16]*SK_MZ[4] -
P[11][17]*SK_MZ[3]);
628 Kfusion[12] = SK_MZ[0]*(
P[12][21] +
P[12][0]*SH_MAG[1] -
P[12][1]*SH_MAG[2] +
P[12][3]*SH_MAG[0] +
P[12][2]*SK_MZ[2] +
P[12][18]*SK_MZ[1] +
P[12][16]*SK_MZ[4] -
P[12][17]*SK_MZ[3]);
631 memset(&Kfusion[10], 0, 12);
635 Kfusion[13] = SK_MZ[0]*(
P[13][21] +
P[13][0]*SH_MAG[1] -
P[13][1]*SH_MAG[2] +
P[13][3]*SH_MAG[0] +
P[13][2]*SK_MZ[2] +
P[13][18]*SK_MZ[1] +
P[13][16]*SK_MZ[4] -
P[13][17]*SK_MZ[3]);
636 Kfusion[14] = SK_MZ[0]*(
P[14][21] +
P[14][0]*SH_MAG[1] -
P[14][1]*SH_MAG[2] +
P[14][3]*SH_MAG[0] +
P[14][2]*SK_MZ[2] +
P[14][18]*SK_MZ[1] +
P[14][16]*SK_MZ[4] -
P[14][17]*SK_MZ[3]);
637 Kfusion[15] = SK_MZ[0]*(
P[15][21] +
P[15][0]*SH_MAG[1] -
P[15][1]*SH_MAG[2] +
P[15][3]*SH_MAG[0] +
P[15][2]*SK_MZ[2] +
P[15][18]*SK_MZ[1] +
P[15][16]*SK_MZ[4] -
P[15][17]*SK_MZ[3]);
640 memset(&Kfusion[13], 0, 12);
645 Kfusion[16] = SK_MZ[0]*(
P[16][21] +
P[16][0]*SH_MAG[1] -
P[16][1]*SH_MAG[2] +
P[16][3]*SH_MAG[0] +
P[16][2]*SK_MZ[2] +
P[16][18]*SK_MZ[1] +
P[16][16]*SK_MZ[4] -
P[16][17]*SK_MZ[3]);
646 Kfusion[17] = SK_MZ[0]*(
P[17][21] +
P[17][0]*SH_MAG[1] -
P[17][1]*SH_MAG[2] +
P[17][3]*SH_MAG[0] +
P[17][2]*SK_MZ[2] +
P[17][18]*SK_MZ[1] +
P[17][16]*SK_MZ[4] -
P[17][17]*SK_MZ[3]);
647 Kfusion[18] = SK_MZ[0]*(
P[18][21] +
P[18][0]*SH_MAG[1] -
P[18][1]*SH_MAG[2] +
P[18][3]*SH_MAG[0] +
P[18][2]*SK_MZ[2] +
P[18][18]*SK_MZ[1] +
P[18][16]*SK_MZ[4] -
P[18][17]*SK_MZ[3]);
648 Kfusion[19] = SK_MZ[0]*(
P[19][21] +
P[19][0]*SH_MAG[1] -
P[19][1]*SH_MAG[2] +
P[19][3]*SH_MAG[0] +
P[19][2]*SK_MZ[2] +
P[19][18]*SK_MZ[1] +
P[19][16]*SK_MZ[4] -
P[19][17]*SK_MZ[3]);
649 Kfusion[20] = SK_MZ[0]*(
P[20][21] +
P[20][0]*SH_MAG[1] -
P[20][1]*SH_MAG[2] +
P[20][3]*SH_MAG[0] +
P[20][2]*SK_MZ[2] +
P[20][18]*SK_MZ[1] +
P[20][16]*SK_MZ[4] -
P[20][17]*SK_MZ[3]);
650 Kfusion[21] = SK_MZ[0]*(
P[21][21] +
P[21][0]*SH_MAG[1] -
P[21][1]*SH_MAG[2] +
P[21][3]*SH_MAG[0] +
P[21][2]*SK_MZ[2] +
P[21][18]*SK_MZ[1] +
P[21][16]*SK_MZ[4] -
P[21][17]*SK_MZ[3]);
653 memset(&Kfusion[16], 0, 24);
658 Kfusion[22] = SK_MZ[0]*(
P[22][21] +
P[22][0]*SH_MAG[1] -
P[22][1]*SH_MAG[2] +
P[22][3]*SH_MAG[0] +
P[22][2]*SK_MZ[2] +
P[22][18]*SK_MZ[1] +
P[22][16]*SK_MZ[4] -
P[22][17]*SK_MZ[3]);
659 Kfusion[23] = SK_MZ[0]*(
P[23][21] +
P[23][0]*SH_MAG[1] -
P[23][1]*SH_MAG[2] +
P[23][3]*SH_MAG[0] +
P[23][2]*SK_MZ[2] +
P[23][18]*SK_MZ[1] +
P[23][16]*SK_MZ[4] -
P[23][17]*SK_MZ[3]);
662 memset(&Kfusion[22], 0, 8);
673 for (
unsigned j = 0; j<=3; j++) {
676 for (
unsigned j = 4; j<=15; j++) {
679 for (
unsigned j = 16; j<=21; j++) {
682 for (
unsigned j = 22; j<=23; j++) {
689 res +=
KH[i][0] *
P[0][j];
690 res +=
KH[i][1] * P[1][j];
691 res +=
KH[i][2] * P[2][j];
692 res +=
KH[i][3] * P[3][j];
693 res +=
KH[i][16] * P[16][j];
694 res +=
KH[i][17] * P[17][j];
695 res +=
KH[i][18] * P[18][j];
696 res +=
KH[i][19] * P[19][j];
697 res +=
KH[i][20] * P[20][j];
698 res +=
KH[i][21] * P[21][j];
703 bool healthyFusion =
true;
705 if (
KHP[i][i] >
P[i][i]) {
706 healthyFusion =
false;
713 P[i][j] =
P[i][j] -
KHP[i][j];
731 }
else if (obsIndex == 1) {
733 }
else if (obsIndex == 2) {
776 float t7 = t3+t4-t5-
t6;
784 float t12 = t8*t11*4.0f;
785 float t13 = t12+1.0f;
787 if (fabsf(t13) > 1e-6
f) {
793 H_YAW[0] = t8*t14*(q3*t3-q3*t4+q3*t5+q3*t6+q0*q1*q2*2.0f)*-2.0
f;
794 H_YAW[1] = t8*t14*(-q2*t3+q2*t4+q2*t5+q2*t6+q0*q1*q3*2.0f)*-2.0
f;
795 H_YAW[2] = t8*t14*(q1*t3+q1*t4+q1*t5-q1*t6+q0*q2*q3*2.0f)*2.0
f;
796 H_YAW[3] = t8*t14*(q0*t3+q0*t4-q0*t5+q0*t6+q1*q2*q3*2.0f)*2.0
f;
801 predicted_yaw = euler321.z;
804 Tbn_zeroYaw.
from_euler(euler321.x, euler321.y, 0.0f);
815 float t7 = t3-t4+t5-
t6;
823 float t12 = t8*t11*4.0f;
824 float t13 = t12+1.0f;
826 if (fabsf(t13) > 1e-6
f) {
832 H_YAW[0] = t8*t14*(q3*t3+q3*t4-q3*t5+q3*t6-q0*q1*q2*2.0f)*-2.0
f;
833 H_YAW[1] = t8*t14*(q2*t3+q2*t4+q2*t5-q2*t6-q0*q1*q3*2.0f)*-2.0
f;
834 H_YAW[2] = t8*t14*(-q1*t3+q1*t4+q1*t5+q1*t6-q0*q2*q3*2.0f)*2.0
f;
835 H_YAW[3] = t8*t14*(q0*t3-q0*t4+q0*t5+q0*t6-q1*q2*q3*2.0f)*2.0
f;
839 predicted_yaw = euler312.
z;
855 measured_yaw = predicted_yaw;
859 float innovation =
wrap_PI(predicted_yaw - measured_yaw);
866 float varInnov = R_YAW;
867 for (uint8_t rowIndex=0; rowIndex<=3; rowIndex++) {
869 for (uint8_t colIndex=0; colIndex<=3; colIndex++) {
870 PH[rowIndex] +=
P[rowIndex][colIndex]*H_YAW[colIndex];
872 varInnov += H_YAW[rowIndex]*PH[rowIndex];
875 if (varInnov >= R_YAW) {
876 varInnovInv = 1.0f / varInnov;
889 for (uint8_t rowIndex=0; rowIndex<=
stateIndexLim; rowIndex++) {
891 for (uint8_t colIndex=0; colIndex<=3; colIndex++) {
892 Kfusion[rowIndex] +=
P[rowIndex][colIndex]*H_YAW[colIndex];
894 Kfusion[rowIndex] *= varInnovInv;
913 if (innovation > 0.5
f) {
915 }
else if (innovation < -0.5
f) {
922 for (uint8_t column = 0; column <= 3; column++) {
923 KH[row][column] =
Kfusion[row] * H_YAW[column];
927 for (uint8_t column = 0; column <=
stateIndexLim; column++) {
928 float tmp =
KH[row][0] *
P[0][column];
929 tmp +=
KH[row][1] * P[1][column];
930 tmp +=
KH[row][2] * P[2][column];
931 tmp +=
KH[row][3] * P[3][column];
932 KHP[row][column] = tmp;
937 bool healthyFusion =
true;
939 if (
KHP[i][i] >
P[i][i]) {
940 healthyFusion =
false;
947 P[i][j] =
P[i][j] -
KHP[i][j];
980 const float R_DECL =
sq(declErr);
1000 float t5 =
P[16][16]*
t2;
1001 float t6 =
P[17][17]*
t3;
1003 float t8 = R_DECL*
t7;
1005 float t10 = R_DECL*
t9;
1006 float t11 = R_DECL*t2*t3*2.0f;
1009 float t12 = t5+t6+t8+t10+t11-t14-
t15;
1011 if (fabsf(t12) > 1e-6
f) {
1020 if (fabsf(t20) > 1e-6
f) {
1028 float H_DECL[24] = {};
1029 H_DECL[16] = -magE*
t21;
1030 H_DECL[17] = magN*
t21;
1034 Kfusion[2] = -t4*t13*(
P[2][16]*magE-
P[2][17]*
magN);
1035 Kfusion[3] = -t4*t13*(
P[3][16]*magE-
P[3][17]*
magN);
1036 Kfusion[4] = -t4*t13*(
P[4][16]*magE-
P[4][17]*
magN);
1037 Kfusion[5] = -t4*t13*(
P[5][16]*magE-
P[5][17]*
magN);
1038 Kfusion[6] = -t4*t13*(
P[6][16]*magE-
P[6][17]*
magN);
1039 Kfusion[7] = -t4*t13*(
P[7][16]*magE-
P[7][17]*
magN);
1040 Kfusion[8] = -t4*t13*(
P[8][16]*magE-
P[8][17]*
magN);
1041 Kfusion[9] = -t4*t13*(
P[9][16]*magE-
P[9][17]*
magN);
1044 Kfusion[10] = -t4*t13*(
P[10][16]*magE-
P[10][17]*
magN);
1045 Kfusion[11] = -t4*t13*(
P[11][16]*magE-
P[11][17]*
magN);
1046 Kfusion[12] = -t4*t13*(
P[12][16]*magE-
P[12][17]*
magN);
1049 memset(&Kfusion[10], 0, 12);
1053 Kfusion[13] = -t4*t13*(
P[13][16]*magE-
P[13][17]*
magN);
1054 Kfusion[14] = -t4*t13*(
P[14][16]*magE-
P[14][17]*
magN);
1055 Kfusion[15] = -t4*t13*(
P[15][16]*magE-
P[15][17]*
magN);
1058 memset(&Kfusion[13], 0, 12);
1062 Kfusion[16] = -t4*t13*(
P[16][16]*magE-
P[16][17]*
magN);
1063 Kfusion[17] = -t4*t13*(
P[17][16]*magE-
P[17][17]*
magN);
1064 Kfusion[18] = -t4*t13*(
P[18][16]*magE-
P[18][17]*
magN);
1065 Kfusion[19] = -t4*t13*(
P[19][16]*magE-
P[19][17]*
magN);
1066 Kfusion[20] = -t4*t13*(
P[20][16]*magE-
P[20][17]*
magN);
1067 Kfusion[21] = -t4*t13*(
P[21][16]*magE-
P[21][17]*
magN);
1070 memset(&Kfusion[16], 0, 24);
1074 Kfusion[22] = -t4*t13*(
P[22][16]*magE-
P[22][17]*
magN);
1075 Kfusion[23] = -t4*t13*(
P[23][16]*magE-
P[23][17]*
magN);
1078 memset(&Kfusion[22], 0, 8);
1085 float innovation = atan2f(magE , magN) - magDecAng;
1088 if (innovation > 0.5
f) {
1090 }
else if (innovation < -0.5
f) {
1098 for (
unsigned j = 0; j<=15; j++) {
1101 KH[i][16] = Kfusion[i] * H_DECL[16];
1102 KH[i][17] = Kfusion[i] * H_DECL[17];
1103 for (
unsigned j = 18; j<=23; j++) {
1109 KHP[i][j] =
KH[i][16] *
P[16][j] +
KH[i][17] *
P[17][j];
1114 bool healthyFusion =
true;
1116 if (
KHP[i][i] >
P[i][i]) {
1117 healthyFusion =
false;
1121 if (healthyFusion) {
1125 P[i][j] =
P[i][j] -
KHP[i][j];
1164 float magLengthNE =
norm(initMagNED.
x,initMagNED.
y);
1170 float var_16 =
P[16][16];
1171 float var_17 =
P[17][17];
1199 #endif // HAL_CPU_CLASS
float norm(const T first, const U second, const Params... parameters)
void to_euler(float &roll, float &pitch, float &yaw) const
Quaternion calcQuatAndFieldStates(float roll, float pitch)
Quaternion prevQuatMagReset
gps_elements gpsDataDelayed
void zeroCols(Matrix24 &covMat, uint8_t first, uint8_t last)
AP_HAL::Util::perf_counter_t _perf_test[10]
void to_axis_angle(Vector3f &v)
float get_declination() const
bool magStateInitComplete
Quaternion quatAtLastMagReset
imu_elements imuDataDelayed
Interface definition for the various Ground Control System.
obs_ring_buffer_t< mag_elements > storedMag
bool assume_zero_sideslip(void) const
void from_euler(float roll, float pitch, float yaw)
void from_euler(float roll, float pitch, float yaw)
struct NavEKF3_core::@153 faultStatus
float posDownAtLastMagReset
static auto MAX(const A &one, const B &two) -> decltype(one > two ? one :two)
struct NavEKF3_core::state_elements & stateStruct
bool inhibitDelAngBiasStates
void zeroRows(Matrix24 &covMat, uint8_t first, uint8_t last)
const Compass * get_compass() const
bool use_compass(void) const
Vector3f calcRotVecVariances(void)
void StoreQuatRotate(Quaternion deltaQuat)
float wrap_PI(const T radian)
void FuseDeclination(float declErr)
float yawInnovAtLastMagReset
resetDataSource velResetSource
const AP_HAL::HAL & hal
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
Vector3f earthMagFieldVar
virtual void perf_end(perf_counter_t h)
bool magStateResetRequest
resetDataSource posResetSource
void send_text(MAV_SEVERITY severity, const char *fmt,...)
void controlMagYawReset()
bool inhibitDelVelBiasStates
const uint32_t magFailTimeLimit_ms
mag_elements magDataDelayed
#define EKF3_MAG_FINAL_RESET_ALT
void from_euler312(float roll, float pitch, float yaw)
float constrain_float(const float amt, const float low, const float high)
Vector3f to_vector312(void) const
virtual void perf_begin(perf_counter_t h)
static constexpr float radians(float deg)
struct NavEKF3_core::@155 mag_state
uint32_t lastSynthYawTime_ms
void alignMagStateDeclination()
const float magVarRateScale
void ConstrainVariances()
bool finalInflightMagInit
uint32_t imuSampleTime_ms
bool finalInflightYawInit
uint32_t lastHealthyMagTime_ms
void initialiseQuatCovariances(Vector3f &rotVarVec)
AP_HAL::Util::perf_counter_t _perf_FuseMagnetometer