48 }
else if (u1 > 0.0) {
53 }
else if (d == 0.0) {
55 }
else if (d == 1.0) {
61 }
else if (u1 == 2.0) {
63 }
else if ((u1 == 0.5) && (u0 >= 0.0)) {
65 }
else if ((u0 < 0.0) && (u1 > floor(u1))) {
88void mekf(
const double q[4],
const double beta[3],
double P[36],
89 const double omega[3],
const double b_B[3],
double height_AGL,
92 static const double Q[36] = {4.3956900000000333E-11,
95 -5.0000000000000008E-23,
99 4.3956900000000333E-11,
102 -5.0000000000000008E-23,
106 4.3956900000000333E-11,
109 -5.0000000000000008E-23,
110 -5.0000000000000008E-23,
113 1.0000000000000001E-20,
117 -5.0000000000000008E-23,
120 1.0000000000000001E-20,
124 -5.0000000000000008E-23,
127 1.0000000000000001E-20};
128 static const double dv[11] = {23950.03, 23938.16, 23926.3, 23914.44,
129 23902.6, 23890.76, 23878.93, 23867.11,
130 23855.29, 23843.49, 23831.69};
131 static const double dv1[11] = {2585.64, 2583.71, 2581.78, 2579.85,
132 2577.92, 2576.0, 2574.08, 2572.15,
133 2570.24, 2568.32, 2566.4};
134 static const double dv2[11] = {39593.08, 39573.32, 39553.57, 39533.84,
135 39514.11, 39494.41, 39474.71, 39455.03,
136 39435.36, 39415.7, 39396.06};
137 static const double b_y[9] = {0.01, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.01};
139 static const signed char iv[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0,
140 1, 0, 0, 0, 1, 0, 0, 0, 1};
141 static const signed char b[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
150 double skew_omega_sq[9];
189 y = floor(height_AGL / 1000.0);
190 omega_norm = ceil(height_AGL / 1000.0);
201 y = 2.0 * (
q[2] *
q[2]);
202 omega_norm = 2.0 * (
q[1] *
q[1]);
203 A[0] = (1.0 - omega_norm) - y;
205 sin_term =
q[2] *
q[3];
206 A[3] = 2.0 * (x - sin_term);
209 A[6] = 2.0 * (A_tmp + angle);
210 A[1] = 2.0 * (x + sin_term);
211 x = 1.0 - 2.0 * (
q[0] *
q[0]);
214 sin_term =
q[0] *
q[3];
215 A[7] = 2.0 * (y - sin_term);
216 A[2] = 2.0 * (A_tmp - angle);
217 A[5] = 2.0 * (y + sin_term);
218 A[8] = x - omega_norm;
228 for (i = 0; i < 3; i++) {
233 axis[i] = (A[i] * d + A[i + 3] * A_tmp) + A[i + 6] * y;
242 for (i = 0; i < 3; i++) {
243 for (cos_term_tmp = 0; cos_term_tmp < 6; cos_term_tmp++) {
245 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
246 d += H[i + 3 * H_tmp] * P[H_tmp + 6 * cos_term_tmp];
248 b_H[i + 3 * cos_term_tmp] = d;
250 for (cos_term_tmp = 0; cos_term_tmp < 3; cos_term_tmp++) {
252 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
253 d += b_H[i + 3 * H_tmp] * H[cos_term_tmp + 3 * H_tmp];
255 H_tmp = i + 3 * cos_term_tmp;
256 skew_omega_sq[H_tmp] = d + (double)
R[H_tmp];
259 mpower(skew_omega_sq, dv3);
260 for (i = 0; i < 6; i++) {
261 for (cos_term_tmp = 0; cos_term_tmp < 3; cos_term_tmp++) {
263 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
264 d += P[i + 6 * H_tmp] * H[cos_term_tmp + 3 * H_tmp];
266 b_H[i + 6 * cos_term_tmp] = d;
271 for (cos_term_tmp = 0; cos_term_tmp < 3; cos_term_tmp++) {
272 K[i + 6 * cos_term_tmp] =
273 (d * dv3[3 * cos_term_tmp] + A_tmp * dv3[3 * cos_term_tmp + 1]) +
274 y * dv3[3 * cos_term_tmp + 2];
298 for (i = 0; i < 6; i++) {
302 delta_x[i] = (d * b_W[0] + A_tmp * b_W[1]) + y * b_W[2];
303 for (cos_term_tmp = 0; cos_term_tmp < 6; cos_term_tmp++) {
304 H_tmp = i + 6 * cos_term_tmp;
307 ((d * H[3 * cos_term_tmp] + A_tmp * H[3 * cos_term_tmp + 1]) +
308 y * H[3 * cos_term_tmp + 2]);
310 for (cos_term_tmp = 0; cos_term_tmp < 6; cos_term_tmp++) {
312 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
313 d += b_Phi[i + 6 * H_tmp] * P[H_tmp + 6 * cos_term_tmp];
315 Phi[i + 6 * cos_term_tmp] = d;
318 delta_q[0] = 0.5 * delta_x[0];
319 delta_q[1] = 0.5 * delta_x[1];
320 delta_q[2] = 0.5 * delta_x[2];
322 ((delta_q[0] *
q[3] +
q[0]) +
q[1] * delta_q[2]) - delta_q[1] *
q[2];
324 ((delta_q[1] *
q[3] -
q[0] * delta_q[2]) +
q[1]) + delta_q[0] *
q[2];
326 ((delta_q[2] *
q[3] +
q[0] * delta_q[1]) - delta_q[0] *
q[1]) +
q[2];
328 ((
q[3] -
q[0] * delta_q[0]) -
q[1] * delta_q[1]) -
q[2] * delta_q[2];
337 memcpy(&P[0], &Phi[0], 36U *
sizeof(
double));
346 angle = omega_norm * 0.01;
349 sin_term = sin(angle);
362 for (b_i = 0; b_i < 3; b_i++) {
363 axis[b_i] = b_W[b_i] / omega_norm;
364 for (i = 0; i < 3; i++) {
365 skew_omega_sq[b_i + 3 * i] =
366 (A[b_i] * A[3 * i] + A[b_i + 3] * A[3 * i + 1]) +
367 A[b_i + 6] * A[3 * i + 2];
371 a = sin_term / omega_norm;
372 y = omega_norm * omega_norm;
375 y = (angle - sin_term) /
rt_powd_snf(omega_norm, 3.0);
378 for (i = 0; i < 3; i++) {
380 A_tmp = skew_omega_sq[3 * i];
381 Phi[6 * i] = (dv3[3 * i] - a * d) + b_a * A_tmp;
383 Phi[H_tmp] = (x * d - y * A_tmp) - b_y[3 * i];
384 cos_term_tmp = 3 * i + 1;
386 A_tmp = skew_omega_sq[cos_term_tmp];
387 Phi[6 * i + 1] = (dv3[cos_term_tmp] - a * d) + b_a * A_tmp;
388 Phi[H_tmp + 1] = (x * d - y * A_tmp) - b_y[cos_term_tmp];
389 cos_term_tmp = 3 * i + 2;
391 A_tmp = skew_omega_sq[cos_term_tmp];
392 Phi[6 * i + 2] = (dv3[cos_term_tmp] - a * d) + b_a * A_tmp;
393 Phi[H_tmp + 2] = (x * d - y * A_tmp) - b_y[cos_term_tmp];
395 for (i = 0; i < 6; i++) {
396 Phi[6 * i + 3] = iv[3 * i];
397 Phi[6 * i + 4] = iv[3 * i + 1];
398 Phi[6 * i + 5] = iv[3 * i + 2];
403 for (i = 0; i < 6; i++) {
404 for (cos_term_tmp = 0; cos_term_tmp < 6; cos_term_tmp++) {
406 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
407 d += Phi[i + 6 * H_tmp] * P[H_tmp + 6 * cos_term_tmp];
409 b_Phi[i + 6 * cos_term_tmp] = d;
411 for (cos_term_tmp = 0; cos_term_tmp < 6; cos_term_tmp++) {
413 for (H_tmp = 0; H_tmp < 6; H_tmp++) {
414 d += b_Phi[i + 6 * H_tmp] * Phi[cos_term_tmp + 6 * H_tmp];
416 H_tmp = i + 6 * cos_term_tmp;
417 P_new[H_tmp] = d +
Q[H_tmp];
423 x = cos(0.5 * angle);
424 sin_term = sin(0.5 * angle);
427 skew_omega_sq[0] = sin_term * 0.0;
428 skew_omega_sq[3] = sin_term * -axis[2];
429 skew_omega_sq[6] = sin_term * axis[1];
430 skew_omega_sq[1] = sin_term * axis[2];
431 skew_omega_sq[4] = sin_term * 0.0;
432 skew_omega_sq[7] = sin_term * -axis[0];
433 skew_omega_sq[2] = sin_term * -axis[1];
434 skew_omega_sq[5] = sin_term * axis[0];
435 skew_omega_sq[8] = sin_term * 0.0;
436 for (b_i = 0; b_i < 3; b_i++) {
437 d = sin_term * axis[b_i];
439 cos_term[H_tmp] = x * (double)b[3 * b_i] - skew_omega_sq[3 * b_i];
440 cos_term_tmp = 3 * b_i + 1;
441 cos_term[H_tmp + 1] =
442 x * (double)b[cos_term_tmp] - skew_omega_sq[cos_term_tmp];
443 cos_term_tmp = 3 * b_i + 2;
444 cos_term[H_tmp + 2] =
445 x * (double)b[cos_term_tmp] - skew_omega_sq[cos_term_tmp];
446 cos_term[b_i + 12] = d;
447 cos_term[H_tmp + 3] = -d;
453 omega_norm =
q_new[3];
454 for (i = 0; i < 4; i++) {
456 ((cos_term[i] * d + cos_term[i + 4] * A_tmp) + cos_term[i + 8] * y) +
457 cos_term[i + 12] * omega_norm;
461 q_new[0] = delta_q[0] / d;
462 q_new[1] = delta_q[1] / d;
463 q_new[2] = delta_q[2] / d;
464 q_new[3] = delta_q[3] / d;
void b_eye(double b_I[36])
Creates a 6x6 identity matrix.
void eye(double b_I[9])
Creates a 3x3 identity matrix.
Utility functions for creating identity matrices of various sizes.
boolean_T rtIsInf(real_T value)
Checks if a double-precision value is positive or negative infinity.
boolean_T rtIsNaN(real_T value)
Checks if a double-precision value is Not-a-Number (NaN).
real_T rtInf
Global constant for positive infinity (double precision).
real_T rtNaN
Global constant for Not-a-Number (double precision).
void mekf(const double q[4], const double beta[3], double P[36], const double omega[3], const double b_B[3], double height_AGL, double q_new[4], double beta_new[3], double P_new[36])
Executes one prediction and correction step of the MEKF.
static double rt_powd_snf(double u0, double u1)
Multiplicative Extended Kalman Filter (MEKF) for attitude and gyroscope bias estimation.
void mpower(const double a[9], double c[9])
Calculates the inverse of a 3x3 matrix.
A MATLAB Coder helper function for calculating the inverse of a 3x3 matrix.
double b_norm(const double x[3])
Calculates the Euclidean norm (magnitude) of a 3-element vector.
double c_norm(const double x[4])
Calculates the Euclidean norm (magnitude) of a 4-element vector.
Provides MATLAB Coder helper functions to calculate the Euclidean norm of a vector.
Provides definitions and utility functions for non-finite floating-point values.