44 #include <mathlib/mathlib.h> 82 rel_wind(0) = vn - vwn;
83 rel_wind(1) = ve - vwe;
86 rel_wind = earth_to_body * rel_wind;
89 for (uint8_t axis_index = 0; axis_index < 2; axis_index++) {
91 if (axis_index == 0) {
94 float airSpd = sqrtf((2.0
f * fabsf(mea_acc)) / (BC_inv_x * rho));
98 float Kacc = fmaxf(1e-1
f, rho * BC_inv_x * airSpd);
100 SH_ACC[0] =
sq(q0) +
sq(q1) -
sq(q2) -
sq(q3);
101 SH_ACC[1] = vn - vwn;
102 SH_ACC[2] = ve - vwe;
103 SH_ACC[3] = 2.0f*q0*q3 + 2.0f*q1*q2;
104 H_ACC[0] = -Kacc*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd);
105 H_ACC[1] = -Kacc*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd);
106 H_ACC[2] = Kacc*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd);
107 H_ACC[3] = -Kacc*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd);
108 H_ACC[4] = -Kacc*SH_ACC[0];
109 H_ACC[5] = -Kacc*SH_ACC[3];
110 H_ACC[6] = Kacc*(2.0f*q0*q2 - 2.0f*q1*q3);
111 H_ACC[22] = Kacc*SH_ACC[0];
112 H_ACC[23] = Kacc*SH_ACC[3];
113 _drag_innov_var[0] = (R_ACC + Kacc*SH_ACC[0]*(Kacc*
P[4][4]*SH_ACC[0] + Kacc*
P[5][4]*SH_ACC[3] - Kacc*
P[22][4]*SH_ACC[0] - Kacc*
P[23][4]*SH_ACC[3] - Kacc*
P[6][4]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][4]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][4]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][4]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][4]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) + Kacc*SH_ACC[3]*(Kacc*
P[4][5]*SH_ACC[0] + Kacc*
P[5][5]*SH_ACC[3] - Kacc*
P[22][5]*SH_ACC[0] - Kacc*
P[23][5]*SH_ACC[3] - Kacc*
P[6][5]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][5]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][5]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][5]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][5]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) - Kacc*SH_ACC[0]*(Kacc*
P[4][22]*SH_ACC[0] + Kacc*
P[5][22]*SH_ACC[3] - Kacc*
P[22][22]*SH_ACC[0] - Kacc*
P[23][22]*SH_ACC[3] - Kacc*
P[6][22]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][22]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][22]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][22]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][22]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) - Kacc*SH_ACC[3]*(Kacc*
P[4][23]*SH_ACC[0] + Kacc*
P[5][23]*SH_ACC[3] - Kacc*
P[22][23]*SH_ACC[0] - Kacc*
P[23][23]*SH_ACC[3] - Kacc*
P[6][23]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][23]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][23]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][23]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][23]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) - Kacc*(2.0f*q0*q2 - 2.0f*q1*q3)*(Kacc*
P[4][6]*SH_ACC[0] + Kacc*
P[5][6]*SH_ACC[3] - Kacc*
P[22][6]*SH_ACC[0] - Kacc*
P[23][6]*SH_ACC[3] - Kacc*
P[6][6]*(2.0
f*q0*q2 - 2.0
f*q1*q3) + Kacc*
P[0][6]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd) + Kacc*
P[1][6]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[2][6]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[3][6]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd)) + Kacc*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd)*(Kacc*
P[4][0]*SH_ACC[0] + Kacc*
P[5][0]*SH_ACC[3] - Kacc*
P[22][0]*SH_ACC[0] - Kacc*
P[23][0]*SH_ACC[3] - Kacc*
P[6][0]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][0]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][0]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][0]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][0]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) + Kacc*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd)*(Kacc*
P[4][1]*SH_ACC[0] + Kacc*
P[5][1]*SH_ACC[3] - Kacc*
P[22][1]*SH_ACC[0] - Kacc*
P[23][1]*SH_ACC[3] - Kacc*
P[6][1]*(2.0
f*q0*q2 - 2.0
f*q1*q3) + Kacc*
P[0][1]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd) + Kacc*
P[1][1]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[2][1]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[3][1]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd)) - Kacc*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd)*(Kacc*
P[4][2]*SH_ACC[0] + Kacc*
P[5][2]*SH_ACC[3] - Kacc*
P[22][2]*SH_ACC[0] - Kacc*
P[23][2]*SH_ACC[3] - Kacc*
P[6][2]*(2.0f*q0*q2 - 2.0f*q1*q3) + Kacc*
P[0][2]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd) + Kacc*
P[1][2]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[2][2]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[3][2]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)) + Kacc*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd)*(Kacc*
P[4][3]*SH_ACC[0] + Kacc*
P[5][3]*SH_ACC[3] - Kacc*
P[22][3]*SH_ACC[0] - Kacc*
P[23][3]*SH_ACC[3] - Kacc*
P[6][3]*(2.0
f*q0*q2 - 2.0
f*q1*q3) + Kacc*
P[0][3]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd) + Kacc*
P[1][3]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[2][3]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[3][3]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd)));
118 SK_ACC[1] = 2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd;
119 SK_ACC[2] = 2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd;
120 SK_ACC[3] = 2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd;
121 SK_ACC[4] = 2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd;
122 SK_ACC[5] = 2.0f*q0*q2 - 2.0f*q1*q3;
123 SK_ACC[6] = SH_ACC[3];
147 Kfusion[22] = -SK_ACC[0]*(Kacc*
P[22][4]*SH_ACC[0] - Kacc*
P[22][22]*SH_ACC[0] + Kacc*
P[22][0]*SK_ACC[3] - Kacc*
P[22][2]*SK_ACC[2] + Kacc*
P[22][3]*SK_ACC[1] + Kacc*
P[22][1]*SK_ACC[4] + Kacc*
P[22][5]*SK_ACC[6] - Kacc*
P[22][6]*SK_ACC[5] - Kacc*
P[22][23]*SK_ACC[6]);
148 Kfusion[23] = -SK_ACC[0]*(Kacc*
P[23][4]*SH_ACC[0] - Kacc*
P[23][22]*SH_ACC[0] + Kacc*
P[23][0]*SK_ACC[3] - Kacc*
P[23][2]*SK_ACC[2] + Kacc*
P[23][3]*SK_ACC[1] + Kacc*
P[23][1]*SK_ACC[4] + Kacc*
P[23][5]*SK_ACC[6] - Kacc*
P[23][6]*SK_ACC[5] - Kacc*
P[23][23]*SK_ACC[6]);
153 if (rel_wind(axis_index) >= 0.0f) {
160 float predAccel = -BC_inv_x * 0.5f * rho *
sq(rel_wind(axis_index)) * drag_sign;
164 }
else if (axis_index == 1) {
167 float airSpd = sqrtf((2.0
f * fabsf(mea_acc)) / (BC_inv_y * rho));
171 float Kacc = fmaxf(1e-1
f, rho * BC_inv_y * airSpd);
173 SH_ACC[0] =
sq(q0) -
sq(q1) +
sq(q2) -
sq(q3);
174 SH_ACC[1] = vn - vwn;
175 SH_ACC[2] = ve - vwe;
176 H_ACC[0] = -Kacc*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd);
177 H_ACC[1] = -Kacc*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd);
178 H_ACC[2] = -Kacc*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd);
179 H_ACC[3] = Kacc*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd);
180 H_ACC[4] = Kacc*(2.0f*q0*q3 - 2.0f*q1*q2);
181 H_ACC[5] = -Kacc*SH_ACC[0];
182 H_ACC[6] = -Kacc*(2.0f*q0*q1 + 2.0f*q2*q3);
183 H_ACC[22] = -2.0f*Kacc*(q0*q3 - q1*q2);
184 H_ACC[23] = Kacc*SH_ACC[0];
185 _drag_innov_var[1] = (R_ACC + Kacc*SH_ACC[0]*(Kacc*
P[5][5]*SH_ACC[0] - Kacc*
P[23][5]*SH_ACC[0] - Kacc*
P[4][5]*(2.0f*q0*q3 - 2.0f*q1*q2) + Kacc*
P[6][5]*(2.0
f*q0*q1 + 2.0
f*q2*q3) + 2*Kacc*
P[22][5]*(q0*q3 - q1*q2) + Kacc*
P[0][5]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd) + Kacc*
P[1][5]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[2][5]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[3][5]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)) - Kacc*SH_ACC[0]*(Kacc*
P[5][23]*SH_ACC[0] - Kacc*
P[23][23]*SH_ACC[0] - Kacc*
P[4][23]*(2.0f*q0*q3 - 2.0f*q1*q2) + Kacc*
P[6][23]*(2.0
f*q0*q1 + 2.0
f*q2*q3) + 2*Kacc*
P[22][23]*(q0*q3 - q1*q2) + Kacc*
P[0][23]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd) + Kacc*
P[1][23]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[2][23]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[3][23]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)) - Kacc*(2.0f*q0*q3 - 2.0f*q1*q2)*(Kacc*
P[5][4]*SH_ACC[0] - Kacc*
P[23][4]*SH_ACC[0] - Kacc*
P[4][4]*(2.0
f*q0*q3 - 2.0
f*q1*q2) + Kacc*
P[6][4]*(2.0f*q0*q1 + 2.0f*q2*q3) + 2*Kacc*
P[22][4]*(q0*q3 - q1*q2) + Kacc*
P[0][4]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd) + Kacc*
P[1][4]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[2][4]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[3][4]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd)) + Kacc*(2.0
f*q0*q1 + 2.0
f*q2*q3)*(Kacc*
P[5][6]*SH_ACC[0] - Kacc*
P[23][6]*SH_ACC[0] - Kacc*
P[4][6]*(2.0f*q0*q3 - 2.0f*q1*q2) + Kacc*
P[6][6]*(2.0
f*q0*q1 + 2.0
f*q2*q3) + 2*Kacc*
P[22][6]*(q0*q3 - q1*q2) + Kacc*
P[0][6]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd) + Kacc*
P[1][6]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[2][6]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[3][6]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)) + 2*Kacc*(q0*q3 - q1*q2)*(Kacc*
P[5][22]*SH_ACC[0] - Kacc*
P[23][22]*SH_ACC[0] - Kacc*
P[4][22]*(2.0
f*q0*q3 - 2.0
f*q1*q2) + Kacc*
P[6][22]*(2.0f*q0*q1 + 2.0f*q2*q3) + 2*Kacc*
P[22][22]*(q0*q3 - q1*q2) + Kacc*
P[0][22]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd) + Kacc*
P[1][22]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[2][22]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[3][22]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd)) + Kacc*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd)*(Kacc*
P[5][0]*SH_ACC[0] - Kacc*
P[23][0]*SH_ACC[0] - Kacc*
P[4][0]*(2.0f*q0*q3 - 2.0f*q1*q2) + Kacc*
P[6][0]*(2.0
f*q0*q1 + 2.0
f*q2*q3) + 2*Kacc*
P[22][0]*(q0*q3 - q1*q2) + Kacc*
P[0][0]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd) + Kacc*
P[1][0]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[2][0]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[3][0]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)) + Kacc*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd)*(Kacc*
P[5][1]*SH_ACC[0] - Kacc*
P[23][1]*SH_ACC[0] - Kacc*
P[4][1]*(2.0
f*q0*q3 - 2.0
f*q1*q2) + Kacc*
P[6][1]*(2.0f*q0*q1 + 2.0f*q2*q3) + 2*Kacc*
P[22][1]*(q0*q3 - q1*q2) + Kacc*
P[0][1]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd) + Kacc*
P[1][1]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[2][1]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[3][1]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd)) + Kacc*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd)*(Kacc*
P[5][2]*SH_ACC[0] - Kacc*
P[23][2]*SH_ACC[0] - Kacc*
P[4][2]*(2.0f*q0*q3 - 2.0f*q1*q2) + Kacc*
P[6][2]*(2.0
f*q0*q1 + 2.0
f*q2*q3) + 2*Kacc*
P[22][2]*(q0*q3 - q1*q2) + Kacc*
P[0][2]*(2.0
f*q0*SH_ACC[2] - 2.0
f*q3*SH_ACC[1] + 2.0
f*q1*vd) + Kacc*
P[1][2]*(2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd) + Kacc*
P[2][2]*(2.0
f*q1*SH_ACC[1] + 2.0
f*q2*SH_ACC[2] + 2.0
f*q3*vd) - Kacc*
P[3][2]*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)) - Kacc*(2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd)*(Kacc*
P[5][3]*SH_ACC[0] - Kacc*
P[23][3]*SH_ACC[0] - Kacc*
P[4][3]*(2.0
f*q0*q3 - 2.0
f*q1*q2) + Kacc*
P[6][3]*(2.0f*q0*q1 + 2.0f*q2*q3) + 2*Kacc*
P[22][3]*(q0*q3 - q1*q2) + Kacc*
P[0][3]*(2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd) + Kacc*
P[1][3]*(2.0
f*q2*SH_ACC[1] - 2.0
f*q1*SH_ACC[2] + 2.0
f*q0*vd) + Kacc*
P[2][3]*(2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd) - Kacc*
P[3][3]*(2.0
f*q0*SH_ACC[1] + 2.0
f*q3*SH_ACC[2] - 2.0
f*q2*vd)));
191 SK_ACC[1] = 2.0f*q0*SH_ACC[1] + 2.0f*q3*SH_ACC[2] - 2.0f*q2*vd;
192 SK_ACC[2] = 2.0f*q2*SH_ACC[1] - 2.0f*q1*SH_ACC[2] + 2.0f*q0*vd;
193 SK_ACC[3] = 2.0f*q0*SH_ACC[2] - 2.0f*q3*SH_ACC[1] + 2.0f*q1*vd;
194 SK_ACC[4] = 2.0f*q1*SH_ACC[1] + 2.0f*q2*SH_ACC[2] + 2.0f*q3*vd;
195 SK_ACC[5] = 2.0f*q0*q3 - 2.0f*q1*q2;
196 SK_ACC[6] = q0*q3 - q1*q2;
197 SK_ACC[7] = 2.0f*q0*q1 + 2.0f*q2*q3;
198 SK_ACC[8] = SH_ACC[0];
222 Kfusion[22] = -SK_ACC[0]*(Kacc*
P[22][0]*SK_ACC[3] + Kacc*
P[22][1]*SK_ACC[2] - Kacc*
P[22][3]*SK_ACC[1] + Kacc*
P[22][2]*SK_ACC[4] - Kacc*
P[22][4]*SK_ACC[5] + Kacc*
P[22][5]*SK_ACC[8] + Kacc*
P[22][6]*SK_ACC[7] + 2*Kacc*
P[22][22]*SK_ACC[6] - Kacc*
P[22][23]*SK_ACC[8]);
223 Kfusion[23] = -SK_ACC[0]*(Kacc*
P[23][0]*SK_ACC[3] + Kacc*
P[23][1]*SK_ACC[2] - Kacc*
P[23][3]*SK_ACC[1] + Kacc*
P[23][2]*SK_ACC[4] - Kacc*
P[23][4]*SK_ACC[5] + Kacc*
P[23][5]*SK_ACC[8] + Kacc*
P[23][6]*SK_ACC[7] + 2*Kacc*
P[23][22]*SK_ACC[6] - Kacc*
P[23][23]*SK_ACC[8]);
228 if (rel_wind(axis_index) >= 0.0f) {
235 float predAccel = -BC_inv_y * 0.5f * rho *
sq(rel_wind(axis_index)) * drag_sign;
251 KH[0] = Kfusion[row] * H_ACC[0];
252 KH[1] = Kfusion[row] * H_ACC[1];
253 KH[2] = Kfusion[row] * H_ACC[2];
254 KH[3] = Kfusion[row] * H_ACC[3];
255 KH[4] = Kfusion[row] * H_ACC[4];
256 KH[5] = Kfusion[row] * H_ACC[5];
257 KH[6] = Kfusion[row] * H_ACC[6];
258 KH[7] = Kfusion[row] * H_ACC[22];
259 KH[8] = Kfusion[row] * H_ACC[23];
261 for (
unsigned column = 0; column <
_k_num_states; column++) {
262 float tmp = KH[0] *
P[0][column];
263 tmp += KH[1] * P[1][column];
264 tmp += KH[2] * P[2][column];
265 tmp += KH[3] * P[3][column];
266 tmp += KH[4] * P[4][column];
267 tmp += KH[5] * P[5][column];
268 tmp += KH[6] * P[6][column];
269 tmp += KH[7] * P[22][column];
270 tmp += KH[8] * P[23][column];
271 KHP[row][column] = tmp;
281 if (
P[i][i] < KHP[i][i]) {
299 for (
unsigned column = 0; column <
_k_num_states; column++) {
300 P[row][column] =
P[row][column] - KHP[row][column];
Matrix3f quat_to_invrotmat(const Quatf &quat)
Adapter / shim layer for system calls needed by ECL.
stateSample _state
state struct of the ekf running at the delayed time horizon
Vector3f accel_bias
delta velocity bias estimate in m/s
dragSample _drag_sample_delayed
float _drag_innov[2]
multirotor drag measurement innovation (m/sec**2)
Vector2f accelXY
measured specific force along the X and Y body axes (m/sec**2)
float P[_k_num_states][_k_num_states]
state covariance matrix
void zeroCols(float(&cov_mat)[_k_num_states][_k_num_states], uint8_t first, uint8_t last)
void fuse(float *K, float innovation)
float bcoef_x
ballistic coefficient along the X-axis (kg/m**2)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
float drag_noise
observation noise variance for drag specific force measurements (m/sec**2)**2
float _drag_innov_var[2]
multirotor drag measurement innovation variance ((m/sec**2)**2)
Vector3f vel
NED velocity in earth frame in m/s.
static constexpr float sq(float var)
void fixCovarianceErrors()
float bcoef_y
ballistic coefficient along the Y-axis (kg/m**2)
Quatf quat_nominal
quaternion defining the rotation from body to earth frame
Vector3< float > Vector3f
void zeroRows(float(&cov_mat)[_k_num_states][_k_num_states], uint8_t first, uint8_t last)
float _drag_test_ratio[2]
Vector2f wind_vel
wind velocity in m/s
static constexpr uint8_t _k_num_states
number of EKF states
float _dt_ekf_avg
average update rate of the ekf
Class for core functions for ekf attitude and position estimator.