Da Vinci Firmware 1
Firmware for the DaVinci-M rocket avionics board.
Loading...
Searching...
No Matches
optimalAngle.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: optimalAngle.c
6 *
7 * MATLAB Coder version : 24.2
8 * C/C++ source code generated on : 06-May-2025 18:24:48
9 */
10
11/* Include Files */
12#include "optimalAngle.h"
13#include "cdEvaluation.h"
14#include "rt_nonfinite.h"
15#include "rt_nonfinite.h"
16#include <math.h>
17
18/* Function Declarations */
19static double rt_powd_snf(double u0, double u1);
20
21/* Function Definitions */
22/*
23 * Arguments : double u0
24 * double u1
25 * Return Type : double
26 */
27static double rt_powd_snf(double u0, double u1)
28{
29 double y;
30 if (rtIsNaN(u0) || rtIsNaN(u1)) {
31 y = rtNaN;
32 } else {
33 double d;
34 y = fabs(u0);
35 d = fabs(u1);
36 if (rtIsInf(u1)) {
37 if (y == 1.0) {
38 y = 1.0;
39 } else if (y > 1.0) {
40 if (u1 > 0.0) {
41 y = rtInf;
42 } else {
43 y = 0.0;
44 }
45 } else if (u1 > 0.0) {
46 y = 0.0;
47 } else {
48 y = rtInf;
49 }
50 } else if (d == 0.0) {
51 y = 1.0;
52 } else if (d == 1.0) {
53 if (u1 > 0.0) {
54 y = u0;
55 } else {
56 y = 1.0 / u0;
57 }
58 } else if (u1 == 2.0) {
59 y = u0 * u0;
60 } else if ((u1 == 0.5) && (u0 >= 0.0)) {
61 y = sqrt(u0);
62 } else if ((u0 < 0.0) && (u1 > floor(u1))) {
63 y = rtNaN;
64 } else {
65 y = pow(u0, u1);
66 }
67 }
68 return y;
69}
70
71/*
72 * Arguments : double sim_time_step
73 * double altitude
74 * double temperature
75 * double velocity
76 * double pressure
77 * double current_delta
78 * double tilt_angle
79 * double target_apogee
80 * double tolerance
81 * const double mach_states[5]
82 * const double deployment_states[6]
83 * const double cd_table[30]
84 * Return Type : double
85 */
86double optimalAngle(double sim_time_step, double altitude, double temperature,
87 double velocity, double pressure, double current_delta,
88 double tilt_angle, double target_apogee, double tolerance,
89 const double mach_states[5],
90 const double deployment_states[6],
91 const double cd_table[30])
92{
93 double dep_max;
94 double dep_min;
95 double max_change;
96 double opt_dep;
97 /* placeholder */
98 dep_min = 0.0;
99 /* deg */
100 dep_max = 173.0;
101 /* deg */
102 max_change = 182.6 * sim_time_step;
103 while (dep_max - dep_min > tolerance) {
104 double delta;
105 double elapsed_time;
106 double pressure_current;
107 double temperature_current;
108 double test_delta;
109 double v_current;
110 double x_dot_predicted;
111 double y_current;
112 double y_dot_current;
113 test_delta = (dep_max + dep_min) / 2.0;
114 delta = current_delta;
115 elapsed_time = 0.0;
116 temperature_current = temperature;
117 pressure_current = pressure;
118 y_current = altitude;
119 v_current = velocity;
120 x_dot_predicted = velocity * sin(tilt_angle);
121 y_dot_current = velocity * cos(tilt_angle);
122 while (y_dot_current > 0.0) {
123 double speed_of_sound;
124 double x_dotdot;
125 double y_dotdot;
126 if (elapsed_time > 0.1) {
127 opt_dep = test_delta - delta;
128 if (fabs(opt_dep) > max_change) {
129 if (rtIsNaN(opt_dep)) {
130 opt_dep = rtNaN;
131 } else if (opt_dep < 0.0) {
132 opt_dep = -1.0;
133 } else {
134 opt_dep = (opt_dep > 0.0);
135 }
136 delta += opt_dep * max_change;
137 } else {
138 delta = test_delta;
139 }
140 }
141 speed_of_sound = sqrt(401.79999999999995 * temperature_current);
142 pressure_current = 0.5 *
143 (pressure_current / (287.0 * temperature_current)) *
144 0.014102609421964583;
145 opt_dep = pressure_current * cdEvaluation(deployment_states, mach_states,
146 cd_table, delta,
147 v_current / speed_of_sound);
148 x_dotdot = -opt_dep * x_dot_predicted * v_current / 23.458000008756152;
149 y_dotdot =
150 -opt_dep * y_dot_current * v_current / 23.458000008756152 - 9.81;
151 opt_dep = x_dot_predicted + x_dotdot * sim_time_step;
152 temperature_current = y_dot_current + y_dotdot * sim_time_step;
153 v_current =
154 sqrt(opt_dep * opt_dep + temperature_current * temperature_current);
155 opt_dep = pressure_current * cdEvaluation(deployment_states, mach_states,
156 cd_table, delta,
157 v_current / speed_of_sound);
158 x_dot_predicted += 0.5 *
159 (x_dotdot + -opt_dep * x_dot_predicted * v_current /
160 23.458000008756152) *
162 opt_dep =
163 y_dot_current + 0.5 *
164 (y_dotdot + (-opt_dep * y_dot_current *
165 v_current / 23.458000008756152 -
166 9.81)) *
168 y_current += 0.5 * (y_dot_current + opt_dep) * sim_time_step;
169 y_dot_current = opt_dep;
170 v_current = sqrt(x_dot_predicted * x_dot_predicted + opt_dep * opt_dep);
171 temperature_current = temperature - 0.00649 * (y_current - altitude);
172 pressure_current =
173 pressure * rt_powd_snf(temperature_current / temperature, 5.2561);
174 elapsed_time += sim_time_step;
175 }
176 if (y_current > target_apogee) {
177 dep_min = test_delta;
178 } else {
179 dep_max = test_delta;
180 }
181 }
182 return 180 - ((dep_min + dep_max) / 2.0);
183}
184
185/*
186 * File trailer for optimalAngle.c
187 *
188 * [EOF]
189 */
double cdEvaluation(const double dep_states[6], const double mach_states[5], const double cd_table[30], double dep, double mach)
Estimates the coefficient of drag (Cd) via 2D bilinear interpolation.
Performs 2D bilinear interpolation to estimate the coefficient of drag (Cd).
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).
double current_delta
Definition main.c:257
const double mach_states[]
Definition main.c:261
float_t altitude
Definition main.c:224
double tilt_angle
Definition main.c:260
double sim_time_step
Definition main.c:256
double tolerance
Definition main.c:259
float_t velocity
Definition main.c:225
double target_apogee
Definition main.c:258
const double deployment_states[]
Definition main.c:262
static double cd_table[]
Definition main.c:263
double optimalAngle(double sim_time_step, double altitude, double temperature, double velocity, double pressure, double current_delta, double tilt_angle, double target_apogee, double tolerance, const double mach_states[5], const double deployment_states[6], const double cd_table[30])
Calculates the optimal constant airbrake angle to reach a target apogee.
static double rt_powd_snf(double u0, double u1)
Model Predictive Controller (MPC) to determine the optimal airbrake angle.
Provides definitions and utility functions for non-finite floating-point values.