9 #include <matrix/math.hpp>
19 typedef matrix::SquareMatrix<float, EKF_AW_COV_SIZE>
EKF_Aw_Cov;
30 typedef matrix::SquareMatrix<float, EKF_AW_Q_SIZE>
EKF_Aw_Q;
40 typedef matrix::SquareMatrix<float, EKF_AW_R_SIZE>
EKF_Aw_R;
92 #ifndef EKF_AW_Q_ACCEL
93 #define EKF_AW_Q_ACCEL 1.0E-4f
96 #define EKF_AW_Q_GYRO 1.0E-09f
99 #define EKF_AW_Q_MU 1.0E-6f
101 #ifndef EKF_AW_Q_OFFSET
102 #define EKF_AW_Q_OFFSET 1.E-8f
106 #ifndef EKF_AW_P0_V_BODY
107 #define EKF_AW_P0_V_BODY 1.E-2f
110 #define EKF_AW_P0_MU EKF_AW_Q_MU*1.E1f
112 #ifndef EKF_AW_P0_OFFSET
113 #define EKF_AW_P0_OFFSET EKF_AW_Q_OFFSET
117 #ifndef EKF_AW_R_V_GND
118 #define EKF_AW_R_V_GND 1.E-5f
120 #ifndef EKF_AW_R_ACCEL_FILT_X
121 #define EKF_AW_R_ACCEL_FILT_X 1.E-5f
123 #ifndef EKF_AW_R_ACCEL_FILT_Y
124 #define EKF_AW_R_ACCEL_FILT_Y 1.E-5f
126 #ifndef EKF_AW_R_ACCEL_FILT_Z
127 #define EKF_AW_R_ACCEL_FILT_Z 1.E-5f
129 #ifndef EKF_AW_R_V_PITOT
130 #define EKF_AW_R_V_PITOT 1.E-7f
134 #ifndef EKF_AW_WING_INSTALLED
135 #define EKF_AW_WING_INSTALLED false
137 #ifndef EKF_AW_USE_MODEL_BASED_X
138 #define EKF_AW_USE_MODEL_BASED_X false
140 #ifndef EKF_AW_USE_MODEL_BASED_Y
141 #define EKF_AW_USE_MODEL_BASED_Y false
143 #ifndef EKF_AW_USE_MODEL_BASED_Z
144 #define EKF_AW_USE_MODEL_BASED_Z false
146 #ifndef EKF_AW_USE_BETA
147 #define EKF_AW_USE_BETA false
149 #ifndef EKF_AW_PROPAGATE_OFFSET
150 #define EKF_AW_PROPAGATE_OFFSET false
152 #ifndef EKF_AW_USE_PITOT
153 #define EKF_AW_USE_PITOT false
157 #ifndef EKF_AW_VEHICLE_MASS
158 #define EKF_AW_VEHICLE_MASS 6.5f
162 #ifndef EKF_AW_K1_FX_DRAG
163 #define EKF_AW_K1_FX_DRAG -3.0E-1f
165 #ifndef EKF_AW_K2_FX_DRAG
166 #define EKF_AW_K2_FX_DRAG -4.0E-2f
169 #ifndef EKF_AW_K1_FX_FUSELAGE
170 #define EKF_AW_K1_FX_FUSELAGE 0.0f
172 #ifndef EKF_AW_K2_FX_FUSELAGE
173 #define EKF_AW_K2_FX_FUSELAGE -0.04f
175 #ifndef EKF_AW_K3_FX_FUSELAGE
176 #define EKF_AW_K3_FX_FUSELAGE 0.0f
178 #ifndef EKF_AW_K4_FX_FUSELAGE
179 #define EKF_AW_K4_FX_FUSELAGE 0.0f
182 #ifndef EKF_AW_K1_FX_HOVER
183 #define EKF_AW_K1_FX_HOVER 0.0f
185 #ifndef EKF_AW_K2_FX_HOVER
186 #define EKF_AW_K2_FX_HOVER 0.0f
188 #ifndef EKF_AW_K3_FX_HOVER
189 #define EKF_AW_K3_FX_HOVER -0.3f
192 #ifndef EKF_AW_K1_FX_WING
193 #define EKF_AW_K1_FX_WING -6.428638953316000e-03f
195 #ifndef EKF_AW_K2_FX_WING
196 #define EKF_AW_K2_FX_WING 1.671952644901720e-01f
198 #ifndef EKF_AW_K3_FX_WING
199 #define EKF_AW_K3_FX_WING 5.944103706458780e-01f
201 #ifndef EKF_AW_K4_FX_WING
202 #define EKF_AW_K4_FX_WING 3.983889380919000e-03f
204 #ifndef EKF_AW_K5_FX_WING
205 #define EKF_AW_K5_FX_WING 3.532085496834000e-03f
208 #ifndef EKF_AW_K1_FX_PUSH
209 #define EKF_AW_K1_FX_PUSH 3.96222948E-07f
211 #ifndef EKF_AW_K2_FX_PUSH
212 #define EKF_AW_K2_FX_PUSH -5.2930351318E-05f
214 #ifndef EKF_AW_K3_FX_PUSH
215 #define EKF_AW_K3_FX_PUSH -2.68843366027904E-01f
218 #ifndef EKF_AW_K1_FX_ELEV
219 #define EKF_AW_K1_FX_ELEV 0.0f
221 #ifndef EKF_AW_K2_FX_ELEV
222 #define EKF_AW_K2_FX_ELEV 0.0f
224 #ifndef EKF_AW_K3_FX_ELEV
225 #define EKF_AW_K3_FX_ELEV 0.0f
229 #ifndef EKF_AW_K_FY_BETA
230 #define EKF_AW_K_FY_BETA -2.19E-1f
232 #ifndef EKF_AW_K_FY_V
233 #define EKF_AW_K_FY_V -3.2E-1f
235 #ifndef EKF_AW_K1_FY_WING
236 #define EKF_AW_K1_FY_WING 0.0f
238 #ifndef EKF_AW_K2_FY_WING
239 #define EKF_AW_K2_FY_WING 0.0f
241 #ifndef EKF_AW_K3_FY_WING
242 #define EKF_AW_K3_FY_WING 0.0f
244 #ifndef EKF_AW_K4_FY_WING
245 #define EKF_AW_K4_FY_WING 0.0f
247 #ifndef EKF_AW_K5_FY_WING
248 #define EKF_AW_K5_FY_WING 0.0f
252 #ifndef EKF_AW_K1_FZ_FUSELAGE
253 #define EKF_AW_K1_FZ_FUSELAGE 0.0f
255 #ifndef EKF_AW_K2_FZ_FUSELAGE
256 #define EKF_AW_K2_FZ_FUSELAGE 0.0f
258 #ifndef EKF_AW_K3_FZ_FUSELAGE
259 #define EKF_AW_K3_FZ_FUSELAGE 0.0f
261 #ifndef EKF_AW_K4_FZ_FUSELAGE
262 #define EKF_AW_K4_FZ_FUSELAGE 0.0f
265 #ifndef EKF_AW_K1_FZ_WING
266 #define EKF_AW_K1_FZ_WING -1.000778727574050e-01f
268 #ifndef EKF_AW_K2_FZ_WING
269 #define EKF_AW_K2_FZ_WING -8.696479964371250e-01f
271 #ifndef EKF_AW_K3_FZ_WING
272 #define EKF_AW_K3_FZ_WING 1.457831456377660e-01f
274 #ifndef EKF_AW_K4_FZ_WING
275 #define EKF_AW_K4_FZ_WING 2.185394878246410e-01f
278 #ifndef EKF_AW_K1_FZ_HOVER
279 #define EKF_AW_K1_FZ_HOVER -8.738705811080210e-07f
281 #ifndef EKF_AW_K2_FZ_HOVER
282 #define EKF_AW_K2_FZ_HOVER -9.517409386179890e-07f
284 #ifndef EKF_AW_K3_FZ_HOVER
285 #define EKF_AW_K3_FZ_HOVER -8.946217883362630e-07f
287 #ifndef EKF_AW_K4_FZ_HOVER
288 #define EKF_AW_K4_FZ_HOVER -8.520556416144729e-07f
290 #ifndef EKF_AW_K5_FZ_HOVER
291 #define EKF_AW_K5_FZ_HOVER 0.0f
294 #ifndef EKF_AW_K1_FZ_ELEV
295 #define EKF_AW_K1_FZ_ELEV 0.0f
297 #ifndef EKF_AW_K2_FZ_ELEV
298 #define EKF_AW_K2_FZ_ELEV 0.0f
302 #ifndef EKF_AW_AZ_SCHED_GAIN
303 #define EKF_AW_AZ_SCHED_GAIN 0
305 #ifndef EKF_AW_AZ_SCHED_START_DEG
306 #define EKF_AW_AZ_SCHED_START_DEG 60
308 #ifndef EKF_AW_AZ_SCHED_END_DEG
309 #define EKF_AW_AZ_SCHED_END_DEG 70
311 #ifndef EKF_AW_AX_SCHED_GAIN
312 #define EKF_AW_AX_SCHED_GAIN 0
314 #ifndef EKF_AW_AX_SCHED_START_DEG
315 #define EKF_AW_AX_SCHED_START_DEG 40
317 #ifndef EKF_AW_AX_SCHED_END_DEG
318 #define EKF_AW_AX_SCHED_END_DEG 60
322 #ifndef EKF_AW_AZ_QUICK_CONV_MU_GAIN
323 #define EKF_AW_AZ_QUICK_CONV_MU_GAIN -2
325 #ifndef EKF_AW_AZ_QUICK_CONV_ACCEL_GAIN
326 #define EKF_AW_AZ_QUICK_CONV_ACCEL_GAIN 0
330 #ifndef EKF_AW_ELEV_MAX_ANGLE
331 #define EKF_AW_ELEV_MAX_ANGLE 37.0f
333 #ifndef EKF_AW_ELEV_MIN_ANGLE
334 #define EKF_AW_ELEV_MIN_ANGLE -10.0f
336 #ifndef EKF_AW_AOA_MAX_ANGLE
337 #define EKF_AW_AOA_MAX_ANGLE 15.0f
339 #ifndef EKF_AW_AOA_MIN_ANGLE
340 #define EKF_AW_AOA_MIN_ANGLE -15.0f
344 #ifndef EKF_AW_SKEW_POLY_0
345 #define EKF_AW_SKEW_POLY_0 0.0f
347 #ifndef EKF_AW_SKEW_POLY_1
348 #define EKF_AW_SKEW_POLY_1 1.0f
350 #ifndef EKF_AW_SKEW_POLY_2
351 #define EKF_AW_SKEW_POLY_2 0.0f
356 #define EKF_AW_DEBUG false
382 #define eawp ekf_aw_private
385 static const matrix::Vector3f
gravity(0.f, 0.f, 9.81f);
392 float fx_fuselage(
float *skew,
float *aoa,
float *u);
393 float fx_elevator(
float *elevator_angle,
float *V_a);
394 float fx_wing(
float *skew,
float *aoa,
float *u);
395 float fy_wing(
float *skew,
float *aoa,
float *u);
396 float fx_fy_hover(
float *RPM_hover_mean,
float *V);
397 float fx_pusher(
float *RPM_pusher,
float *u);
398 float fz_fuselage(
float *skew,
float *aoa,
float *V_a);
399 float fz_elevator(
float *elevator_angle,
float *V_a);
400 float fz_wing(
float *skew,
float *aoa,
float *V_a);
401 float fz_hover(matrix::Vector<float, 4> RPM_hover,
float *V_a);
407 eawp.state.V_body.setZero();
408 eawp.state.wind.setZero();
409 eawp.state.offset.setZero();
412 eawp.measurements.V_gnd.setZero();
413 eawp.measurements.accel_filt.setZero();
414 eawp.measurements.V_pitot = 0.f;
417 eawp.inputs.accel.setZero();
418 eawp.inputs.rates.setZero();
419 eawp.inputs.euler.setZero();
420 eawp.inputs.RPM_pusher = 0.f;
421 eawp.inputs.RPM_hover.setZero();
422 eawp.inputs.skew = 0.f;
423 eawp.inputs.elevator_angle = 0.f;
426 eawp.innovations.V_gnd.setZero();
427 eawp.innovations.accel_filt.setZero();
428 eawp.innovations.V_pitot = 0.f;
431 eawp.forces.fuselage.setZero();
432 eawp.forces.wing.setZero();
433 eawp.forces.elevator.setZero();
434 eawp.forces.hover.setZero();
435 eawp.forces.pusher.setZero();
453 eawp.health.healthy =
true;
545 eawp.health.crashes_n = 0;
592 float *hover_RPM_array,
float *skew,
float *elevator_angle,
FloatVect3 *V_gnd,
FloatVect3 *acc_filt,
float *V_pitot,
607 if (
eawp.health.crashes_n > floor(5.0f / dt)) {
608 eawp.health.healthy =
false;
617 eawp.inputs.accel(0) = acc->
x;
eawp.inputs.accel(1) = acc->
y;
eawp.inputs.accel(2) = acc->
z;
618 eawp.inputs.rates(0) = gyro->
p;
eawp.inputs.rates(1) = gyro->
q;
eawp.inputs.rates(2) = gyro->
r;
621 eawp.inputs.RPM_pusher = *pusher_RPM;
623 eawp.inputs.RPM_hover(0) = hover_RPM_array[0];
eawp.inputs.RPM_hover(1) = hover_RPM_array[1];
624 eawp.inputs.RPM_hover(2) = hover_RPM_array[2];
eawp.inputs.RPM_hover(3) = hover_RPM_array[3];
627 eawp.inputs.skew = *skew;
634 eawp.inputs.elevator_angle = *elevator_angle;
637 eawp.inputs.elevator_angle;
640 eawp.measurements.V_gnd(0) = V_gnd->
x;
eawp.measurements.V_gnd(1) = V_gnd->
y;
eawp.measurements.V_gnd(2) = V_gnd->
z;
641 eawp.measurements.accel_filt(0) = acc_filt->
x;
eawp.measurements.accel_filt(1) = acc_filt->
y;
642 eawp.measurements.accel_filt(2) = acc_filt->
z;
643 eawp.measurements.V_pitot = *V_pitot;
646 float V_a =
eawp.state.V_body.norm();
647 float u =
eawp.state.V_body(0);
648 float v =
eawp.state.V_body(1);
649 float w =
eawp.state.V_body(2);
650 float sign_u = u < 0.0f ? -1.0f : u > 0.0f ? 1.0f : 0.0f;
651 float sign_v = v < 0.0f ? -1.0f : v > 0.0f ? 1.0f : 0.0f;
653 float p =
eawp.inputs.rates(0);
654 float q =
eawp.inputs.rates(1);
655 float r =
eawp.inputs.rates(2);
657 float phi =
eawp.inputs.euler(0);
658 float theta =
eawp.inputs.euler(1);
659 float psi =
eawp.inputs.euler(2);
666 float cos_phi = cosf(phi);
667 float sin_phi = sinf(phi);
668 float cos_theta = cosf(theta);
669 float sin_theta = sinf(theta);
670 float cos_psi = cosf(psi);
671 float sin_psi = sinf(psi);
673 float cos_skew = cosf(
eawp.inputs.skew);
674 float sin_skew = sinf(
eawp.inputs.skew);
682 matrix::Matrix3f dcm;
683 dcm(0, 0) = cos_theta * cos_psi;
684 dcm(0, 1) = -cos_phi * sin_psi + sin_phi * sin_theta * cos_psi;
685 dcm(0, 2) = sin_phi * sin_psi + cos_phi * sin_theta * cos_psi;
687 dcm(1, 0) = cos_theta * sin_psi;
688 dcm(1, 1) = cos_phi * cos_psi + sin_phi * sin_theta * sin_psi;
689 dcm(1, 2) = -sin_phi * cos_psi + cos_phi * sin_theta * sin_psi;
691 dcm(2, 0) = -sin_theta;
692 dcm(2, 1) = sin_phi * cos_theta;
693 dcm(2, 2) = cos_phi * cos_theta;
696 float aoa = atan2f(w, fabsf(u) < 1.E-5 ? 1
E-5 : u);
699 float tan_aoa = tanf(aoa);
702 float diff_alpha_u = 0.0f;
703 float diff_alpha_w = 0.0f;
704 if ((fabsf(u) > 1
E-5) & (fabsf(w) > 1
E-5)) {
705 diff_alpha_u = -w / (u * u + w * w);
706 diff_alpha_w = u / (u * u + w * w);
712 beta = asinf(v / V_a < -1.0f ? -1.0f : v / V_a > 1.0f ? 1.0f : v / V_a);
715 float hover_RPM_mean = (
eawp.inputs.RPM_hover(0) +
eawp.inputs.RPM_hover(1) +
eawp.inputs.RPM_hover(
716 2) +
eawp.inputs.RPM_hover(3)) / 4.0f;
818 matrix::Vector3f state_dev = -
eawp.inputs.rates.cross(
eawp.state.V_body) + dcm.transpose() *
gravity +
823 for (
int i = 0; i < 3; i++) {
824 if (std::isnan(state_dev(i))) {
831 eawp.health.healthy =
false;
832 eawp.health.crashes_n += 1;
834 eawp.state.V_body += state_dev * dt;
850 1)) + v * v *
eawp.Q(5, 5) + w * w *
eawp.Q(4, 4);
858 0)) + u * u *
eawp.Q(5, 5) + w * w *
eawp.Q(3, 3);
866 0)) + u * u *
eawp.Q(4, 4) + v * v *
eawp.Q(3, 3);
948 a_x = (
eawp.forces.fuselage(0) +
949 eawp.forces.wing(0) +
950 eawp.forces.elevator(0) +
951 eawp.forces.hover(0) +
952 eawp.forces.pusher(0) +
986 a_z = (
eawp.forces.fuselage(2) +
987 eawp.forces.elevator(2) +
988 eawp.forces.wing(2) +
991 a_z =
eawp.measurements.accel_filt(2);
994 matrix::Vector3f accel_est = {a_x, a_y, a_z};
997 eawp.innovations.V_gnd =
eawp.measurements.V_gnd - (dcm *
eawp.state.V_body +
999 eawp.innovations.accel_filt =
eawp.measurements.accel_filt - accel_est;
1000 eawp.innovations.V_pitot =
eawp.measurements.V_pitot -
eawp.state.V_body(0);
1029 matrix::Matrix<float, EKF_AW_R_SIZE, EKF_AW_COV_SIZE> G;
1033 G(0, 0) = cos_psi * cos_theta;
1034 G(0, 1) = cos_psi * sin_phi * sin_theta - cos_phi * sin_psi;
1035 G(0, 2) = sin_phi * sin_psi + cos_phi * cos_psi * sin_theta;
1037 G(1, 0) = cos_theta * sin_psi;
1038 G(1, 1) = cos_phi * cos_psi + sin_phi * sin_psi * sin_theta;
1039 G(1, 2) = cos_phi * sin_psi * sin_theta - cos_psi * sin_phi;
1041 G(2, 0) = -sin_theta;
1042 G(2, 1) = cos_theta * sin_phi;
1043 G(2, 2) = cos_phi * cos_theta;
1102 float protected_V_a = fabsf(V_a) < 1
E-5 ? 1
E-5 : V_a;
1103 float cos_beta = fabsf(cosf(beta)) < 1
E-5 ? 1
E-5 : cosf(beta);
1111 #if EKF_AW_WING_INSTALLED
1131 #if EKF_AW_WING_INSTALLED
1166 matrix::SquareMatrix<float, EKF_AW_R_SIZE> S = G *
eawp.P * G.transpose() +
eawp.R;
1174 matrix::Matrix<float, EKF_AW_COV_SIZE, EKF_AW_R_SIZE>
K =
eawp.P * G.transpose() * S.I();
1185 if (std::isnan(
K(i, j))) {
1193 eawp.health.healthy =
false;
1194 eawp.health.crashes_n += 1;
1196 eawp.health.healthy =
true;
1199 matrix::Matrix<float, 3, 3> K_slice_3;
1200 matrix::Matrix<float, 3, 1> K_slice_1;
1203 K_slice_3 =
K.slice<3, 3>(0, 0);
eawp.state.V_body += K_slice_3 *
eawp.innovations.V_gnd;
1204 K_slice_3 =
K.slice<3, 3>(3, 0);
eawp.state.wind += K_slice_3 *
eawp.innovations.V_gnd;
1206 K_slice_3 =
K.slice<3, 3>(6, 0);
eawp.state.offset += K_slice_3 *
eawp.innovations.V_gnd;
1210 K_slice_3 =
K.slice<3, 3>(0, 3);
eawp.state.V_body += K_slice_3 *
eawp.innovations.accel_filt;
1211 K_slice_3 =
K.slice<3, 3>(3, 3);
eawp.state.wind += K_slice_3 *
eawp.innovations.accel_filt;
1213 K_slice_3 =
K.slice<3, 3>(6, 3);
eawp.state.offset += K_slice_3 *
eawp.innovations.accel_filt;
1218 K_slice_1 =
K.slice<3, 1>(0, 6);
eawp.state.V_body += K_slice_1 *
eawp.innovations.V_pitot;
1219 K_slice_1 =
K.slice<3, 1>(3, 6);
eawp.state.wind += K_slice_1 *
eawp.innovations.V_pitot;
1221 K_slice_1 =
K.slice<3, 1>(6, 6);
eawp.state.offset += K_slice_1 *
eawp.innovations.V_pitot;
1230 matrix::SquareMatrix<float, EKF_AW_COV_SIZE> eye;
1239 eawp.forces.fuselage(0) = duration_1 * 1.0f;
1240 eawp.forces.fuselage(1) = duration_2 * 1.0f;
1241 eawp.forces.fuselage(2) = duration_3 * 1.0f;
1243 eawp.forces.wing(0) = duration_4 * 1.0f;
1244 eawp.forces.wing(1) = duration_5 * 1.0f;
1245 eawp.forces.wing(2) = duration_6 * 1.0f;
1247 eawp.forces.elevator(0) = duration_7 * 1.0f;
1248 eawp.forces.elevator(1) = duration_8 * 1.0f;
1249 eawp.forces.elevator(2) = duration_9 * 1.0f;
1251 eawp.forces.hover(0) = duration_10 * 1.0f;
1252 eawp.forces.hover(1) = duration_11 * 1.0f;
1268 .x =
eawp.state.V_body(0),
1269 .y =
eawp.state.V_body(1),
1270 .z =
eawp.state.V_body(2)
1278 .
x =
eawp.state.wind(0),
1279 .y =
eawp.state.wind(1),
1280 .z =
eawp.state.wind(2)
1288 .
x =
eawp.state.offset(0),
1289 .y =
eawp.state.offset(1),
1290 .z =
eawp.state.offset(2)
1298 .healthy =
eawp.health.healthy,
1299 .crashes_n =
eawp.health.crashes_n
1307 .
x =
eawp.innovations.V_gnd(0),
1308 .y =
eawp.innovations.V_gnd(1),
1309 .z =
eawp.innovations.V_gnd(2)
1316 .
x =
eawp.innovations.accel_filt(0),
1317 .y =
eawp.innovations.accel_filt(1),
1318 .z =
eawp.innovations.accel_filt(2)
1325 const float w =
eawp.innovations.V_pitot;
1334 if (
eawp.R(i, i) <= 0.0f) {
1335 diagonal[i] =
eawp.R(i, i);
1337 diagonal[i] = log10(
eawp.R(i, i));
1341 memcpy(meas_cov, diagonal, 7 *
sizeof(
float));
1349 if (
eawp.P(i, i) <= 0.0f) {
1350 diagonal[i] =
eawp.P(i, i);
1352 diagonal[i] = log10(
eawp.P(i, i));
1356 memcpy(state_cov, diagonal, 9 *
sizeof(
float));
1364 if (
eawp.Q(i, i) <= 0.0f) {
1365 diagonal[i] =
eawp.Q(i, i);
1367 diagonal[i] = log10(
eawp.Q(i, i));
1371 memcpy(process_cov, diagonal, 9 *
sizeof(
float));
1377 for (
int8_t i = 0; i < 3; i++) {
1378 temp[i] =
eawp.forces.fuselage(i);
1380 memcpy(force, temp, 3 *
sizeof(
float));
1386 for (
int8_t i = 0; i < 3; i++) {
1387 temp[i] =
eawp.forces.wing(i);
1389 memcpy(force, temp, 3 *
sizeof(
float));
1395 for (
int8_t i = 0; i < 3; i++) {
1396 temp[i] =
eawp.forces.elevator(i);
1398 memcpy(force, temp, 3 *
sizeof(
float));
1404 for (
int8_t i = 0; i < 3; i++) {
1405 temp[i] =
eawp.forces.hover(i);
1407 memcpy(force, temp, 3 *
sizeof(
float));
1413 for (
int8_t i = 0; i < 3; i++) {
1414 temp[i] =
eawp.forces.pusher(i);
1416 memcpy(force, temp, 3 *
sizeof(
float));
1428 eawp.state.V_body(0) =
s->x;
1429 eawp.state.V_body(1) =
s->y;
1430 eawp.state.V_body(2) =
s->z;
1435 eawp.state.wind(0) =
s->x;
1436 eawp.state.wind(1) =
s->y;
1437 eawp.state.wind(2) =
s->z;
1442 eawp.state.offset(0) =
s->x;
1443 eawp.state.offset(1) =
s->y;
1444 eawp.state.offset(2) =
s->z;
1449 eawp.health.healthy =
true;
1450 eawp.health.crashes_n = 0;
1459 float sign = *u < 0.0f ? -1.0f : *u > 0.0f ? 1.0f : 0.0f;
1483 float sign = *u < 0.0f ? -1.0f : *u > 0.0f ? 1.0f : 0.0f;
1505 float sign = *V < 0.0f ? -1.0f : *V > 0.0f ? 1.0f : 0.0f;
1521 if (*RPM_pusher > 500) {
1537 float fy_wing(
float *skew,
float *aoa __attribute__((unused)),
float *u)
1540 float sign = *u < 0.0f ? -1.0f : *u > 0.0f ? 1.0f : 0.0f;
1575 float sign = *u < 0.0f ? -1.0f : *u > 0.0f ? 1.0f : 0.0f;
1592 float fz_hover(matrix::Vector<float, 4> RPM_hover,
float *V_a)
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
float fz_fuselage(float *skew, float *aoa, float *V_a)
#define EKF_AW_K2_FX_HOVER
void ekf_aw_get_hover_force(float force[3])
#define EKF_AW_USE_MODEL_BASED_X
#define EKF_AW_K2_FZ_HOVER
void ekf_aw_update_params(void)
struct ekfAwInputs inputs
#define EKF_AW_K4_FZ_FUSELAGE
float ekf_aw_get_innov_V_pitot(void)
struct FloatVect3 ekf_aw_get_innov_accel_filt(void)
matrix::Vector3f accel_filt
void ekf_aw_get_meas_cov(float meas_cov[7])
float fz_wing(float *skew, float *aoa, float *V_a)
void ekf_aw_set_speed_body(struct NedCoor_f *s)
void ekf_aw_get_state_cov(float state_cov[9])
#define EKF_AW_K4_FX_WING
#define EKF_AW_K4_FX_FUSELAGE
matrix::SquareMatrix< float, EKF_AW_R_SIZE > EKF_Aw_R
#define EKF_AW_K4_FZ_WING
#define EKF_AW_K3_FX_ELEV
#define EKF_AW_ELEV_MAX_ANGLE
struct NedCoor_f ekf_aw_get_speed_body(void)
#define EKF_AW_K5_FZ_HOVER
#define EKF_AW_K1_FX_DRAG
matrix::SquareMatrix< float, EKF_AW_Q_SIZE > EKF_Aw_Q
struct ekfAwForces forces
#define EKF_AW_K1_FZ_HOVER
#define EKF_AW_K4_FZ_HOVER
float fx_wing(float *skew, float *aoa, float *u)
#define EKF_AW_R_ACCEL_FILT_Y
float fy_wing(float *skew, float *aoa, float *u)
#define EKF_AW_AZ_QUICK_CONV_MU_GAIN
#define EKF_AW_USE_MODEL_BASED_Z
#define EKF_AW_K1_FX_FUSELAGE
struct ekfHealth ekf_aw_get_health(void)
matrix::Vector3f elevator
#define EKF_AW_R_ACCEL_FILT_Z
#define EKF_AW_ELEV_MIN_ANGLE
#define EKF_AW_AX_SCHED_GAIN
#define EKF_AW_AZ_SCHED_END_DEG
void ekf_aw_get_fuselage_force(float force[3])
void ekf_aw_propagate(struct FloatVect3 *acc, struct FloatRates *gyro, struct FloatEulers *euler, float *pusher_RPM, float *hover_RPM_array, float *skew, float *elevator_angle, FloatVect3 *V_gnd, FloatVect3 *acc_filt, float *V_pitot, float dt)
struct ekfAwMeasurements innovations
@ EKF_AW_R_a_z_filt_index
@ EKF_AW_R_a_y_filt_index
@ EKF_AW_R_a_x_filt_index
#define EKF_AW_K2_FZ_ELEV
#define EKF_AW_K5_FX_WING
#define EKF_AW_AX_SCHED_START_DEG
#define EKF_AW_K3_FZ_HOVER
void ekf_aw_reset_health(void)
void ekf_aw_set_offset(struct NedCoor_f *s)
#define EKF_AW_K2_FZ_FUSELAGE
struct ekfAwParameters * ekf_aw_get_param_handle(void)
#define EKF_AW_AX_SCHED_END_DEG
#define EKF_AW_K3_FX_HOVER
#define EKF_AW_K5_FY_WING
#define EKF_AW_AOA_MAX_ANGLE
float fx_pusher(float *RPM_pusher, float *u)
#define EKF_AW_K1_FZ_WING
#define EKF_AW_USE_MODEL_BASED_Y
#define EKF_AW_K1_FZ_ELEV
float fx_elevator(float *elevator_angle, float *V_a)
#define EKF_AW_K1_FX_HOVER
#define EKF_AW_K3_FX_FUSELAGE
#define EKF_AW_K2_FX_WING
#define EKF_AW_K2_FY_WING
#define EKF_AW_K1_FX_ELEV
#define EKF_AW_AZ_SCHED_GAIN
#define EKF_AW_K1_FX_WING
struct NedCoor_f ekf_aw_get_wind_ned(void)
#define EKF_AW_K2_FX_PUSH
float fz_hover(matrix::Vector< float, 4 > RPM_hover, float *V_a)
static struct ekfAwPrivate ekf_aw_private
#define EKF_AW_K3_FX_PUSH
#define EKF_AW_SKEW_POLY_2
#define EKF_AW_SKEW_POLY_1
void ekf_aw_get_elevator_force(float force[3])
float fx_fuselage(float *skew, float *aoa, float *u)
#define EKF_AW_K3_FZ_WING
#define EKF_AW_AOA_MIN_ANGLE
#define EKF_AW_K1_FY_WING
struct FloatVect3 ekf_aw_get_innov_V_gnd(void)
static void init_ekf_aw_state(void)
void ekf_aw_get_pusher_force(float force[3])
#define EKF_AW_K2_FX_DRAG
#define EKF_AW_K1_FZ_FUSELAGE
struct ekfAwMeasurements measurements
void ekf_aw_get_process_cov(float process_cov[12])
#define EKF_AW_VEHICLE_MASS
#define EKF_AW_WING_INSTALLED
#define EKF_AW_PROPAGATE_OFFSET
#define EKF_AW_K2_FX_FUSELAGE
#define EKF_AW_AZ_SCHED_START_DEG
#define EKF_AW_K3_FY_WING
static const matrix::Vector3f gravity(0.f, 0.f, 9.81f)
void ekf_aw_get_wing_force(float force[3])
#define EKF_AW_K1_FX_PUSH
#define EKF_AW_SKEW_POLY_0
#define EKF_AW_K3_FX_WING
#define EKF_AW_K3_FZ_FUSELAGE
float fx_fy_hover(float *RPM_hover_mean, float *V)
struct ekfAwParameters ekf_aw_params
void ekf_aw_set_wind(struct NedCoor_f *s)
#define EKF_AW_K4_FY_WING
#define EKF_AW_AZ_QUICK_CONV_ACCEL_GAIN
matrix::Vector< float, 4 > RPM_hover
float fz_elevator(float *elevator_angle, float *V_a)
#define EKF_AW_K2_FX_ELEV
struct NedCoor_f ekf_aw_get_offset(void)
#define EKF_AW_R_ACCEL_FILT_X
#define EKF_AW_K2_FZ_WING
matrix::SquareMatrix< float, EKF_AW_COV_SIZE > EKF_Aw_Cov
matrix::Vector3f fuselage
float Q_gyro
gyro process noise
float R_V_pitot
airspeed measurement noise
float Q_k
offset process noise
float R_accel_filt[3]
filtered accel measurement noise
float R_V_gnd
speed measurement noise
float Q_mu
wind process noise
float Q_accel
accel process noise
static float sign(float x)
sign function
vector in North East Down coordinates Units: meters
Architecture independent timing functions.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
signed char int8_t
Typedef defining 8 bit char type.