STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_flight_altitude_optimizer.py
Go to the documentation of this file.
1"""Unit tests for flight altitude optimizer (no RocketPy required)."""
2
3import numpy as np
4
6 BurnTimeEval,
7 optimize_minimum_fuel_burn_time,
8 required_propellant_at_burn_time,
9 truncate_time_series,
10)
11
12
14 times = np.array([0.0, 1.0, 2.0, 3.0])
15 thrust = np.array([100.0, 200.0, 300.0, 400.0])
16 mdot_O = np.ones(4) * 2.0
17 mdot_F = np.ones(4) * 0.5
18
19 t_out, thrust_out, mdot_O_out, mdot_F_out = truncate_time_series(
20 times, thrust, mdot_O, mdot_F, 2.5
21 )
22
23 assert np.isclose(t_out[-1], 2.5)
24 assert np.isclose(thrust_out[-1], 350.0)
25 assert np.isclose(mdot_O_out[-1], 2.0)
26 assert np.isclose(mdot_F_out[-1], 0.5)
27
28
30 times = np.linspace(0, 4, 5)
31 thrust = np.linspace(1000, 2000, 5)
32 mdot_O = np.ones(5) * 1.0
33 mdot_F = np.ones(5) * 0.25
34
35 _, fuel_short, _ = required_propellant_at_burn_time(times, thrust, mdot_O, mdot_F, 2.0)
36 _, fuel_long, _ = required_propellant_at_burn_time(times, thrust, mdot_O, mdot_F, 4.0)
37
38 assert fuel_long > fuel_short
39 assert np.isclose(fuel_short, 0.5, rtol=0.05)
40 assert np.isclose(fuel_long, 1.0, rtol=0.05)
41
42
44 times = np.linspace(0, 10, 11)
45 thrust = np.ones(11) * 5000.0
46 mdot_O = np.ones(11) * 2.0
47 mdot_F = np.ones(11) * 0.4
48
49 # Synthetic apogee ~ 500 * burn_time (monotonic)
50 def simulate_at_burn_time(t: float) -> BurnTimeEval:
51 lox, fuel, _ = required_propellant_at_burn_time(times, thrust, mdot_O, mdot_F, t)
52 apogee = 500.0 * t
53 return BurnTimeEval(
54 burn_time_s=t,
55 lox_required_kg=lox,
56 fuel_required_kg=fuel,
57 apogee_m=apogee,
58 success=True,
59 )
60
61 result = optimize_minimum_fuel_burn_time(
62 times=times,
63 thrust=thrust,
64 mdot_O=mdot_O,
65 mdot_F=mdot_F,
66 target_apogee_m=2000.0,
67 apogee_tolerance_m=50.0,
68 simulate_at_burn_time=simulate_at_burn_time,
69 time_resolution_s=0.1,
70 )
71
72 assert result.success
73 assert np.isclose(result.optimal_burn_time_s, 4.0, atol=0.15)
74 assert np.isclose(result.optimal_fuel_kg, 1.6, rtol=0.1)
75 assert result.achieved_apogee_m >= 1950.0
76
77
79 times = np.linspace(0, 5, 6)
80 thrust = np.ones(6) * 3000.0
81 mdot_O = np.ones(6)
82 mdot_F = np.ones(6) * 0.2
83
84 def simulate_at_burn_time(t: float) -> BurnTimeEval:
85 lox, fuel, _ = required_propellant_at_burn_time(times, thrust, mdot_O, mdot_F, t)
86 return BurnTimeEval(
87 burn_time_s=t,
88 lox_required_kg=lox,
89 fuel_required_kg=fuel,
90 apogee_m=100.0 * t,
91 success=True,
92 )
93
94 result = optimize_minimum_fuel_burn_time(
95 times=times,
96 thrust=thrust,
97 mdot_O=mdot_O,
98 mdot_F=mdot_F,
99 target_apogee_m=2000.0,
100 apogee_tolerance_m=10.0,
101 simulate_at_burn_time=simulate_at_burn_time,
102 )
103
104 assert not result.success
105 assert result.infeasible_reason is not None