rocketpy 1.2.0__tar.gz → 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rocketpy-1.2.0 → rocketpy-1.2.1}/PKG-INFO +1 -1
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/rocket_prints.py +8 -1
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/rocket/aero_surface.py +10 -2
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/rocket/rocket.py +21 -10
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy.egg-info/PKG-INFO +1 -1
- {rocketpy-1.2.0 → rocketpy-1.2.1}/setup.py +1 -1
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_rocket.py +75 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/LICENSE +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/README.md +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/control/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/control/controller.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/environment/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/environment/environment.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/environment/environment_analysis.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/mathutils/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/mathutils/function.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/mathutils/vector_matrix.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/fluid.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/hybrid_motor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/liquid_motor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/motor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/solid_motor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/tank.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/motors/tank_geometry.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/aero_surface_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/compare/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/compare/compare.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/compare/compare_flights.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/environment_analysis_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/environment_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/flight_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/fluid_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/hybrid_motor_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/liquid_motor_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/motor_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/rocket_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/solid_motor_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/tank_geometry_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/plots/tank_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/aero_surface_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/compare_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/controller_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/environment_analysis_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/environment_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/flight_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/fluid_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/hybrid_motor_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/liquid_motor_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/motor_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/parachute_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/solid_motor_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/tank_geometry_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/prints/tank_prints.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/rocket/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/rocket/components.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/rocket/parachute.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/simulation/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/simulation/flight.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/simulation/flight_data_importer.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/tools.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/units.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy/utilities.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy.egg-info/SOURCES.txt +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy.egg-info/dependency_links.txt +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy.egg-info/requires.txt +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/rocketpy.egg-info/top_level.txt +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/setup.cfg +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/__init__.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/conftest.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_environment.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_environment_analysis.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_flight.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_flight_data_importer.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_function.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_genericmotor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_hybridmotor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_liquidmotor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_plots.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_solidmotor.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_tank.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_tools_matrix.py +0 -0
- {rocketpy-1.2.0 → rocketpy-1.2.1}/tests/test_tools_vector.py +0 -0
|
@@ -114,9 +114,13 @@ class _RocketPrints:
|
|
|
114
114
|
print("\nAerodynamics Lift Coefficient Derivatives\n")
|
|
115
115
|
for surface, position in self.rocket.aerodynamic_surfaces:
|
|
116
116
|
name = surface.name
|
|
117
|
+
# ref_factor corrects lift for different reference areas
|
|
118
|
+
ref_factor = (surface.rocket_radius / self.rocket.radius) ** 2
|
|
117
119
|
print(
|
|
118
120
|
name
|
|
119
|
-
+ " Lift Coefficient Derivative: {:.3f}".format(
|
|
121
|
+
+ " Lift Coefficient Derivative: {:.3f}".format(
|
|
122
|
+
ref_factor * surface.clalpha(0)
|
|
123
|
+
)
|
|
120
124
|
+ "/rad"
|
|
121
125
|
)
|
|
122
126
|
|
|
@@ -135,6 +139,9 @@ class _RocketPrints:
|
|
|
135
139
|
print(
|
|
136
140
|
f"Center of Mass position (time=0): {self.rocket.center_of_mass(0):.3f} m"
|
|
137
141
|
)
|
|
142
|
+
print(
|
|
143
|
+
f"Center of Pressure position (time=0): {self.rocket.cp_position(0):.3f} m"
|
|
144
|
+
)
|
|
138
145
|
print(
|
|
139
146
|
"Initial Static Margin (mach=0, time=0): "
|
|
140
147
|
+ "{:.3f}".format(self.rocket.static_margin(0))
|
|
@@ -349,12 +349,20 @@ class NoseCone(AeroSurface):
|
|
|
349
349
|
# If base radius is not given, the ratio between base radius and
|
|
350
350
|
# rocket radius is assumed as 1, meaning that the nose cone has the
|
|
351
351
|
# same radius as the rocket
|
|
352
|
-
if self.base_radius is None
|
|
352
|
+
if self.base_radius is None and self.rocket_radius is not None:
|
|
353
353
|
self.radius_ratio = 1
|
|
354
|
+
self.base_radius = self.rocket_radius
|
|
355
|
+
elif self.base_radius is not None and self.rocket_radius is None:
|
|
356
|
+
self.radius_ratio = 1
|
|
357
|
+
self.rocket_radius = self.base_radius
|
|
354
358
|
# If base radius is given, the ratio between base radius and rocket
|
|
355
359
|
# radius is calculated
|
|
356
|
-
|
|
360
|
+
elif self.base_radius is not None and self.rocket_radius is not None:
|
|
357
361
|
self.radius_ratio = self.base_radius / self.rocket_radius
|
|
362
|
+
else:
|
|
363
|
+
raise ValueError(
|
|
364
|
+
"Either base radius or rocket radius must be given to calculate the nose cone radius ratio."
|
|
365
|
+
)
|
|
358
366
|
|
|
359
367
|
self.fineness_ratio = self.length / (2 * self.base_radius)
|
|
360
368
|
return None
|
|
@@ -517,9 +517,13 @@ class Rocket:
|
|
|
517
517
|
# Calculate total lift coefficient derivative and center of pressure
|
|
518
518
|
if len(self.aerodynamic_surfaces) > 0:
|
|
519
519
|
for aero_surface, position in self.aerodynamic_surfaces:
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
520
|
+
# ref_factor corrects lift for different reference areas
|
|
521
|
+
ref_factor = (aero_surface.rocket_radius / self.radius) ** 2
|
|
522
|
+
self.total_lift_coeff_der += ref_factor * aero_surface.clalpha
|
|
523
|
+
self.cp_position += (
|
|
524
|
+
ref_factor
|
|
525
|
+
* aero_surface.clalpha
|
|
526
|
+
* (position - self._csys * aero_surface.cpz)
|
|
523
527
|
)
|
|
524
528
|
self.cp_position /= self.total_lift_coeff_der
|
|
525
529
|
|
|
@@ -871,7 +875,9 @@ class Rocket:
|
|
|
871
875
|
self.add_surfaces(tail, position)
|
|
872
876
|
return tail
|
|
873
877
|
|
|
874
|
-
def add_nose(
|
|
878
|
+
def add_nose(
|
|
879
|
+
self, length, kind, position, bluffness=0, name="Nose Cone", base_radius=None
|
|
880
|
+
):
|
|
875
881
|
"""Creates a nose cone, storing its parameters as part of the
|
|
876
882
|
aerodynamic_surfaces list. Its parameters are the axial position
|
|
877
883
|
along the rocket and its derivative of the coefficient of lift
|
|
@@ -894,6 +900,9 @@ class Rocket:
|
|
|
894
900
|
the radius of the base of the ogive.
|
|
895
901
|
name : string
|
|
896
902
|
Nose cone name. Default is "Nose Cone".
|
|
903
|
+
base_radius : int, float, optional
|
|
904
|
+
Nose cone base radius in meters. If not given, the rocket radius
|
|
905
|
+
will be used.
|
|
897
906
|
|
|
898
907
|
See Also
|
|
899
908
|
--------
|
|
@@ -907,8 +916,8 @@ class Rocket:
|
|
|
907
916
|
nose = NoseCone(
|
|
908
917
|
length=length,
|
|
909
918
|
kind=kind,
|
|
910
|
-
base_radius=self.radius,
|
|
911
|
-
rocket_radius=self.radius,
|
|
919
|
+
base_radius=base_radius or self.radius,
|
|
920
|
+
rocket_radius=base_radius or self.radius,
|
|
912
921
|
bluffness=bluffness,
|
|
913
922
|
name=name,
|
|
914
923
|
)
|
|
@@ -983,8 +992,9 @@ class Rocket:
|
|
|
983
992
|
with its base perpendicular to the rocket's axis. Cannot be used in
|
|
984
993
|
conjunction with sweep_length.
|
|
985
994
|
radius : int, float, optional
|
|
986
|
-
Reference radius
|
|
987
|
-
|
|
995
|
+
Reference fuselage radius where the fins are located. This is used
|
|
996
|
+
to calculate lift coefficient and to draw the rocket. If None,
|
|
997
|
+
which is default, the rocket radius will be used.
|
|
988
998
|
airfoil : tuple, optional
|
|
989
999
|
Default is null, in which case fins will be treated as flat plates.
|
|
990
1000
|
Otherwise, if tuple, fins will be considered as airfoils. The
|
|
@@ -1064,8 +1074,9 @@ class Rocket:
|
|
|
1064
1074
|
Fins cant angle with respect to the rocket centerline. Must be given
|
|
1065
1075
|
in degrees.
|
|
1066
1076
|
radius : int, float, optional
|
|
1067
|
-
Reference radius
|
|
1068
|
-
|
|
1077
|
+
Reference fuselage radius where the fins are located. This is used
|
|
1078
|
+
to calculate lift coefficient and to draw the rocket. If None,
|
|
1079
|
+
which is default, the rocket radius will be used.
|
|
1069
1080
|
airfoil : tuple, optional
|
|
1070
1081
|
Default is null, in which case fins will be treated as flat plates.
|
|
1071
1082
|
Otherwise, if tuple, fins will be considered as airfoils. The
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from unittest.mock import patch
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
+
import pytest
|
|
4
5
|
|
|
5
6
|
from rocketpy import Rocket, SolidMotor
|
|
7
|
+
from rocketpy.rocket import NoseCone
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
@patch("matplotlib.pyplot.show")
|
|
@@ -205,3 +207,76 @@ def test_air_brakes_clamp_off(mock_show, calisto_air_brakes_clamp_off):
|
|
|
205
207
|
assert air_brakes_clamp_off.deployment_level == 0
|
|
206
208
|
|
|
207
209
|
assert air_brakes_clamp_off.all_info() == None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def test_add_surfaces_different_noses(calisto):
|
|
213
|
+
"""Test the add_surfaces method with different nose cone configurations.
|
|
214
|
+
More specifically, this will check the static margin of the rocket with
|
|
215
|
+
different nose cone configurations.
|
|
216
|
+
|
|
217
|
+
Parameters
|
|
218
|
+
----------
|
|
219
|
+
calisto : Rocket
|
|
220
|
+
Pytest fixture for the calisto rocket.
|
|
221
|
+
"""
|
|
222
|
+
length = 0.55829
|
|
223
|
+
kind = "vonkarman"
|
|
224
|
+
position = 1.16
|
|
225
|
+
bluffness = 0
|
|
226
|
+
base_radius = 0.0635
|
|
227
|
+
rocket_radius = 0.0635
|
|
228
|
+
|
|
229
|
+
# Case 1: base_radius == rocket_radius
|
|
230
|
+
nose1 = NoseCone(
|
|
231
|
+
length,
|
|
232
|
+
kind,
|
|
233
|
+
base_radius=base_radius,
|
|
234
|
+
bluffness=bluffness,
|
|
235
|
+
rocket_radius=rocket_radius,
|
|
236
|
+
name="Nose Cone 1",
|
|
237
|
+
)
|
|
238
|
+
calisto.add_surfaces(nose1, position)
|
|
239
|
+
assert nose1.radius_ratio == pytest.approx(1, 1e-8)
|
|
240
|
+
assert calisto.static_margin(0) == pytest.approx(-8.9053, 0.01)
|
|
241
|
+
|
|
242
|
+
# Case 2: base_radius == rocket_radius / 2
|
|
243
|
+
calisto.aerodynamic_surfaces.remove(nose1)
|
|
244
|
+
nose2 = NoseCone(
|
|
245
|
+
length,
|
|
246
|
+
kind,
|
|
247
|
+
base_radius=base_radius / 2,
|
|
248
|
+
bluffness=bluffness,
|
|
249
|
+
rocket_radius=rocket_radius,
|
|
250
|
+
name="Nose Cone 2",
|
|
251
|
+
)
|
|
252
|
+
calisto.add_surfaces(nose2, position)
|
|
253
|
+
assert nose2.radius_ratio == pytest.approx(0.5, 1e-8)
|
|
254
|
+
assert calisto.static_margin(0) == pytest.approx(-8.9053, 0.01)
|
|
255
|
+
|
|
256
|
+
# Case 3: base_radius == None
|
|
257
|
+
calisto.aerodynamic_surfaces.remove(nose2)
|
|
258
|
+
nose3 = NoseCone(
|
|
259
|
+
length,
|
|
260
|
+
kind,
|
|
261
|
+
base_radius=None,
|
|
262
|
+
bluffness=bluffness,
|
|
263
|
+
rocket_radius=rocket_radius * 2,
|
|
264
|
+
name="Nose Cone 3",
|
|
265
|
+
)
|
|
266
|
+
calisto.add_surfaces(nose3, position)
|
|
267
|
+
assert nose3.radius_ratio == pytest.approx(1, 1e-8)
|
|
268
|
+
assert calisto.static_margin(0) == pytest.approx(-8.9053, 0.01)
|
|
269
|
+
|
|
270
|
+
# Case 4: rocket_radius == None
|
|
271
|
+
calisto.aerodynamic_surfaces.remove(nose3)
|
|
272
|
+
nose4 = NoseCone(
|
|
273
|
+
length,
|
|
274
|
+
kind,
|
|
275
|
+
base_radius=base_radius,
|
|
276
|
+
bluffness=bluffness,
|
|
277
|
+
rocket_radius=None,
|
|
278
|
+
name="Nose Cone 4",
|
|
279
|
+
)
|
|
280
|
+
calisto.add_surfaces(nose4, position)
|
|
281
|
+
assert nose4.radius_ratio == pytest.approx(1, 1e-8)
|
|
282
|
+
assert calisto.static_margin(0) == pytest.approx(-8.9053, 0.01)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|