EKF: Fix critical bug in fusion of yaw and declination observations
This bug was in the derivation and resulted from use of a tan instead of an atan operator. The derivations have been reworked and the updated auto-code has been imported as part of this patch.
// if the horizontal magnetic field is too small, this calculation will be badly conditioned
// if the horizontal magnetic field is too small, this calculation will be badly conditioned
if(fabsf(magN)<0.001f){
if(magN<0.001f){
return;
return;
}
}
floatt2=1.0f/magN;
floatt2=magE*magE;
floatt4=magE*t2;
floatt3=magN*magN;
floatt3=tanf(t4);
floatt4=t2+t3;
floatt5=t3*t3;
floatt5=1.0f/t4;
floatt6=t5+1.0f;
floatt22=magE*t5;
floatt25=t2*t6;
floatt23=magN*t5;
floatt7=1.0f/(magN*magN);
floatt6=P[16][16]*t22;
floatt26=magE*t6*t7;
floatt13=P[17][16]*t23;
floatt8=P[17][17]*t25;
floatt7=t6-t13;
floatt15=P[16][17]*t26;
floatt8=t22*t7;
floatt9=t8-t15;
floatt9=P[16][17]*t22;
floatt10=t25*t9;
floatt14=P[17][17]*t23;
floatt11=P[17][16]*t25;
floatt10=t9-t14;
floatt16=P[16][16]*t26;
floatt15=t23*t10;
floatt12=t11-t16;
floatt11=R_DECL+t8-t15;// innovation variance
floatt17=t26*t12;
floatt13=R_DECL+t10-t17;// innovation variance
// check the innovation variance calculation for a badly conditioned covariance matrix
// check the innovation variance calculation for a badly conditioned covariance matrix
if(t13>=R_DECL){
if(t11>=R_DECL){
// the innovation variance contribution from the state covariances is not negative, no fault
// the innovation variance contribution from the state covariances is not negative, no fault
_fault_status.bad_mag_decl=false;
_fault_status.bad_mag_decl=false;
@ -651,50 +654,51 @@ void Ekf::fuseDeclination()
return;
return;
}
}
floatt14=1.0f/t13;
floatt12=1.0f/t11;
floatt18=magE;
floatt19=magN;
floatt21=1.0f/t19;
floatt22=t18*t21;
floatt20=tanf(t22);
floatt23=t20*t20;
floatt24=t23+1.0f;
// Calculate the observation Jacobian
// Calculate the observation Jacobian
// Note only 2 terms are non-zero which can be used in matrix operations for calculation of Kalman gains and covariance update to significantly reduce cost
// Note only 2 terms are non-zero which can be used in matrix operations for calculation of Kalman gains and covariance update to significantly reduce cost
floatH_DECL[24]={};
floatH_DECL[24]={};
H_DECL[16]=-t18*1.0f/(t19*t19)*t24;
H_DECL[16]=-magE*t5;
H_DECL[17]=t21*t24;
H_DECL[17]=magN*t5;
// Calculate the Kalman gains
// Calculate the Kalman gains
floatKfusion[_k_num_states]={};
floatKfusion[_k_num_states]={};
Kfusion[0]=t14*(P[0][17]*t25-P[0][16]*t26);
Kfusion[0]=-t12*(P[0][16]*t22-P[0][17]*t23);
Kfusion[1]=t14*(P[1][17]*t25-P[1][16]*t26);
Kfusion[1]=-t12*(P[1][16]*t22-P[1][17]*t23);
Kfusion[2]=t14*(P[2][17]*t25-P[2][16]*t26);
Kfusion[2]=-t12*(P[2][16]*t22-P[2][17]*t23);
Kfusion[3]=t14*(P[3][17]*t25-P[3][16]*t26);
Kfusion[3]=-t12*(P[3][16]*t22-P[3][17]*t23);
Kfusion[4]=t14*(P[4][17]*t25-P[4][16]*t26);
Kfusion[4]=-t12*(P[4][16]*t22-P[4][17]*t23);
Kfusion[5]=t14*(P[5][17]*t25-P[5][16]*t26);
Kfusion[5]=-t12*(P[5][16]*t22-P[5][17]*t23);
Kfusion[6]=t14*(P[6][17]*t25-P[6][16]*t26);
Kfusion[6]=-t12*(P[6][16]*t22-P[6][17]*t23);
Kfusion[7]=t14*(P[7][17]*t25-P[7][16]*t26);
Kfusion[7]=-t12*(P[7][16]*t22-P[7][17]*t23);
Kfusion[8]=t14*(P[8][17]*t25-P[8][16]*t26);
Kfusion[8]=-t12*(P[8][16]*t22-P[8][17]*t23);
Kfusion[9]=t14*(P[9][17]*t25-P[9][16]*t26);
Kfusion[9]=-t12*(P[9][16]*t22-P[9][17]*t23);
Kfusion[10]=t14*(P[10][17]*t25-P[10][16]*t26);
Kfusion[10]=-t12*(P[10][16]*t22-P[10][17]*t23);
Kfusion[11]=t14*(P[11][17]*t25-P[11][16]*t26);
Kfusion[11]=-t12*(P[11][16]*t22-P[11][17]*t23);
Kfusion[12]=t14*(P[12][17]*t25-P[12][16]*t26);
Kfusion[12]=-t12*(P[12][16]*t22-P[12][17]*t23);
Kfusion[13]=t14*(P[13][17]*t25-P[13][16]*t26);
Kfusion[13]=-t12*(P[13][16]*t22-P[13][17]*t23);
Kfusion[14]=t14*(P[14][17]*t25-P[14][16]*t26);
Kfusion[14]=-t12*(P[14][16]*t22-P[14][17]*t23);
Kfusion[15]=t14*(P[15][17]*t25-P[15][16]*t26);
Kfusion[15]=-t12*(P[15][16]*t22-P[15][17]*t23);
Kfusion[16]=-t14*(t16-P[16][17]*t25);
Kfusion[16]=-t12*(t6-P[16][17]*t23);
Kfusion[17]=t14*(t8-P[17][16]*t26);
Kfusion[17]=t12*(t14-P[17][16]*t22);
Kfusion[18]=t14*(P[18][17]*t25-P[18][16]*t26);
Kfusion[18]=-t12*(P[18][16]*t22-P[18][17]*t23);
Kfusion[19]=t14*(P[19][17]*t25-P[19][16]*t26);
Kfusion[19]=-t12*(P[19][16]*t22-P[19][17]*t23);
Kfusion[20]=t14*(P[20][17]*t25-P[20][16]*t26);
Kfusion[20]=-t12*(P[20][16]*t22-P[20][17]*t23);
Kfusion[21]=t14*(P[21][17]*t25-P[21][16]*t26);
Kfusion[21]=-t12*(P[21][16]*t22-P[21][17]*t23);
Kfusion[22]=t14*(P[22][17]*t25-P[22][16]*t26);
Kfusion[23]=t14*(P[23][17]*t25-P[23][16]*t26);
// Don't update wind states unless we are doing wind estimation