Da Vinci Firmware 1
Firmware for the DaVinci-M rocket avionics board.
Loading...
Searching...
No Matches
kalmanFilter.c
Go to the documentation of this file.
1/*
2 * Academic License - for use in teaching, academic research, and meeting
3 * course requirements at degree granting institutions only. Not for
4 * government, commercial, or other organizational use.
5 * File: kalmanFilter_VES_definitive.c
6 *
7 * MATLAB Coder version : 24.2
8 * C/C++ source code generated on : 05-May-2025 19:53:20
9 */
10
11/* Include Files */
12#include "kalmanFilter.h"
13#include "mrdivide_helper.h"
14#include <math.h>
15
16
17
18/* Function Definitions */
19/*
20 * Implements a Kalman filter to estimate state variables (barometric altitude,
21 * GNSS velocity) with conditional measurement updates based on GNSS signal
22 * availability.
23 *
24 * Parameters:
25 * x_est (2x1 array): Current state estimate [barometric_altitude;
26 * gnss_velocity] P (2x2 array): Current estimate covariance matrix z (2x1
27 * array): Measurement vector [measured_barometric_altitude;
28 * measured_gnss_velocity] alpha (float): Current tilt angle (in radians) of the
29 * rocket a_m (float): Measured acceleration (affects the system's state
30 * dynamics) Ts (float): Time step Q (2x2 array): Process noise covariance
31 * matrix R (2x2 array): Measurement noise covariance matrix gnss_signal
32 * (logical): Flag indicating GNSS signal availability (1=available,
33 * 0=unavailable)
34 *
35 * Returns:
36 * tuple: Updated state estimate `x_est` and covariance matrix `P`
37 *
38 * Arguments : double x_est[2]
39 * double P[4]
40 * const double z[2]
41 * double alpha
42 * double a_m
43 * double Ts
44 * const double Q[4]
45 * const double R[4]
46 * double gnss_signal
47 * Return Type : void
48 */
49void kalmanFilter(double x_est[2], double P[4],
50 const double z[2], double alpha, double a_m,
51 double Ts, const double Q[4],
52 const double R[4], bool gnss_signal)
53{
54 static const signed char b_a[4] = {1, 0, 0, 1};
55 double F[4];
56 double P0[4];
57 double x_pred[2];
58 double cos_alpha;
59 double d;
60 double d1;
61 double d2;
62 double d3;
63 double d4;
64 int a_tmp;
65 int i;
66 /* Compute cos_alpha from the input tilt angle alpha */
67 cos_alpha = cos(alpha);
68 /* State transition matrix */
69 F[0] = 1.0;
70 F[2] = Ts * cos_alpha;
71 F[1] = 0.0;
72 F[3] = 1.0;
73 /* Barometric altitude depends on vertical velocity component */
74 /* GNSS velocity has simple integration relationship */
75 /* Control input matrix */
76 /* Barometric altitude change */
77 /* GNSS velocity change */
78 /* Prediction step */
79 x_pred[0] =
80 (x_est[0] + x_est[1] * F[2]) + Ts * Ts / 2.0 * (a_m * cos_alpha - 9.81);
81 x_pred[1] = (0.0 * x_est[0] + x_est[1]) + Ts * (a_m - 9.81 * cos_alpha);
82 /* Observation matrix - identity when both measurements available */
83 /* Always measure barometric altitude */
84 /* GNSS velocity measurement depends on signal */
85 /* Modify measurement update based on GNSS signal availability */
86 if (gnss_signal == true) {
87 double K[4];
88 double a[4];
89 double b_Ts[2];
90 double P0_idx_0;
91 double P0_idx_1;
92 double P0_idx_2;
93 double P0_idx_3;
94 int b_a_tmp;
95 /* Full update (both altitude and velocity) */
96 for (i = 0; i < 2; i++) {
97 a_tmp = b_a[i];
98 b_a_tmp = b_a[i + 2];
99 cos_alpha = (double)a_tmp * P[0] + (double)b_a_tmp * P[1];
100 d = (double)a_tmp * P[2] + (double)b_a_tmp * P[3];
101 P0[i] = (cos_alpha + d * 0.0) + R[i];
102 P0[i + 2] = (cos_alpha * 0.0 + d) + R[i + 2];
103 cos_alpha = P[i + 2];
104 a[i] = P[i] + cos_alpha * 0.0;
105 a[i + 2] = P[i] * 0.0 + cos_alpha;
106 }
107 cos_alpha = P0[0] * P0[3] - P0[1] * P0[2];
108 P0_idx_0 = P0[3] / cos_alpha;
109 P0_idx_2 = -P0[2] / cos_alpha;
110 P0_idx_1 = -P0[1] / cos_alpha;
111 P0_idx_3 = P0[0] / cos_alpha;
112 cos_alpha = P[0];
113 d = P[1];
114 d1 = P[2];
115 d2 = P[3];
116 d3 = x_pred[0];
117 d4 = x_pred[1];
118 for (i = 0; i < 2; i++) {
119 double d5;
120 double d6;
121 double d7;
122 d5 = a[i + 2];
123 d6 = a[i];
124 d7 = d6 * P0_idx_0 + d5 * P0_idx_1;
125 K[i] = d7;
126 d5 = d6 * P0_idx_2 + d5 * P0_idx_3;
127 K[i + 2] = d5;
128 a_tmp = b_a[i];
129 d6 = (double)a_tmp - (d7 + d5 * 0.0);
130 a[i] = d6;
131 b_a_tmp = b_a[i + 2];
132 d5 = (double)b_a_tmp - (d7 * 0.0 + d5);
133 a[i + 2] = d5;
134 P0[i] = d6 * cos_alpha + d5 * d;
135 P0[i + 2] = d6 * d1 + d5 * d2;
136 b_Ts[i] = z[i] - ((double)a_tmp * d3 + (double)b_a_tmp * d4);
137 }
138 x_est[0] = x_pred[0] + (K[0] * b_Ts[0] + b_Ts[1] * K[2]);
139 x_est[1] = x_pred[1] + (b_Ts[0] * K[1] + b_Ts[1] * K[3]);
140 } else {
141 double a[4];
142 /* Partial update (only altitude) */
143 /* Only observe altitude */
144 /* Only altitude measurement noise */
145 x_est[0] = P[0] + P[2] * 0.0;
146 x_est[1] = P[1] + P[3] * 0.0;
147 cos_alpha =
148 1.0 / (((P[0] + 0.0 * P[1]) + (P[2] + 0.0 * P[3]) * 0.0) + R[0]);
149 x_est[0] *= cos_alpha;
150 x_est[1] *= cos_alpha;
151 a[0] = 1.0 - x_est[0];
152 a[1] = 0.0 - x_est[1];
153 a[2] = 0.0 - x_est[0] * 0.0;
154 a[3] = 1.0 - x_est[1] * 0.0;
155 /* Only update altitude (first element of state vector) */
156 cos_alpha = 0.0;
157 d = P[0];
158 d1 = P[1];
159 d2 = P[2];
160 d3 = P[3];
161 for (i = 0; i < 2; i++) {
162 double d5;
163 d4 = a[i + 2];
164 d5 = a[i];
165 P0[i] = d5 * d + d4 * d1;
166 P0[i + 2] = d5 * d2 + d4 * d3;
167 cos_alpha += (1.0 - (double)i) * x_pred[i];
168 }
169 cos_alpha = z[0] - cos_alpha;
170 x_est[0] = x_pred[0] + x_est[0] * cos_alpha;
171 x_est[1] = x_pred[1] + x_est[1] * cos_alpha;
172 }
173 /* Always update covariance matrix */
174 cos_alpha = P0[0];
175 d = P0[1];
176 d1 = P0[2];
177 d2 = P0[3];
178 for (i = 0; i < 2; i++) {
179 d3 = F[i + 2];
180 a_tmp = (int)F[i];
181 d4 = (double)a_tmp * cos_alpha + d3 * d;
182 d3 = (double)a_tmp * d1 + d3 * d2;
183 P[i] = (d4 + d3 * F[2]) + Q[i];
184 P[i + 2] = (d4 * 0.0 + d3) + Q[i + 2];
185 }
186}
187
188
189/*
190 * File trailer for kalmanFilter_VES_definitive.c
191 *
192 * [EOF]
193 */
void kalmanFilter(double x_est[2], double P[4], const double z[2], double alpha, double a_m, double Ts, const double Q[4], const double R[4], bool gnss_signal)
Executes one prediction and correction step of the Kalman filter.
double alpha
Definition main.c:249
double a_m
Definition main.c:250
const double R[]
Definition main.c:253
double z[]
Definition main.c:248
const double Q[]
Definition main.c:252
double x_est[]
Definition main.c:254
double Ts
Definition main.c:251
Provides MATLAB Coder helper functions for right matrix division.