-
-
Notifications
You must be signed in to change notification settings - Fork 265
ENH: Improve parachute geometric parametrization #835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
0873d21
02ddd1b
1119ef8
413503f
f09a4b0
78ef92e
7defc38
465f526
c5ce166
f84459d
4fcb406
159cce8
0c434f8
f136ffb
112b75a
40d10c5
1e2a2fd
65530fd
363bfc8
53b0940
87216ca
4f20568
68fc191
9a03c01
486a5d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ | |
|
|
||
|
|
||
| class Parachute: | ||
| """Keeps parachute information. | ||
| """Keeps information of the parachute, which is modeled as a hemispheroid. | ||
|
|
||
| Attributes | ||
| ---------- | ||
|
|
@@ -92,6 +92,15 @@ class Parachute: | |
| Function of noisy_pressure_signal. | ||
| Parachute.clean_pressure_signal_function : Function | ||
| Function of clean_pressure_signal. | ||
| Parachute.radius : float | ||
| Length of the non-unique semi-axis (radius) of the inflated hemispheroid | ||
| parachute in meters. | ||
| Parachute.height : float, None | ||
| Length of the unique semi-axis (height) of the inflated hemispheroid | ||
| parachute in meters. | ||
| Parachute.porosity : float | ||
| Porosity of the parachute is the ratio of open space in the canopy to total | ||
| canopy area. | ||
| """ | ||
|
|
||
| def __init__( | ||
|
|
@@ -102,6 +111,9 @@ def __init__( | |
| sampling_rate, | ||
| lag=0, | ||
| noise=(0, 0, 0), | ||
| radius=1.5, | ||
| height=None, | ||
| porosity=0.0432, | ||
| ): | ||
| """Initializes Parachute class. | ||
|
|
||
|
|
@@ -154,6 +166,17 @@ def __init__( | |
| The values are used to add noise to the pressure signal which is | ||
| passed to the trigger function. Default value is ``(0, 0, 0)``. | ||
| Units are in Pa. | ||
| radius : float, optional | ||
| Length of the non-unique semi-axis (radius) of the inflated hemispheroid | ||
| parachute. Default value is 1.5. | ||
| Units are in meters. | ||
| height : float, optional | ||
| Length of the unique semi-axis (height) of the inflated hemispheroid | ||
| parachute. Default value is the radius of the parachute. | ||
| Units are in meters. | ||
| porosity : float, optional | ||
| Porosity of the parachute is the ratio of open space in the canopy to total | ||
| canopy area. Default value is 0.0432 (for consistency with previous versions). | ||
|
Gui-FernandesBR marked this conversation as resolved.
Outdated
|
||
| """ | ||
| self.name = name | ||
| self.cd_s = cd_s | ||
|
|
@@ -170,6 +193,15 @@ def __init__( | |
| self.clean_pressure_signal_function = Function(0) | ||
| self.noisy_pressure_signal_function = Function(0) | ||
| self.noise_signal_function = Function(0) | ||
| self.radius = radius | ||
| self.height = height or radius | ||
| self.porosity = porosity | ||
| self.ka = 1.068 * ( | ||
| 1 | ||
| - 1.465 * self.porosity | ||
| - 0.25975 * self.porosity**2 | ||
| + 1.2626 * self.porosity**3 | ||
| ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you document Parachute.ka in the class docstring please? Also, what does ka mean? Could we think about a new, more descriptive name for it? In python, we rather use the explicit version than implicit version of name variables. self.aoa is not preferred
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ka is the added mass coefficient. Should I change the variable to added_mass_coefficient and document it?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, please. To document it, you just have to add some docstrings to class |
||
|
|
||
| alpha, beta = self.noise_corr | ||
| self.noise_function = lambda: alpha * self.noise_signal[-1][ | ||
|
|
@@ -264,6 +296,9 @@ def to_dict(self, include_outputs=False): | |
| "sampling_rate": self.sampling_rate, | ||
| "lag": self.lag, | ||
| "noise": self.noise, | ||
| "radius": self.radius, | ||
| "height": self.height, | ||
| "porosity": self.porosity, | ||
| } | ||
|
|
||
| if include_outputs: | ||
|
|
@@ -290,6 +325,9 @@ def from_dict(cls, data): | |
| sampling_rate=data["sampling_rate"], | ||
| lag=data["lag"], | ||
| noise=data["noise"], | ||
| radius=data.get("radius", 1.5), | ||
| height=data.get("height", None), | ||
| porosity=data.get("porosity", 0.0432), | ||
| ) | ||
|
|
||
| return parachute | ||
|
Gui-FernandesBR marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -765,7 +765,21 @@ def __simulate(self, verbose): | |
| callbacks = [ | ||
| lambda self, parachute_cd_s=parachute.cd_s: setattr( | ||
| self, "parachute_cd_s", parachute_cd_s | ||
| ) | ||
| ), | ||
| lambda self, | ||
| parachute_radius=parachute.parachute_radius: setattr( | ||
| self, "parachute_radius", parachute_radius | ||
| ), | ||
| lambda self, | ||
| parachute_height=parachute.parachute_height: setattr( | ||
| self, "parachute_height", parachute_height | ||
| ), | ||
| lambda self, parachute_porosity=parachute.porosity: setattr( | ||
| self, "parachute_porosity", parachute_porosity | ||
| ), | ||
| lambda self, ka=parachute.ka: setattr( | ||
| self, "parachute_ka", ka | ||
| ), | ||
| ] | ||
| self.flight_phases.add_phase( | ||
| node.t + parachute.lag, | ||
|
|
@@ -1011,7 +1025,28 @@ def __simulate(self, verbose): | |
| lambda self, | ||
| parachute_cd_s=parachute.cd_s: setattr( | ||
| self, "parachute_cd_s", parachute_cd_s | ||
| ) | ||
| ), | ||
| lambda self, | ||
| parachute_radius=parachute.radius: setattr( | ||
| self, | ||
| "parachute_radius", | ||
| parachute_radius, | ||
| ), | ||
| lambda self, | ||
| parachute_height=parachute.height: setattr( | ||
| self, | ||
| "parachute_height", | ||
| parachute_height, | ||
| ), | ||
| lambda self, | ||
| parachute_porosity=parachute.porosity: setattr( | ||
| self, | ||
| "parachute_porosity", | ||
| parachute_porosity, | ||
| ), | ||
| lambda self, ka=parachute.ka: setattr( | ||
| self, "ka", ka | ||
| ), | ||
| ] | ||
| self.flight_phases.add_phase( | ||
| overshootable_node.t + parachute.lag, | ||
|
|
@@ -1963,24 +1998,27 @@ def u_dot_parachute(self, t, u, post_processing=False): | |
| wind_velocity_x = self.env.wind_velocity_x.get_value_opt(z) | ||
| wind_velocity_y = self.env.wind_velocity_y.get_value_opt(z) | ||
|
|
||
| # Get Parachute data | ||
| cd_s = self.parachute_cd_s | ||
|
|
||
| # Get the mass of the rocket | ||
| mp = self.rocket.dry_mass | ||
|
|
||
| # Define constants | ||
| ka = 1 # Added mass coefficient (depends on parachute's porosity) | ||
| R = 1.5 # Parachute radius | ||
| # to = 1.2 | ||
| # eta = 1 | ||
| # Rdot = (6 * R * (1 - eta) / (1.2**6)) * ( | ||
| # (1 - eta) * t**5 + eta * (to**3) * (t**2) | ||
| # ) | ||
| # Rdot = 0 | ||
|
|
||
| # tf = 8 * nominal diameter / velocity at line stretch | ||
|
|
||
| # Calculate added mass | ||
| ma = ka * rho * (4 / 3) * np.pi * R**3 | ||
| ma = ( | ||
| self.ka | ||
| * rho | ||
| * (4 / 3) | ||
| * np.pi | ||
| * self.parachute_radius**2 | ||
| * self.parachute_height | ||
| ) | ||
|
Comment on lines
+2014
to
+2024
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is calculating the volume of the whole sphere right? I think it should be divided by two to account for the hemispheroid shape only
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| # Calculate freestream speed | ||
| freestream_x = vx - wind_velocity_x | ||
|
|
@@ -1989,14 +2027,14 @@ def u_dot_parachute(self, t, u, post_processing=False): | |
| free_stream_speed = (freestream_x**2 + freestream_y**2 + freestream_z**2) ** 0.5 | ||
|
|
||
| # Determine drag force | ||
| pseudo_drag = -0.5 * rho * cd_s * free_stream_speed | ||
| pseudo_drag = -0.5 * rho * self.parachute_cd_s * free_stream_speed | ||
| # pseudo_drag = pseudo_drag - ka * rho * 4 * np.pi * (R**2) * Rdot | ||
| Dx = pseudo_drag * freestream_x | ||
| Dx = pseudo_drag * freestream_x # add eta efficiency for wake | ||
| Dy = pseudo_drag * freestream_y | ||
| Dz = pseudo_drag * freestream_z | ||
| ax = Dx / (mp + ma) | ||
| ay = Dy / (mp + ma) | ||
| az = (Dz - 9.8 * mp) / (mp + ma) | ||
| az = (Dz - mp * self.env.gravity.get_value_opt(z)) / (mp + ma) | ||
|
|
||
| # Add coriolis acceleration | ||
| _, w_earth_y, w_earth_z = self.env.earth_rotation_vector | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having both
cdsandparachute_radius? do you think we could possible calculate the cd based on these other parameters?