Skip to content

Commit

Permalink
adapts API to recent rocketpy changes
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielBarberini committed Oct 14, 2024
1 parent 5c064ac commit 2dcd980
Show file tree
Hide file tree
Showing 12 changed files with 377 additions and 344 deletions.
17 changes: 14 additions & 3 deletions lib/models/aerosurfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


class RailButtons(BaseModel):
name: str
name: str = "RailButtons"
upper_button_position: float
lower_button_position: float
angular_position: float
Expand Down Expand Up @@ -34,13 +34,24 @@ class Fins(BaseModel):
name: str
n: int
root_chord: float
tip_chord: Optional[float] = None
span: float
position: float

# Optional parameters
tip_chord: Optional[float] = None
cant_angle: Optional[float] = None
radius: Optional[float] = None
rocket_radius: Optional[float] = None
airfoil: Optional[Tuple[List[Tuple[float, float]], AngleUnit]] = None

def get_additional_parameters(self):
return {
key: value
for key, value in self.dict().items()
if value is not None
and key
not in ["fins_kind", "name", "n", "root_chord", "span", "position"]
}


# TODO: implement airbrakes
class AirBrakes(BaseModel):
Expand Down
6 changes: 4 additions & 2 deletions lib/models/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ class AtmosphericModelTypes(str, Enum):
class Env(BaseModel):
latitude: float
longitude: float
elevation: Optional[int] = 0
elevation: Optional[int] = 1

# Optional parameters
atmospheric_model_type: Optional[AtmosphericModelTypes] = None
atmospheric_model_type: AtmosphericModelTypes = (
AtmosphericModelTypes.STANDARD_ATMOSPHERE
)
atmospheric_model_file: Optional[str] = None
date: Optional[datetime.datetime] = (
datetime.datetime.today() + datetime.timedelta(days=1)
Expand Down
27 changes: 23 additions & 4 deletions lib/models/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,35 @@ class Flight(BaseModel):
name: str = "Flight"
environment: Env
rocket: Rocket
rail_length: float
rail_length: float = 1
time_overshoot: bool = True
terminate_on_apogee: bool = True
equations_of_motion: EquationsOfMotion = EquationsOfMotion.STANDARD

# Optional parameters
inclination: Optional[int] = None
heading: Optional[int] = None
# TODO: implement initial_solution
terminate_on_apogee: Optional[bool] = None
max_time: Optional[int] = None
max_time_step: Optional[float] = None
min_time_step: Optional[int] = None
rtol: Optional[float] = None
atol: Optional[float] = None
time_overshoot: Optional[bool] = None
verbose: Optional[bool] = None
equations_of_motion: Optional[EquationsOfMotion] = None

def get_additional_parameters(self):
return {
key: value
for key, value in self.dict().items()
if value is not None
and key
not in [
"name",
"environment",
"rocket",
"rail_length",
"time_overshoot",
"terminate_on_apogee",
"equations_of_motion",
]
}
10 changes: 6 additions & 4 deletions lib/models/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class Motor(BaseModel):
burn_time: float
nozzle_radius: float
dry_mass: float
dry_inertia: Tuple[float, float, float]
dry_inertia: Tuple[float, float, float] = (0, 0, 0)
center_of_dry_mass_position: float

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

# Optional parameters
interpolation_method: Optional[InterpolationMethods] = None
coordinate_system_orientation: Optional[CoordinateSystemOrientation] = None
reshape_thrust_curve: Optional[Union[bool, tuple]] = None
interpolation_method: InterpolationMethods = InterpolationMethods.LINEAR
coordinate_system_orientation: CoordinateSystemOrientation = (
CoordinateSystemOrientation.NOZZLE_TO_COMBUSTION_CHAMBER
)
reshape_thrust_curve: Union[bool, tuple] = False

# Computed parameters
_motor_kind: MotorKinds = PrivateAttr(default=MotorKinds.SOLID)
Expand Down
10 changes: 6 additions & 4 deletions lib/models/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ class Rocket(BaseModel):
inertia: Union[
Tuple[float, float, float],
Tuple[float, float, float, float, float, float],
]
power_off_drag: List[Tuple[float, float]]
power_on_drag: List[Tuple[float, float]]
] = (0, 0, 0)
power_off_drag: List[Tuple[float, float]] = [(0, 0)]
power_on_drag: List[Tuple[float, float]] = [(0, 0)]
coordinate_system_orientation: CoordinateSystemOrientation = (
CoordinateSystemOrientation.TAIL_TO_NOSE
)

# Optional parameters
parachutes: Optional[List[Parachute]] = None
rail_buttons: Optional[RailButtons] = None
nose: Optional[NoseCone] = None
fins: Optional[List[Fins]] = None
tail: Optional[Tail] = None
coordinate_system_orientation: Optional[CoordinateSystemOrientation] = None
10 changes: 1 addition & 9 deletions lib/services/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,12 @@ def from_flight_model(cls, flight: Flight) -> Self:
rocketpy_rocket = RocketService.from_rocket_model(flight.rocket).rocket
rocketpy_flight = RocketPyFlight(
rocket=rocketpy_rocket,
inclination=flight.inclination,
heading=flight.heading,
environment=rocketpy_env,
rail_length=flight.rail_length,
# initial_solution=flight.initial_solution,
terminate_on_apogee=flight.terminate_on_apogee,
max_time=flight.max_time,
max_time_step=flight.max_time_step,
min_time_step=flight.min_time_step,
rtol=flight.rtol,
atol=flight.atol,
time_overshoot=flight.time_overshoot,
verbose=flight.verbose,
equations_of_motion=flight.equations_of_motion.value.lower(),
**flight.get_additional_parameters(),
)
return cls(flight=rocketpy_flight)

Expand Down
6 changes: 1 addition & 5 deletions lib/services/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ def from_motor_model(cls, motor: Motor) -> Self:
"dry_mass": motor.dry_mass,
"dry_inertia": motor.dry_inertia,
"center_of_dry_mass_position": motor.center_of_dry_mass_position,
"coordinate_system_orientation": (
motor.coordinate_system_orientation.value.lower()
if motor.coordinate_system_orientation
else None
),
"coordinate_system_orientation": motor.coordinate_system_orientation.value.lower(),
"interpolation_method": motor.interpolation_method.value.lower(),
"reshape_thrust_curve": False or motor.reshape_thrust_curve,
}
Expand Down
76 changes: 39 additions & 37 deletions lib/services/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,46 +47,53 @@ def from_rocket_model(cls, rocket: Rocket) -> Self:
)

# RailButtons
rocketpy_rocket.set_rail_buttons(
upper_button_position=rocket.rail_buttons.upper_button_position,
lower_button_position=rocket.rail_buttons.lower_button_position,
angular_position=rocket.rail_buttons.angular_position,
)
rocketpy_rocket.add_motor(
MotorService.from_motor_model(rocket.motor).motor,
rocket.motor_position,
)
if rocket.rail_buttons:
rocketpy_rocket.set_rail_buttons(
upper_button_position=rocket.rail_buttons.upper_button_position,
lower_button_position=rocket.rail_buttons.lower_button_position,
angular_position=rocket.rail_buttons.angular_position,
)
rocketpy_rocket.add_motor(
MotorService.from_motor_model(rocket.motor).motor,
rocket.motor_position,
)

# NoseCone
nose = cls.get_rocketpy_nose(rocket.nose)
rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position)
rocketpy_rocket.evaluate_static_margin()
if rocket.nose:
nose = cls.get_rocketpy_nose(rocket.nose)
rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position)
rocketpy_rocket.evaluate_static_margin()

# FinSet
rocketpy_finset_list = cls.get_rocketpy_finset_list_from_fins_list(
rocket.fins
)
for finset in rocketpy_finset_list:
rocketpy_rocket.aerodynamic_surfaces.add(finset, finset.position)
rocketpy_rocket.evaluate_static_margin()
if rocket.fins:
rocketpy_finset_list = cls.get_rocketpy_finset_list_from_fins_list(
rocket.fins
)
for finset in rocketpy_finset_list:
rocketpy_rocket.aerodynamic_surfaces.add(
finset, finset.position
)
rocketpy_rocket.evaluate_static_margin()

# Tail
tail = cls.get_rocketpy_tail(rocket.tail)
rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position)
rocketpy_rocket.evaluate_static_margin()
if rocket.tail:
tail = cls.get_rocketpy_tail(rocket.tail)
rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position)
rocketpy_rocket.evaluate_static_margin()

# Air Brakes

# Parachutes
for parachute in rocket.parachutes:
if cls.check_parachute_trigger(parachute.trigger):
rocketpy_parachute = cls.get_rocketpy_parachute(parachute)
rocketpy_rocket.parachutes.append(rocketpy_parachute)
else:
logger.warning(
"Parachute trigger not valid. Skipping parachute."
)
continue
if rocket.parachutes:
for parachute in rocket.parachutes:
if cls.check_parachute_trigger(parachute.trigger):
rocketpy_parachute = cls.get_rocketpy_parachute(parachute)
rocketpy_rocket.parachutes.append(rocketpy_parachute)
else:
logger.warning(
"Parachute trigger not valid. Skipping parachute."
)
continue

return cls(rocket=rocketpy_rocket)

Expand Down Expand Up @@ -160,21 +167,16 @@ def get_rocketpy_finset(fins: Fins, kind: str) -> RocketPyFins:
n=fins.n,
name=fins.name,
root_chord=fins.root_chord,
tip_chord=fins.tip_chord,
span=fins.span,
cant_angle=fins.cant_angle,
rocket_radius=fins.radius,
airfoil=fins.airfoil,
**fins.get_additional_parameters(),
)
case "ELLIPTICAL":
rocketpy_finset = RocketPyEllipticalFins(
n=fins.n,
name=fins.name,
root_chord=fins.root_chord,
span=fins.span,
cant_angle=fins.cant_angle,
rocket_radius=fins.radius,
airfoil=fins.airfoil,
**fins.get_additional_parameters(),
)
case _:
raise ValueError(f"Invalid fins kind: {kind}")
Expand Down
85 changes: 44 additions & 41 deletions lib/views/environment.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
from typing import Optional, Any
from datetime import datetime
from datetime import datetime, timedelta
from pydantic import BaseModel
from lib.models.environment import AtmosphericModelTypes
from lib.utils import to_python_primitive


class EnvSummary(BaseModel):
latitude: Optional[float]
longitude: Optional[float]
elevation: Optional[float]
atmospheric_model_type: Optional[str]
air_gas_constant: Optional[float]
standard_g: Optional[float]
earth_radius: Optional[float]
datum: Optional[str]
timezone: Optional[str]
initial_utm_zone: Optional[int]
initial_utm_letter: Optional[str]
initial_north: Optional[float]
initial_east: Optional[float]
initial_hemisphere: Optional[str]
initial_ew: Optional[str]
max_expected_height: Optional[int]
date: Optional[datetime]
local_date: Optional[datetime]
datetime_date: Optional[datetime]
ellipsoid: Optional[Any]
barometric_height: Optional[Any]
barometric_height_ISA: Optional[Any]
pressure: Optional[Any]
pressure_ISA: Optional[Any]
temperature: Optional[Any]
temperature_ISA: Optional[Any]
density: Optional[Any]
speed_of_sound: Optional[Any]
dynamic_viscosity: Optional[Any]
gravity: Optional[Any]
somigliana_gravity: Optional[Any]
wind_speed: Optional[Any]
wind_direction: Optional[Any]
wind_heading: Optional[Any]
wind_velocity_x: Optional[Any]
wind_velocity_y: Optional[Any]
calculate_earth_radius: Optional[Any]
decimal_degrees_to_arc_seconds: Optional[Any]
geodesic_to_utm: Optional[Any]
utm_to_geodesic: Optional[Any]
latitude: Optional[float] = None
longitude: Optional[float] = None
elevation: Optional[float] = 1
atmospheric_model_type: Optional[str] = (
AtmosphericModelTypes.STANDARD_ATMOSPHERE.value
)
air_gas_constant: Optional[float] = None
standard_g: Optional[float] = None
earth_radius: Optional[float] = None
datum: Optional[str] = None
timezone: Optional[str] = None
initial_utm_zone: Optional[int] = None
initial_utm_letter: Optional[str] = None
initial_north: Optional[float] = None
initial_east: Optional[float] = None
initial_hemisphere: Optional[str] = None
initial_ew: Optional[str] = None
max_expected_height: Optional[int] = None
date: Optional[datetime] = datetime.today() + timedelta(days=1)
local_date: Optional[datetime] = datetime.today() + timedelta(days=1)
datetime_date: Optional[datetime] = datetime.today() + timedelta(days=1)
ellipsoid: Optional[Any] = None
barometric_height: Optional[Any] = None
barometric_height_ISA: Optional[Any] = None
pressure: Optional[Any] = None
pressure_ISA: Optional[Any] = None
temperature: Optional[Any] = None
temperature_ISA: Optional[Any] = None
density: Optional[Any] = None
speed_of_sound: Optional[Any] = None
dynamic_viscosity: Optional[Any] = None
gravity: Optional[Any] = None
somigliana_gravity: Optional[Any] = None
wind_speed: Optional[Any] = None
wind_direction: Optional[Any] = None
wind_heading: Optional[Any] = None
wind_velocity_x: Optional[Any] = None
wind_velocity_y: Optional[Any] = None
calculate_earth_radius: Optional[Any] = None
decimal_degrees_to_arc_seconds: Optional[Any] = None
geodesic_to_utm: Optional[Any] = None
utm_to_geodesic: Optional[Any] = None

class Config:
json_encoders = {Any: to_python_primitive}
Expand Down
Loading

0 comments on commit 2dcd980

Please sign in to comment.