Skip to content

Commit dbb6f9d

Browse files
adapts API to recent rocketpy changes
1 parent eb3d79a commit dbb6f9d

File tree

12 files changed

+377
-344
lines changed

12 files changed

+377
-344
lines changed

lib/models/aerosurfaces.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55

66
class RailButtons(BaseModel):
7-
name: str
7+
name: str = "RailButtons"
88
upper_button_position: float
99
lower_button_position: float
1010
angular_position: float
@@ -34,13 +34,24 @@ class Fins(BaseModel):
3434
name: str
3535
n: int
3636
root_chord: float
37-
tip_chord: Optional[float] = None
3837
span: float
3938
position: float
39+
40+
# Optional parameters
41+
tip_chord: Optional[float] = None
4042
cant_angle: Optional[float] = None
41-
radius: Optional[float] = None
43+
rocket_radius: Optional[float] = None
4244
airfoil: Optional[Tuple[List[Tuple[float, float]], AngleUnit]] = None
4345

46+
def get_additional_parameters(self):
47+
return {
48+
key: value
49+
for key, value in self.dict().items()
50+
if value is not None
51+
and key
52+
not in ["fins_kind", "name", "n", "root_chord", "span", "position"]
53+
}
54+
4455

4556
# TODO: implement airbrakes
4657
class AirBrakes(BaseModel):

lib/models/environment.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ class AtmosphericModelTypes(str, Enum):
1616
class Env(BaseModel):
1717
latitude: float
1818
longitude: float
19-
elevation: Optional[int] = 0
19+
elevation: Optional[int] = 1
2020

2121
# Optional parameters
22-
atmospheric_model_type: Optional[AtmosphericModelTypes] = None
22+
atmospheric_model_type: AtmosphericModelTypes = (
23+
AtmosphericModelTypes.STANDARD_ATMOSPHERE
24+
)
2325
atmospheric_model_file: Optional[str] = None
2426
date: Optional[datetime.datetime] = (
2527
datetime.datetime.today() + datetime.timedelta(days=1)

lib/models/flight.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,35 @@ class Flight(BaseModel):
1414
name: str = "Flight"
1515
environment: Env
1616
rocket: Rocket
17-
rail_length: float
17+
rail_length: float = 1
18+
time_overshoot: bool = True
19+
terminate_on_apogee: bool = True
20+
equations_of_motion: EquationsOfMotion = EquationsOfMotion.STANDARD
21+
22+
# Optional parameters
1823
inclination: Optional[int] = None
1924
heading: Optional[int] = None
2025
# TODO: implement initial_solution
21-
terminate_on_apogee: Optional[bool] = None
2226
max_time: Optional[int] = None
2327
max_time_step: Optional[float] = None
2428
min_time_step: Optional[int] = None
2529
rtol: Optional[float] = None
2630
atol: Optional[float] = None
27-
time_overshoot: Optional[bool] = None
2831
verbose: Optional[bool] = None
29-
equations_of_motion: Optional[EquationsOfMotion] = None
32+
33+
def get_additional_parameters(self):
34+
return {
35+
key: value
36+
for key, value in self.dict().items()
37+
if value is not None
38+
and key
39+
not in [
40+
"name",
41+
"environment",
42+
"rocket",
43+
"rail_length",
44+
"time_overshoot",
45+
"terminate_on_apogee",
46+
"equations_of_motion",
47+
]
48+
}

lib/models/motor.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class Motor(BaseModel):
7676
burn_time: float
7777
nozzle_radius: float
7878
dry_mass: float
79-
dry_inertia: Tuple[float, float, float]
79+
dry_inertia: Tuple[float, float, float] = (0, 0, 0)
8080
center_of_dry_mass_position: float
8181

8282
# Generic motor parameters
@@ -102,9 +102,11 @@ class Motor(BaseModel):
102102
throat_radius: Optional[float] = None
103103

104104
# Optional parameters
105-
interpolation_method: Optional[InterpolationMethods] = None
106-
coordinate_system_orientation: Optional[CoordinateSystemOrientation] = None
107-
reshape_thrust_curve: Optional[Union[bool, tuple]] = None
105+
interpolation_method: InterpolationMethods = InterpolationMethods.LINEAR
106+
coordinate_system_orientation: CoordinateSystemOrientation = (
107+
CoordinateSystemOrientation.NOZZLE_TO_COMBUSTION_CHAMBER
108+
)
109+
reshape_thrust_curve: Union[bool, tuple] = False
108110

109111
# Computed parameters
110112
_motor_kind: MotorKinds = PrivateAttr(default=MotorKinds.SOLID)

lib/models/rocket.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,16 @@ class Rocket(BaseModel):
3434
inertia: Union[
3535
Tuple[float, float, float],
3636
Tuple[float, float, float, float, float, float],
37-
]
38-
power_off_drag: List[Tuple[float, float]]
39-
power_on_drag: List[Tuple[float, float]]
37+
] = (0, 0, 0)
38+
power_off_drag: List[Tuple[float, float]] = [(0, 0)]
39+
power_on_drag: List[Tuple[float, float]] = [(0, 0)]
40+
coordinate_system_orientation: CoordinateSystemOrientation = (
41+
CoordinateSystemOrientation.TAIL_TO_NOSE
42+
)
4043

4144
# Optional parameters
4245
parachutes: Optional[List[Parachute]] = None
4346
rail_buttons: Optional[RailButtons] = None
4447
nose: Optional[NoseCone] = None
4548
fins: Optional[List[Fins]] = None
4649
tail: Optional[Tail] = None
47-
coordinate_system_orientation: Optional[CoordinateSystemOrientation] = None

lib/services/flight.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,12 @@ def from_flight_model(cls, flight: Flight) -> Self:
3131
rocketpy_rocket = RocketService.from_rocket_model(flight.rocket).rocket
3232
rocketpy_flight = RocketPyFlight(
3333
rocket=rocketpy_rocket,
34-
inclination=flight.inclination,
35-
heading=flight.heading,
3634
environment=rocketpy_env,
3735
rail_length=flight.rail_length,
38-
# initial_solution=flight.initial_solution,
3936
terminate_on_apogee=flight.terminate_on_apogee,
40-
max_time=flight.max_time,
41-
max_time_step=flight.max_time_step,
42-
min_time_step=flight.min_time_step,
43-
rtol=flight.rtol,
44-
atol=flight.atol,
4537
time_overshoot=flight.time_overshoot,
46-
verbose=flight.verbose,
4738
equations_of_motion=flight.equations_of_motion.value.lower(),
39+
**flight.get_additional_parameters(),
4840
)
4941
return cls(flight=rocketpy_flight)
5042

lib/services/motor.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@ def from_motor_model(cls, motor: Motor) -> Self:
4141
"dry_mass": motor.dry_mass,
4242
"dry_inertia": motor.dry_inertia,
4343
"center_of_dry_mass_position": motor.center_of_dry_mass_position,
44-
"coordinate_system_orientation": (
45-
motor.coordinate_system_orientation.value.lower()
46-
if motor.coordinate_system_orientation
47-
else None
48-
),
44+
"coordinate_system_orientation": motor.coordinate_system_orientation.value.lower(),
4945
"interpolation_method": motor.interpolation_method.value.lower(),
5046
"reshape_thrust_curve": False or motor.reshape_thrust_curve,
5147
}

lib/services/rocket.py

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -47,46 +47,53 @@ def from_rocket_model(cls, rocket: Rocket) -> Self:
4747
)
4848

4949
# RailButtons
50-
rocketpy_rocket.set_rail_buttons(
51-
upper_button_position=rocket.rail_buttons.upper_button_position,
52-
lower_button_position=rocket.rail_buttons.lower_button_position,
53-
angular_position=rocket.rail_buttons.angular_position,
54-
)
55-
rocketpy_rocket.add_motor(
56-
MotorService.from_motor_model(rocket.motor).motor,
57-
rocket.motor_position,
58-
)
50+
if rocket.rail_buttons:
51+
rocketpy_rocket.set_rail_buttons(
52+
upper_button_position=rocket.rail_buttons.upper_button_position,
53+
lower_button_position=rocket.rail_buttons.lower_button_position,
54+
angular_position=rocket.rail_buttons.angular_position,
55+
)
56+
rocketpy_rocket.add_motor(
57+
MotorService.from_motor_model(rocket.motor).motor,
58+
rocket.motor_position,
59+
)
5960

6061
# NoseCone
61-
nose = cls.get_rocketpy_nose(rocket.nose)
62-
rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position)
63-
rocketpy_rocket.evaluate_static_margin()
62+
if rocket.nose:
63+
nose = cls.get_rocketpy_nose(rocket.nose)
64+
rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position)
65+
rocketpy_rocket.evaluate_static_margin()
6466

6567
# FinSet
66-
rocketpy_finset_list = cls.get_rocketpy_finset_list_from_fins_list(
67-
rocket.fins
68-
)
69-
for finset in rocketpy_finset_list:
70-
rocketpy_rocket.aerodynamic_surfaces.add(finset, finset.position)
71-
rocketpy_rocket.evaluate_static_margin()
68+
if rocket.fins:
69+
rocketpy_finset_list = cls.get_rocketpy_finset_list_from_fins_list(
70+
rocket.fins
71+
)
72+
for finset in rocketpy_finset_list:
73+
rocketpy_rocket.aerodynamic_surfaces.add(
74+
finset, finset.position
75+
)
76+
rocketpy_rocket.evaluate_static_margin()
7277

7378
# Tail
74-
tail = cls.get_rocketpy_tail(rocket.tail)
75-
rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position)
76-
rocketpy_rocket.evaluate_static_margin()
79+
if rocket.tail:
80+
tail = cls.get_rocketpy_tail(rocket.tail)
81+
rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position)
82+
rocketpy_rocket.evaluate_static_margin()
7783

7884
# Air Brakes
7985

8086
# Parachutes
81-
for parachute in rocket.parachutes:
82-
if cls.check_parachute_trigger(parachute.trigger):
83-
rocketpy_parachute = cls.get_rocketpy_parachute(parachute)
84-
rocketpy_rocket.parachutes.append(rocketpy_parachute)
85-
else:
86-
logger.warning(
87-
"Parachute trigger not valid. Skipping parachute."
88-
)
89-
continue
87+
if rocket.parachutes:
88+
for parachute in rocket.parachutes:
89+
if cls.check_parachute_trigger(parachute.trigger):
90+
rocketpy_parachute = cls.get_rocketpy_parachute(parachute)
91+
rocketpy_rocket.parachutes.append(rocketpy_parachute)
92+
else:
93+
logger.warning(
94+
"Parachute trigger not valid. Skipping parachute."
95+
)
96+
continue
9097

9198
return cls(rocket=rocketpy_rocket)
9299

@@ -160,21 +167,16 @@ def get_rocketpy_finset(fins: Fins, kind: str) -> RocketPyFins:
160167
n=fins.n,
161168
name=fins.name,
162169
root_chord=fins.root_chord,
163-
tip_chord=fins.tip_chord,
164170
span=fins.span,
165-
cant_angle=fins.cant_angle,
166-
rocket_radius=fins.radius,
167-
airfoil=fins.airfoil,
171+
**fins.get_additional_parameters(),
168172
)
169173
case "ELLIPTICAL":
170174
rocketpy_finset = RocketPyEllipticalFins(
171175
n=fins.n,
172176
name=fins.name,
173177
root_chord=fins.root_chord,
174178
span=fins.span,
175-
cant_angle=fins.cant_angle,
176-
rocket_radius=fins.radius,
177-
airfoil=fins.airfoil,
179+
**fins.get_additional_parameters(),
178180
)
179181
case _:
180182
raise ValueError(f"Invalid fins kind: {kind}")

lib/views/environment.py

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,53 @@
11
from typing import Optional, Any
2-
from datetime import datetime
2+
from datetime import datetime, timedelta
33
from pydantic import BaseModel
4+
from lib.models.environment import AtmosphericModelTypes
45
from lib.utils import to_python_primitive
56

67

78
class EnvSummary(BaseModel):
8-
latitude: Optional[float]
9-
longitude: Optional[float]
10-
elevation: Optional[float]
11-
atmospheric_model_type: Optional[str]
12-
air_gas_constant: Optional[float]
13-
standard_g: Optional[float]
14-
earth_radius: Optional[float]
15-
datum: Optional[str]
16-
timezone: Optional[str]
17-
initial_utm_zone: Optional[int]
18-
initial_utm_letter: Optional[str]
19-
initial_north: Optional[float]
20-
initial_east: Optional[float]
21-
initial_hemisphere: Optional[str]
22-
initial_ew: Optional[str]
23-
max_expected_height: Optional[int]
24-
date: Optional[datetime]
25-
local_date: Optional[datetime]
26-
datetime_date: Optional[datetime]
27-
ellipsoid: Optional[Any]
28-
barometric_height: Optional[Any]
29-
barometric_height_ISA: Optional[Any]
30-
pressure: Optional[Any]
31-
pressure_ISA: Optional[Any]
32-
temperature: Optional[Any]
33-
temperature_ISA: Optional[Any]
34-
density: Optional[Any]
35-
speed_of_sound: Optional[Any]
36-
dynamic_viscosity: Optional[Any]
37-
gravity: Optional[Any]
38-
somigliana_gravity: Optional[Any]
39-
wind_speed: Optional[Any]
40-
wind_direction: Optional[Any]
41-
wind_heading: Optional[Any]
42-
wind_velocity_x: Optional[Any]
43-
wind_velocity_y: Optional[Any]
44-
calculate_earth_radius: Optional[Any]
45-
decimal_degrees_to_arc_seconds: Optional[Any]
46-
geodesic_to_utm: Optional[Any]
47-
utm_to_geodesic: Optional[Any]
9+
latitude: Optional[float] = None
10+
longitude: Optional[float] = None
11+
elevation: Optional[float] = 1
12+
atmospheric_model_type: Optional[str] = (
13+
AtmosphericModelTypes.STANDARD_ATMOSPHERE.value
14+
)
15+
air_gas_constant: Optional[float] = None
16+
standard_g: Optional[float] = None
17+
earth_radius: Optional[float] = None
18+
datum: Optional[str] = None
19+
timezone: Optional[str] = None
20+
initial_utm_zone: Optional[int] = None
21+
initial_utm_letter: Optional[str] = None
22+
initial_north: Optional[float] = None
23+
initial_east: Optional[float] = None
24+
initial_hemisphere: Optional[str] = None
25+
initial_ew: Optional[str] = None
26+
max_expected_height: Optional[int] = None
27+
date: Optional[datetime] = datetime.today() + timedelta(days=1)
28+
local_date: Optional[datetime] = datetime.today() + timedelta(days=1)
29+
datetime_date: Optional[datetime] = datetime.today() + timedelta(days=1)
30+
ellipsoid: Optional[Any] = None
31+
barometric_height: Optional[Any] = None
32+
barometric_height_ISA: Optional[Any] = None
33+
pressure: Optional[Any] = None
34+
pressure_ISA: Optional[Any] = None
35+
temperature: Optional[Any] = None
36+
temperature_ISA: Optional[Any] = None
37+
density: Optional[Any] = None
38+
speed_of_sound: Optional[Any] = None
39+
dynamic_viscosity: Optional[Any] = None
40+
gravity: Optional[Any] = None
41+
somigliana_gravity: Optional[Any] = None
42+
wind_speed: Optional[Any] = None
43+
wind_direction: Optional[Any] = None
44+
wind_heading: Optional[Any] = None
45+
wind_velocity_x: Optional[Any] = None
46+
wind_velocity_y: Optional[Any] = None
47+
calculate_earth_radius: Optional[Any] = None
48+
decimal_degrees_to_arc_seconds: Optional[Any] = None
49+
geodesic_to_utm: Optional[Any] = None
50+
utm_to_geodesic: Optional[Any] = None
4851

4952
class Config:
5053
json_encoders = {Any: to_python_primitive}

0 commit comments

Comments
 (0)