Skip to content

Commit 1ffbc47

Browse files
Merge branch 'develop' into env_localise
2 parents bbb2b87 + eaa9181 commit 1ffbc47

5 files changed

Lines changed: 108 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Attention: The newest changes should be on top -->
3333
### Added
3434

3535
- ENH: Air brakes controller functions now support 8-parameter signature [#854](https://github.com/RocketPy-Team/RocketPy/pull/854)
36+
- MNT: net thrust addition to 3 dof in flight class [#907] (https://github.com/RocketPy-Team/RocketPy/pull/907)
3637
- ENH: 3-dof lateral motion improvement [#883](https://github.com/RocketPy-Team/RocketPy/pull/883)
3738
- ENH: Add multi-dimensional drag coefficient support (Cd as function of M, Re, α) [#875](https://github.com/RocketPy-Team/RocketPy/pull/875)
3839
- ENH: Add save functionality to `_MonteCarloPlots.all` method [#848](https://github.com/RocketPy-Team/RocketPy/pull/848)
@@ -53,6 +54,7 @@ Attention: The newest changes should be on top -->
5354

5455
### Fixed
5556

57+
- BUG: energy_data plot not working for 3 dof sims [[#906](https://github.com/RocketPy-Team/RocketPy/issues/906)]
5658
- BUG: Fix CSV column header spacing in FlightDataExporter [#864](https://github.com/RocketPy-Team/RocketPy/issues/864)
5759
- BUG: Fix parallel Monte Carlo simulation showing incorrect iteration count [#806](https://github.com/RocketPy-Team/RocketPy/pull/806)
5860

rocketpy/simulation/flight.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,11 +2042,20 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
20422042
R3 += fz
20432043

20442044
# Thrust and weight
2045-
thrust = self.rocket.motor.thrust.get_value_opt(t)
2045+
# Calculate net thrust including pressure thrust correction if motor is burning
2046+
if self.rocket.motor.burn_start_time < t < self.rocket.motor.burn_out_time:
2047+
pressure = self.env.pressure.get_value_opt(z)
2048+
net_thrust = max(
2049+
self.rocket.motor.thrust.get_value_opt(t)
2050+
+ self.rocket.motor.pressure_thrust(pressure),
2051+
0,
2052+
)
2053+
else:
2054+
net_thrust = 0
20462055
gravity = self.env.gravity.get_value_opt(z)
20472056
weight_body = Kt @ Vector([0, 0, -total_mass * gravity])
20482057

2049-
total_force = Vector([0, 0, thrust]) + weight_body + Vector([R1, R2, R3])
2058+
total_force = Vector([0, 0, net_thrust]) + weight_body + Vector([R1, R2, R3])
20502059

20512060
# Dynamics
20522061
v_dot = K @ (total_force / total_mass)
@@ -2134,7 +2143,7 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
21342143

21352144
if post_processing:
21362145
self.__post_processed_variables.append(
2137-
[t, *v_dot, *w_dot, R1, R2, R3, 0, 0, 0]
2146+
[t, *v_dot, *w_dot, R1, R2, R3, 0, 0, 0, net_thrust]
21382147
)
21392148

21402149
return u_dot

rocketpy/utilities.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def fin_flutter_analysis(
283283
flight,
284284
)
285285
if see_graphs:
286-
_flutter_plots(flight, flutter_mach, safety_factor, filename)
286+
_flutter_plots(flight, flutter_mach, safety_factor, filename=filename)
287287
else:
288288
return flutter_mach, safety_factor
289289

tests/integration/simulation/test_flight_3dof.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,26 @@ def test_weathercock_anti_aligned_uses_perp_axis_and_evolves(flight_weathercock_
301301
assert e_dot_magnitude > 1e-6, (
302302
"Quaternion derivatives should be non-zero for anti-aligned"
303303
)
304+
305+
306+
def test_3dof_net_thrust_available(flight_3dof):
307+
"""Tests that net_thrust property is available in 3 DOF mode.
308+
The net_thrust property is required for energy plots and should be
309+
available in both 3 DOF and 6 DOF modes.
310+
311+
Parameters
312+
----------
313+
flight_3dof : rocketpy.simulation.flight.Flight
314+
A Flight object configured for 3-DOF simulation.
315+
"""
316+
# Check that net_thrust can be accessed
317+
assert hasattr(flight_3dof, "net_thrust"), "net_thrust attribute not found"
318+
319+
# Check that it returns a Function object with data
320+
net_thrust = flight_3dof.net_thrust
321+
assert len(net_thrust) > 0, "net_thrust should have data points"
322+
323+
# Verify that thrust_power can be computed (uses net_thrust internally)
324+
assert hasattr(flight_3dof, "thrust_power"), "thrust_power attribute not found"
325+
thrust_power = flight_3dof.thrust_power
326+
assert len(thrust_power) > 0, "thrust_power should have data points"

tests/unit/test_utilities.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,76 @@ def test_fin_flutter_analysis(flight_calisto_custom_wind):
117117
assert np.isclose(safety_factor(np.inf), 61.669562809629035, atol=5e-3)
118118

119119

120+
def test_fin_flutter_analysis_with_prints(flight_calisto_custom_wind):
121+
"""Test fin_flutter_analysis with see_prints=True to cover print branch.
122+
123+
Parameters
124+
----------
125+
flight_calisto_custom_wind : Flight
126+
A Flight object with a rocket with fins.
127+
"""
128+
flutter_mach, safety_factor = utilities.fin_flutter_analysis(
129+
fin_thickness=2 / 1000,
130+
shear_modulus=10e9,
131+
flight=flight_calisto_custom_wind,
132+
see_prints=True,
133+
see_graphs=False, # False = returns tuple!
134+
filename=None,
135+
)
136+
137+
# Verify returns are valid
138+
assert flutter_mach is not None
139+
assert safety_factor is not None
140+
141+
142+
@patch("matplotlib.pyplot.show")
143+
def test_fin_flutter_analysis_with_graphs(mock_show, flight_calisto_custom_wind): # pylint: disable=unused-argument
144+
"""Test fin_flutter_analysis with see_graphs=True to cover plotting branch.
145+
146+
Parameters
147+
----------
148+
mock_show : mock
149+
Mock of matplotlib.pyplot.show function.
150+
flight_calisto_custom_wind : Flight
151+
A Flight object with a rocket with fins.
152+
"""
153+
result = utilities.fin_flutter_analysis(
154+
fin_thickness=2 / 1000,
155+
shear_modulus=10e9,
156+
flight=flight_calisto_custom_wind,
157+
see_prints=False,
158+
see_graphs=True, # True = returns None!
159+
filename=None,
160+
)
161+
162+
assert result is None
163+
mock_show.assert_called()
164+
165+
166+
@patch("matplotlib.pyplot.show")
167+
def test_fin_flutter_analysis_complete_output(mock_show, flight_calisto_custom_wind): # pylint: disable=unused-argument
168+
"""Test fin_flutter_analysis with both prints and graphs enabled.
169+
170+
Parameters
171+
----------
172+
mock_show : mock
173+
Mock of matplotlib.pyplot.show function.
174+
flight_calisto_custom_wind : Flight
175+
A Flight object with a rocket with fins.
176+
"""
177+
result = utilities.fin_flutter_analysis(
178+
fin_thickness=2 / 1000,
179+
shear_modulus=10e9,
180+
flight=flight_calisto_custom_wind,
181+
see_prints=True,
182+
see_graphs=True, # True = returns None!
183+
filename=None,
184+
)
185+
186+
assert result is None
187+
mock_show.assert_called()
188+
189+
120190
def test_flutter_prints(flight_calisto_custom_wind):
121191
"""Tests the _flutter_prints function.
122192

0 commit comments

Comments
 (0)