Skip to content

Commit

Permalink
Merge pull request #543 from RocketPy-Team/enh/dispersion-model
Browse files Browse the repository at this point in the history
ENH: Dispersion Class Overhaul
  • Loading branch information
MateusStano authored Feb 8, 2024
2 parents a2bc40c + b012ca1 commit b16e329
Show file tree
Hide file tree
Showing 4 changed files with 497 additions and 487 deletions.
117 changes: 66 additions & 51 deletions docs/notebooks/dispersion_analysis/dispersion_class_usage.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions rocketpy/monte_carlo/dispersion_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self, object, **kwargs):
If the input arguments do not conform to the specified formats.
"""
self.object = object
self.last_rnd_dict = {}

for input_name, input_value in kwargs.items():
if input_name not in self.exception_list:
Expand Down
106 changes: 87 additions & 19 deletions rocketpy/monte_carlo/mc_rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,76 @@ def _randomize_position(self, position):
elif isinstance(position, list):
return choice(position) if position else position

def dict_generator(self):
"""Special generator for the rocket class that yields a dictionary with
the randomly generated input arguments. The dictionary is saved as an
attribute of the class. The dictionary is generated by looping through
all attributes of the class and generating a random value for each
attribute. The random values are generated according to the format of
each attribute. Tuples are generated using the distribution function
specified in the tuple. Lists are generated using the random.choice
function.
Parameters
----------
None
Yields
-------
dict
Dictionary with the randomly generated input arguments.
"""
generated_dict = next(super().dict_generator())
generated_dict["motors"] = []
generated_dict["aerodynamic_surfaces"] = []
generated_dict["rail_buttons"] = []
generated_dict["parachutes"] = []
self.last_rnd_dict = generated_dict
yield generated_dict

def _create_motor(self, component_monte_carlo_motor):
monte_carlo_motor = component_monte_carlo_motor.component
motor = monte_carlo_motor.create_object()
position_rnd = self._randomize_position(component_monte_carlo_motor.position)
self.last_rnd_dict["motors"].append(monte_carlo_motor.last_rnd_dict)
self.last_rnd_dict["motors"][-1]["position"] = position_rnd
return motor, position_rnd

def _create_surface(self, component_monte_carlo_surface):
monte_carlo_surface = component_monte_carlo_surface.component
surface = monte_carlo_surface.create_object()
position_rnd = self._randomize_position(component_monte_carlo_surface.position)
self.last_rnd_dict["aerodynamic_surfaces"].append(
monte_carlo_surface.last_rnd_dict
)
self.last_rnd_dict["aerodynamic_surfaces"][-1]["position"] = position_rnd
return surface, position_rnd

def _create_rail_buttons(self, component_monte_carlo_rail_buttons):
monte_carlo_rail_buttons = component_monte_carlo_rail_buttons.component
rail_buttons = monte_carlo_rail_buttons.create_object()
lower_button_position_rnd = self._randomize_position(
component_monte_carlo_rail_buttons.position
)
upper_button_position_rnd = (
rail_buttons.buttons_distance + lower_button_position_rnd
)
self.last_rnd_dict["rail_buttons"].append(
monte_carlo_rail_buttons.last_rnd_dict
)
self.last_rnd_dict["rail_buttons"][-1][
"lower_button_position"
] = lower_button_position_rnd
self.last_rnd_dict["rail_buttons"][-1][
"upper_button_position"
] = upper_button_position_rnd
return rail_buttons, lower_button_position_rnd, upper_button_position_rnd

def _create_parachute(self, monte_carlo_parachute):
parachute = monte_carlo_parachute.create_object()
self.last_rnd_dict["parachutes"].append(monte_carlo_parachute.last_rnd_dict)
return parachute

def create_object(self):
"""Creates and returns a Rocket object from the randomly generated input
arguments.
Expand Down Expand Up @@ -549,36 +619,34 @@ def create_object(self):
rocket.power_on_drag *= generated_dict["power_on_drag_factor"]

for component_motor in self.motors:
m = component_motor.component.create_object()
position_rnd = self._randomize_position(component_motor.position)
rocket.add_motor(m, position_rnd)
motor, position_rnd = self._create_motor(component_motor)
rocket.add_motor(motor, position_rnd)

for component_surface in self.aerodynamic_surfaces:
s = component_surface.component.create_object()
position_rnd = self._randomize_position(component_surface.position)
rocket.add_surfaces(s, position_rnd)
surface, position_rnd = self._create_surface(component_surface)
rocket.add_surfaces(surface, position_rnd)

for component_rail_buttons in self.rail_buttons:
r = component_rail_buttons.component.create_object()
lower_button_position_rnd = self._randomize_position(
component_rail_buttons.position
)
upper_button_position_rnd = r.buttons_distance + lower_button_position_rnd
(
rail_buttons,
lower_button_position_rnd,
upper_button_position_rnd,
) = self._create_rail_buttons(component_rail_buttons)
rocket.set_rail_buttons(
upper_button_position=upper_button_position_rnd,
lower_button_position=lower_button_position_rnd,
angular_position=r.angular_position,
angular_position=rail_buttons.angular_position,
)

for parachute in self.parachutes:
p = parachute.create_object()
parachute = self._create_parachute(parachute)
rocket.add_parachute(
name=p.name,
cd_s=p.cd_s,
trigger=p.trigger,
sampling_rate=p.sampling_rate,
lag=p.lag,
noise=p.noise,
name=parachute.name,
cd_s=parachute.cd_s,
trigger=parachute.trigger,
sampling_rate=parachute.sampling_rate,
lag=parachute.lag,
noise=parachute.noise,
)

return rocket
Loading

0 comments on commit b16e329

Please sign in to comment.