Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Attention: The newest changes should be on top -->

### Added

- MNT: net thrust addition to 3 dof in flight class [#907] (https://github.com/RocketPy-Team/RocketPy/pull/907)
- ENH: 3-dof lateral motion improvement [#883](https://github.com/RocketPy-Team/RocketPy/pull/883)
- ENH: Add multi-dimensional drag coefficient support (Cd as function of M, Re, α) [#875](https://github.com/RocketPy-Team/RocketPy/pull/875)
- ENH: Add save functionality to `_MonteCarloPlots.all` method [#848](https://github.com/RocketPy-Team/RocketPy/pull/848)
Expand All @@ -52,6 +53,7 @@ Attention: The newest changes should be on top -->

### Fixed

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

Expand Down
15 changes: 12 additions & 3 deletions rocketpy/simulation/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -2041,11 +2041,20 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):
R3 += fz

# Thrust and weight
thrust = self.rocket.motor.thrust.get_value_opt(t)
# Calculate net thrust including pressure thrust correction if motor is burning
if self.rocket.motor.burn_start_time < t < self.rocket.motor.burn_out_time:
pressure = self.env.pressure.get_value_opt(z)
net_thrust = max(
self.rocket.motor.thrust.get_value_opt(t)
+ self.rocket.motor.pressure_thrust(pressure),
0,
)
else:
net_thrust = 0
gravity = self.env.gravity.get_value_opt(z)
weight_body = Kt @ Vector([0, 0, -total_mass * gravity])

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

# Dynamics
v_dot = K @ (total_force / total_mass)
Expand Down Expand Up @@ -2133,7 +2142,7 @@ def u_dot_generalized_3dof(self, t, u, post_processing=False):

if post_processing:
self.__post_processed_variables.append(
[t, *v_dot, *w_dot, R1, R2, R3, 0, 0, 0]
[t, *v_dot, *w_dot, R1, R2, R3, 0, 0, 0, net_thrust]
)

return u_dot
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/simulation/test_flight_3dof.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,26 @@ def test_weathercock_anti_aligned_uses_perp_axis_and_evolves(flight_weathercock_
assert e_dot_magnitude > 1e-6, (
"Quaternion derivatives should be non-zero for anti-aligned"
)


def test_3dof_net_thrust_available(flight_3dof):
"""Tests that net_thrust property is available in 3 DOF mode.
The net_thrust property is required for energy plots and should be
available in both 3 DOF and 6 DOF modes.

Parameters
----------
flight_3dof : rocketpy.simulation.flight.Flight
A Flight object configured for 3-DOF simulation.
"""
# Check that net_thrust can be accessed
assert hasattr(flight_3dof, "net_thrust"), "net_thrust attribute not found"

# Check that it returns a Function object with data
net_thrust = flight_3dof.net_thrust
assert len(net_thrust) > 0, "net_thrust should have data points"

# Verify that thrust_power can be computed (uses net_thrust internally)
assert hasattr(flight_3dof, "thrust_power"), "thrust_power attribute not found"
thrust_power = flight_3dof.thrust_power
assert len(thrust_power) > 0, "thrust_power should have data points"