Skip to content

Commit 4cc5d83

Browse files
MNT: EmptyMotor class inherits from Motor(ABC) (#779)
* MNT: reimplement EmptyMotor class and refactor imports * MNT: add structural mass ratio property to EmptyMotor class * MNT: refactor EmptyMotor properties to use funcify_method and add tests * DEV: updates changelog
1 parent e640744 commit 4cc5d83

File tree

11 files changed

+120
-60
lines changed

11 files changed

+120
-60
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ Attention: The newest changes should be on top -->
3232

3333
### Added
3434

35-
- DOC: ASTRA Flight Example [#770](https://github.com/RocketPy-Team/RocketPy/pull/770))
35+
- DOC: ASTRA Flight Example [#770](https://github.com/RocketPy-Team/RocketPy/pull/770)
3636

3737
### Changed
3838

39-
-
39+
- MNT: EmptyMotor class inherits from Motor(ABC) [#779](https://github.com/RocketPy-Team/RocketPy/pull/779)
4040

4141
### Fixed
4242

rocketpy/motors/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from .empty_motor import EmptyMotor
12
from .fluid import Fluid
23
from .hybrid_motor import HybridMotor
34
from .liquid_motor import LiquidMotor
4-
from .motor import EmptyMotor, GenericMotor, Motor
5+
from .motor import GenericMotor, Motor
56
from .solid_motor import SolidMotor
67
from .tank import (
78
LevelBasedTank,

rocketpy/motors/empty_motor.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from rocketpy.mathutils import Function, funcify_method
2+
from rocketpy.motors.motor import Motor
3+
4+
5+
class EmptyMotor(Motor):
6+
"""Class that represents an empty motor with no mass and no thrust."""
7+
8+
def __init__(self):
9+
"""Initializes an empty motor with no mass and no thrust."""
10+
11+
super().__init__(
12+
thrust_source=0,
13+
dry_inertia=(0, 0, 0),
14+
nozzle_radius=0,
15+
center_of_dry_mass_position=0,
16+
dry_mass=0,
17+
nozzle_position=0,
18+
burn_time=1,
19+
reshape_thrust_curve=False,
20+
interpolation_method="linear",
21+
coordinate_system_orientation="nozzle_to_combustion_chamber",
22+
)
23+
24+
# Mass properties
25+
self.propellant_mass = Function(0, "Time (s)", "Propellant Mass (kg)")
26+
self.total_mass = Function(0, "Time (s)", "Total Mass (kg)")
27+
self.total_mass_flow_rate = Function(
28+
0, "Time (s)", "Mass Depletion Rate (kg/s)"
29+
)
30+
self.center_of_mass = Function(0, "Time (s)", "Center of Mass (kg)")
31+
32+
# Inertia properties
33+
self.I_11 = Function(0)
34+
self.I_22 = Function(0)
35+
self.I_33 = Function(0)
36+
self.I_12 = Function(0)
37+
self.I_13 = Function(0)
38+
self.I_23 = Function(0)
39+
40+
@funcify_method("Time (s)", "Center of Propellant Mass (kg)", "linear", "zero")
41+
def center_of_propellant_mass(self):
42+
return 0
43+
44+
@funcify_method("Time (s)", "Exhaust Velocity (m/s)", "linear", "zero")
45+
def exhaust_velocity(self):
46+
return 0
47+
48+
@property
49+
def propellant_initial_mass(self):
50+
return 0
51+
52+
@funcify_method("Time (s)", "Propellant I_11 (kg m²)", "linear", "zero")
53+
def propellant_I_11(self):
54+
return 0
55+
56+
@funcify_method("Time (s)", "Propellant I_12 (kg m²)", "linear", "zero")
57+
def propellant_I_12(self):
58+
return 0
59+
60+
@funcify_method("Time (s)", "Propellant I_13 (kg m²)", "linear", "zero")
61+
def propellant_I_13(self):
62+
return 0
63+
64+
@funcify_method("Time (s)", "Propellant I_22 (kg m²)", "linear", "zero")
65+
def propellant_I_22(self):
66+
return 0
67+
68+
@funcify_method("Time (s)", "Propellant I_23 (kg m²)", "linear", "zero")
69+
def propellant_I_23(self):
70+
return 0
71+
72+
@funcify_method("Time (s)", "Propellant I_33 (kg m²)", "linear", "zero")
73+
def propellant_I_33(self):
74+
return 0
75+
76+
@property
77+
def structural_mass_ratio(self):
78+
return 0

rocketpy/motors/motor.py

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ def all_info(self):
11631163
self.plots.all()
11641164

11651165

1166+
# TODO: move this class to a separate file, needs a breaking change warning
11661167
class GenericMotor(Motor):
11671168
"""Class that represents a simple motor defined mainly by its thrust curve.
11681169
There is no distinction between the propellant types (e.g. Solid, Liquid).
@@ -1601,56 +1602,3 @@ def from_dict(cls, data):
16011602
nozzle_position=data["nozzle_position"],
16021603
interpolation_method=data["interpolate"],
16031604
)
1604-
1605-
1606-
class EmptyMotor:
1607-
"""Class that represents an empty motor with no mass and no thrust."""
1608-
1609-
# TODO: This is a temporary solution. It should be replaced by a class that
1610-
# inherits from the abstract Motor class. Currently cannot be done easily.
1611-
# pylint: disable=too-many-statements
1612-
def __init__(self):
1613-
"""Initializes an empty motor with no mass and no thrust.
1614-
1615-
Notes
1616-
-----
1617-
This class is a temporary solution to the problem of having a motor
1618-
with no mass and no thrust. It should be replaced by a class that
1619-
inherits from the abstract Motor class. Currently cannot be done easily.
1620-
"""
1621-
self._csys = 1
1622-
self.dry_mass = 0
1623-
self.nozzle_radius = 0
1624-
self.thrust = Function(0, "Time (s)", "Thrust (N)")
1625-
self.propellant_mass = Function(0, "Time (s)", "Propellant Mass (kg)")
1626-
self.propellant_initial_mass = 0
1627-
self.total_mass = Function(0, "Time (s)", "Total Mass (kg)")
1628-
self.total_mass_flow_rate = Function(
1629-
0, "Time (s)", "Mass Depletion Rate (kg/s)"
1630-
)
1631-
self.burn_out_time = 1
1632-
self.nozzle_position = 0
1633-
self.nozzle_radius = 0
1634-
self.center_of_dry_mass_position = 0
1635-
self.center_of_propellant_mass = Function(
1636-
0, "Time (s)", "Center of Propellant Mass (kg)"
1637-
)
1638-
self.center_of_mass = Function(0, "Time (s)", "Center of Mass (kg)")
1639-
self.dry_I_11 = 0
1640-
self.dry_I_22 = 0
1641-
self.dry_I_33 = 0
1642-
self.dry_I_12 = 0
1643-
self.dry_I_13 = 0
1644-
self.dry_I_23 = 0
1645-
self.propellant_I_11 = Function(0, "Time (s)", "Propellant I_11 (kg m²)")
1646-
self.propellant_I_22 = Function(0, "Time (s)", "Propellant I_22 (kg m²)")
1647-
self.propellant_I_33 = Function(0, "Time (s)", "Propellant I_33 (kg m²)")
1648-
self.propellant_I_12 = Function(0, "Time (s)", "Propellant I_12 (kg m²)")
1649-
self.propellant_I_13 = Function(0, "Time (s)", "Propellant I_13 (kg m²)")
1650-
self.propellant_I_23 = Function(0, "Time (s)", "Propellant I_23 (kg m²)")
1651-
self.I_11 = Function(0)
1652-
self.I_22 = Function(0)
1653-
self.I_33 = Function(0)
1654-
self.I_12 = Function(0)
1655-
self.I_13 = Function(0)
1656-
self.I_23 = Function(0)

rocketpy/rocket/rocket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from rocketpy.control.controller import _Controller
77
from rocketpy.mathutils.function import Function
88
from rocketpy.mathutils.vector_matrix import Matrix, Vector
9-
from rocketpy.motors.motor import EmptyMotor
9+
from rocketpy.motors.empty_motor import EmptyMotor
1010
from rocketpy.plots.rocket_plots import _RocketPlots
1111
from rocketpy.prints.rocket_prints import _RocketPrints
1212
from rocketpy.rocket.aero_surface import (

rocketpy/stochastic/stochastic_rocket.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from random import choice
55

66
from rocketpy.mathutils.vector_matrix import Vector
7-
from rocketpy.motors.motor import EmptyMotor, GenericMotor, Motor
7+
from rocketpy.motors.empty_motor import EmptyMotor
8+
from rocketpy.motors.motor import GenericMotor, Motor
89
from rocketpy.motors.solid_motor import SolidMotor
910
from rocketpy.rocket.aero_surface import (
1011
EllipticalFins,

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"tests.fixtures.motor.liquid_fixtures",
99
"tests.fixtures.motor.hybrid_fixtures",
1010
"tests.fixtures.motor.solid_motor_fixtures",
11+
"tests.fixtures.motor.empty_motor_fixtures",
1112
"tests.fixtures.motor.tanks_fixtures",
1213
"tests.fixtures.motor.tank_geometry_fixtures",
1314
"tests.fixtures.motor.generic_motor_fixtures",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pytest
2+
3+
from rocketpy.motors.empty_motor import EmptyMotor
4+
5+
6+
@pytest.fixture
7+
def empty_motor():
8+
"""An example of an empty motor with zero thrust and mass.
9+
10+
Returns
11+
-------
12+
rocketpy.EmptyMotor
13+
"""
14+
return EmptyMotor()

tests/fixtures/motor/solid_motor_fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def dimensionless_cesaroni_m1670(kg, m): # old name: dimensionless_motor
122122
@pytest.fixture
123123
def dummy_empty_motor():
124124
# Create a motor with ZERO thrust and ZERO mass to keep the rocket's speed constant
125-
# TODO: why don t we use these same values to create EmptyMotor class?
125+
# TODO: Maybe we should simple use the new `EmptyMotor` class?
126126
return SolidMotor(
127127
thrust_source=1e-300,
128128
burn_time=1e-10,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from unittest.mock import patch
2+
3+
4+
@patch("matplotlib.pyplot.show")
5+
def test_empty_motor_info(mock_show, empty_motor): # pylint: disable=unused-argument
6+
"""Tests the LiquidMotor.all_info() method.
7+
8+
Parameters
9+
----------
10+
mock_show : mock
11+
Mock of the matplotlib.pyplot.show function.
12+
empty_motor : rocketpy.EmptyMotor
13+
The EmptyMotor object to be used in the tests.
14+
"""
15+
assert empty_motor.info() is None
16+
assert empty_motor.all_info() is None

0 commit comments

Comments
 (0)