Skip to content

Commit

Permalink
updates pydantic and fix optional parameters for the API
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielBarberini committed Oct 14, 2024
1 parent 0820715 commit 5927b63
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 161 deletions.
8 changes: 4 additions & 4 deletions lib/models/aerosurfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ class Fins(BaseModel):
name: str
n: int
root_chord: float
tip_chord: Optional[float]
tip_chord: Optional[float] = None
span: float
position: float
cant_angle: float
radius: float
airfoil: Tuple[List[Tuple[float, float]], AngleUnit]
cant_angle: Optional[float] = None
radius: Optional[float] = None
airfoil: Optional[Tuple[List[Tuple[float, float]], AngleUnit]] = None


# TODO: implement airbrakes
Expand Down
23 changes: 17 additions & 6 deletions lib/models/environment.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import datetime
from enum import Enum
from typing import Optional
from pydantic import BaseModel


class AtmosphericModelTypes(str, Enum):
STANDARD_ATMOSPHERE: str = "STANDARD_ATMOSPHERE"
CUSTOM_ATMOSPHERE: str = "CUSTOM_ATMOSPHERE"
WYOMING_SOUNDING: str = "WYOMING_SOUNDING"
NOAARUCSOUNDING: str = "NOAARUCSOUNDING"
FORECAST: str = "FORECAST"
REANALYSIS: str = "REANALYSIS"
ENSEMBLE: str = "ENSEMBLE"


class Env(BaseModel):
latitude: float = 0
longitude: float = 0
elevation: Optional[int] = 1400
latitude: float
longitude: float
elevation: Optional[int] = None

# Opional parameters
atmospheric_model_type: Optional[str] = "standard_atmosphere"
atmospheric_model_file: Optional[str] = "GFS"
# Optional parameters
atmospheric_model_type: Optional[AtmosphericModelTypes] = None
atmospheric_model_file: Optional[str] = None
date: Optional[datetime.datetime] = (
datetime.datetime.today() + datetime.timedelta(days=1)
)
34 changes: 16 additions & 18 deletions lib/models/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,24 @@


class EquationsOfMotion(str, Enum):
STANDARD = "STANDARD"
SOLID_PROPULSION = "SOLID_PROPULSION"
STANDARD: str = "STANDARD"
SOLID_PROPULSION: str = "SOLID_PROPULSION"


class Flight(BaseModel):
name: str = "Flight"
environment: Env = Env()
rocket: Rocket = Rocket()
rail_length: float = 5.2
inclination: Optional[int] = 80.0
heading: Optional[int] = 90.0
environment: Env
rocket: Rocket
rail_length: float
inclination: Optional[int] = None
heading: Optional[int] = None
# TODO: implement initial_solution
terminate_on_apogee: Optional[bool] = False
max_time: Optional[int] = 600
max_time_step: Optional[float] = 9999
min_time_step: Optional[int] = 0
rtol: Optional[float] = 1e-3
atol: Optional[float] = 1e-3
time_overshoot: Optional[bool] = True
verbose: Optional[bool] = False
equations_of_motion: Optional[EquationsOfMotion] = (
EquationsOfMotion.STANDARD
)
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
93 changes: 47 additions & 46 deletions lib/models/motor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enum import Enum
from typing import Optional, Tuple, List
from typing import Optional, Tuple, List, Union
from pydantic import BaseModel, PrivateAttr


Expand Down Expand Up @@ -27,80 +27,81 @@ class TankFluids(BaseModel):
density: float


class InterpolationMethods(str, Enum):
LINEAR: str = "LINEAR"
SPLINE: str = "SPLINE"
AKIMA: str = "AKIMA"


class MotorTank(BaseModel):
# Required parameters
geometry: List[Tuple[Tuple[float, float], float]] = [
((0.0, 5.0), 1.0),
((5.0, 10.0), 2.0),
]
gas: TankFluids = TankFluids(name="GAS", density=100)
liquid: TankFluids = TankFluids(name="LIQUID", density=1000)
flux_time: Tuple[float, float] = (0.0, 3.9)
position: float = 1.0
discretize: int = 100
geometry: List[Tuple[Tuple[float, float], float]]
gas: TankFluids
liquid: TankFluids
flux_time: Tuple[float, float]
position: float
discretize: int

# Level based tank parameters
liquid_height: Optional[float] = 0.5
liquid_height: Optional[float]

# Mass based tank parameters
liquid_mass: Optional[float] = 5.0
gas_mass: Optional[float] = 0.1
liquid_mass: Optional[float]
gas_mass: Optional[float]

# Mass flow based tank parameters
gas_mass_flow_rate_in: Optional[float] = 0.0
gas_mass_flow_rate_out: Optional[float] = 0.1
liquid_mass_flow_rate_in: Optional[float] = 0.0
liquid_mass_flow_rate_out: Optional[float] = 1
initial_liquid_mass: Optional[float] = 5.0
initial_gas_mass: Optional[float] = 0.4
gas_mass_flow_rate_in: Optional[float]
gas_mass_flow_rate_out: Optional[float]
liquid_mass_flow_rate_in: Optional[float]
liquid_mass_flow_rate_out: Optional[float]
initial_liquid_mass: Optional[float]
initial_gas_mass: Optional[float]

# Ullage based tank parameters
ullage: Optional[float] = 0.1
ullage: Optional[float]

# Optional parameters
name: Optional[str] = "Tank"
name: Optional[str]

# Computed parameters
tank_kind: TankKinds = TankKinds.MASS_FLOW


class Motor(BaseModel):
# Required parameters
thrust_source: List[List[float]] = [[0.0, 0.0], [1.0, 1.0]]
burn_time: float = 3.9
nozzle_radius: float = 0.033
dry_mass: float = 1.815
dry_inertia: Tuple[float, float, float] = (0.125, 0.125, 0.002)
center_of_dry_mass_position: float = 0.317
thrust_source: List[List[float]]
burn_time: float
nozzle_radius: float
dry_mass: float
dry_inertia: Tuple[float, float, float]
center_of_dry_mass_position: float

# Generic motor parameters
chamber_radius: Optional[float] = 0.033
chamber_height: Optional[float] = 0.1
chamber_position: Optional[float] = 0.0
propellant_initial_mass: Optional[float] = 1.0
nozzle_position: Optional[float] = 0.0
chamber_radius: Optional[float] = None
chamber_height: Optional[float] = None
chamber_position: Optional[float] = None
propellant_initial_mass: Optional[float] = None
nozzle_position: Optional[float] = None

# Liquid motor parameters
tanks: Optional[List[MotorTank]] = [MotorTank()]
tanks: Optional[List[MotorTank]] = None

# Solid motor parameters
grain_number: Optional[int] = 5
grain_density: Optional[float] = 1815
grain_outer_radius: Optional[float] = 0.033
grain_initial_inner_radius: Optional[float] = 0.015
grain_initial_height: Optional[float] = 0.12
grains_center_of_mass_position: Optional[float] = -0.85704
grain_separation: Optional[float] = 0.005
grain_number: Optional[int] = None
grain_density: Optional[float] = None
grain_outer_radius: Optional[float] = None
grain_initial_inner_radius: Optional[float] = None
grain_initial_height: Optional[float] = None
grains_center_of_mass_position: Optional[float] = None
grain_separation: Optional[float] = None

# Hybrid motor parameters
throat_radius: Optional[float] = 0.011
throat_radius: Optional[float] = None

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

# Computed parameters
_motor_kind: MotorKinds = PrivateAttr(default=MotorKinds.SOLID)
Expand Down
83 changes: 20 additions & 63 deletions lib/models/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
NoseCone,
Tail,
RailButtons,
FinsKinds,
)


Expand All @@ -17,71 +16,29 @@ class CoordinateSystemOrientation(str, Enum):


class Parachute(BaseModel):
name: str = "Main"
cd_s: float = 10
sampling_rate: int = 105
lag: float = 1.5
trigger: Union[str, float] = "apogee"
noise: Tuple[float, float, float] = (0, 8.3, 0.5)
name: str
cd_s: float
sampling_rate: int
lag: float
trigger: Union[str, float]
noise: Tuple[float, float, float]


class Rocket(BaseModel):
# Required parameters
motor: Motor = Motor()
radius: float = 0.0632
mass: float = 16.235
motor_position: float = -1.255
center_of_mass_without_motor: int = 0
inertia: Tuple[float, float, float] = (6.321, 6.321, 0.0346)
power_off_drag: List[Tuple[float, float]] = [
(0.0, 0.0),
(0.1, 0.1),
(0.2, 0.2),
]
power_on_drag: List[Tuple[float, float]] = [
(0.0, 0.0),
(0.1, 0.1),
(0.2, 0.2),
]
motor: Motor
radius: float
mass: float
motor_position: float
center_of_mass_without_motor: int
inertia: Tuple[float, float, float]
power_off_drag: List[Tuple[float, float]]
power_on_drag: List[Tuple[float, float]]

# Optional parameters
parachutes: Optional[List[Parachute]] = [Parachute()]
rail_buttons: Optional[RailButtons] = RailButtons(
name="RailButtons",
upper_button_position=-0.5,
lower_button_position=0.2,
angular_position=45,
)
nose: Optional[NoseCone] = NoseCone(
name="Nose",
length=0.55829,
kind="vonKarman",
position=1.278,
base_radius=0.0635,
rocket_radius=0.0635,
)
fins: Optional[List[Fins]] = [
Fins(
fins_kind=FinsKinds.TRAPEZOIDAL,
name="Fins",
n=4,
root_chord=0.12,
tip_chord=0.04,
span=0.1,
position=-1.04956,
cant_angle=0,
radius=0.0635,
airfoil=([(0.0, 0.0), (0.1, 0.1), (0.2, 0.2)], "RADIANS"),
)
]
tail: Optional[Tail] = Tail(
name="Tail",
top_radius=0.0635,
bottom_radius=0.0435,
length=0.06,
position=-1.194656,
radius=0.0635,
)
coordinate_system_orientation: Optional[CoordinateSystemOrientation] = (
CoordinateSystemOrientation.TAIL_TO_NOSE
)
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
3 changes: 2 additions & 1 deletion lib/services/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def from_env_model(cls, env: Env) -> Self:
date=env.date,
)
rocketpy_env.set_atmospheric_model(
type=env.atmospheric_model_type, file=env.atmospheric_model_file
type=env.atmospheric_model_type.value.lower(),
file=env.atmospheric_model_file,
)
return cls(environment=rocketpy_env)

Expand Down
4 changes: 2 additions & 2 deletions lib/services/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def from_motor_model(cls, motor: Motor) -> Self:
if motor.coordinate_system_orientation
else None
),
"interpolation_method": motor.interpolation_method,
"reshape_thrust_curve": motor.reshape_thrust_curve,
"interpolation_method": motor.interpolation_method.value.lower(),
"reshape_thrust_curve": False or motor.reshape_thrust_curve,
}

match motor.motor_kind:
Expand Down
15 changes: 15 additions & 0 deletions lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import io
import typing

import numpy as np

from starlette.datastructures import Headers, MutableHeaders
from starlette.types import ASGIApp, Message, Receive, Scope, Send

Expand Down Expand Up @@ -126,3 +128,16 @@ async def send_with_gzip(self, message: Message) -> None:

async def unattached_send(message: Message) -> typing.NoReturn:
raise RuntimeError("send awaitable not set") # pragma: no cover


def to_python_primitive(v):
if hasattr(v, "source"):
if isinstance(v.source, np.ndarray):
return v.source.tolist()

if isinstance(v.source, (np.generic,)):
return v.source.item()

return str(v.source)

return str(v)
Loading

0 comments on commit 5927b63

Please sign in to comment.