61 """Test that blowdown decreases P_u when u=0 and mdot>0."""
63 u = np.array([0.0, 0.0], dtype=np.float64)
66 P_u_F_initial = self.
x0[IDX_P_U_F]
67 P_u_O_initial = self.
x0[IDX_P_U_O]
73 P_u_F_next = x_next[IDX_P_U_F]
74 P_u_O_next = x_next[IDX_P_U_O]
76 self.assertLess(P_u_F_next, P_u_F_initial,
77 f
"P_u_F should decrease: {P_u_F_next} < {P_u_F_initial}")
78 self.assertLess(P_u_O_next, P_u_O_initial,
79 f
"P_u_O should decrease: {P_u_O_next} < {P_u_O_initial}")
82 """Test that pressurization increases P_u when u>0 and headroom positive."""
84 u = np.array([1.0, 1.0], dtype=np.float64)
97 P_u_F_initial = x[IDX_P_U_F]
98 P_u_O_initial = x[IDX_P_U_O]
101 x_next = step(x, u, self.
dt, self.
params, mdot_F_low, mdot_O_low)
104 P_u_F_next = x_next[IDX_P_U_F]
105 P_u_O_next = x_next[IDX_P_U_O]
107 self.assertGreater(P_u_F_next, P_u_F_initial,
108 f
"P_u_F should increase: {P_u_F_next} > {P_u_F_initial}")
109 self.assertGreater(P_u_O_next, P_u_O_initial,
110 f
"P_u_O should increase: {P_u_O_next} > {P_u_O_initial}")
113 """Test that ullage volume increases with propellant consumption."""
114 V_u_F_initial = self.
x0[IDX_V_U_F]
115 V_u_O_initial = self.
x0[IDX_V_U_O]
119 V_u_F_next = x_next[IDX_V_U_F]
120 V_u_O_next = x_next[IDX_V_U_O]
123 self.assertGreater(V_u_F_next, V_u_F_initial,
124 f
"V_u_F should increase: {V_u_F_next} > {V_u_F_initial}")
125 self.assertGreater(V_u_O_next, V_u_O_initial,
126 f
"V_u_O should increase: {V_u_O_next} > {V_u_O_initial}")
129 """Test COPV pressure decreases with control usage."""
130 P_copv_initial = self.
x0[IDX_P_COPV]
134 P_copv_next = x_next[IDX_P_COPV]
137 self.assertLess(P_copv_next, P_copv_initial,
138 f
"P_copv should decrease: {P_copv_next} < {P_copv_initial}")
141 u_zero = np.array([0.0, 0.0], dtype=np.float64)
142 x_next_zero = step(self.
x0, u_zero, self.
dt, self.
params, 0.0, 0.0)
143 P_copv_next_zero = x_next_zero[IDX_P_COPV]
145 self.assertLess(P_copv_next_zero, P_copv_initial,
146 f
"P_copv should decrease even with u=0 due to loss: "
147 f
"{P_copv_next_zero} < {P_copv_initial}")
150 """Test regulator pressure behavior."""
152 params_setpoint = DynamicsParams.from_config(self.
config)
153 params_setpoint.reg_setpoint = 25e6
156 P_reg_next = x_next[IDX_P_REG]
159 self.assertAlmostEqual(P_reg_next, 25e6, delta=1e3,
160 msg=f
"P_reg should be at setpoint: {P_reg_next} ≈ 25e6")
163 params_ratio = DynamicsParams.from_config(self.
config)
164 params_ratio.reg_setpoint =
None
165 params_ratio.reg_ratio = 0.8
167 x_next_ratio = step(self.
x0, self.
u0, self.
dt, params_ratio, self.
mdot_F, self.
mdot_O)
168 P_reg_next_ratio = x_next_ratio[IDX_P_REG]
169 P_copv_next_ratio = x_next_ratio[IDX_P_COPV]
172 expected_P_reg = params_ratio.reg_ratio * P_copv_next_ratio
173 self.assertAlmostEqual(P_reg_next_ratio, expected_P_reg, delta=1e3,
174 msg=f
"P_reg should be {params_ratio.reg_ratio} * P_copv: "
175 f
"{P_reg_next_ratio} ≈ {expected_P_reg}")
178 """Test feed pressure follows ullage pressure with lag."""
187 P_d_F_next = x_next[IDX_P_D_F]
188 P_d_O_next = x_next[IDX_P_D_O]
191 self.assertGreater(P_d_F_next, x[IDX_P_D_F],
192 f
"P_d_F should increase toward P_u_F: {P_d_F_next} > {x[IDX_P_D_F]}")
193 self.assertGreater(P_d_O_next, x[IDX_P_D_O],
194 f
"P_d_O should increase toward P_u_O: {P_d_O_next} > {x[IDX_P_D_O]}")
197 """Test linearization returns correct matrix shapes."""
200 self.assertEqual(A.shape, (N_STATE, N_STATE))
201 self.assertEqual(B.shape, (N_STATE, N_CONTROL))
202 self.assertTrue(np.all(np.isfinite(A)))
203 self.assertTrue(np.all(np.isfinite(B)))