Skip to content

Commit e6ecbcc

Browse files
committed
Modify linear generic surface and stochastic classes to support stochastic linear generic surface
1 parent 373a7df commit e6ecbcc

3 files changed

Lines changed: 160 additions & 1 deletion

File tree

rocketpy/rocket/aero_surface/linear_generic_surface.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ def __init__(
1313
self,
1414
reference_area,
1515
reference_length,
16-
coefficients,
16+
coefficient_constants=None,
17+
coefficients=None,
1718
center_of_pressure=(0, 0, 0),
1819
name="Generic Linear Surface",
1920
):
@@ -41,6 +42,13 @@ def __init__(
4142
reference_length : int, float
4243
Reference length of the aerodynamic surface. Has the unit of meters.
4344
Commonly defined as the rocket's diameter.
45+
coefficient_constants: list, optional
46+
List of constants to be populated to the coefficients. This
47+
list will overwrite the coefficients dict if not None. The order is
48+
as follows: [cL_0, cL_alpha, cL_beta, cL_p, cL_q, cL_r, cQ_0, cQ_alpha,
49+
cQ_beta, cQ_p, cQ_q, cQ_r, cD_0, cD_alpha, cD_beta, cD_p, cD_q, cD_r,
50+
cm_0, cm_alpha, cm_beta, cm_p, cm_q, cm_r, cn_0, cn_alpha, cn_beta,
51+
cn_p, cn_q, cn_r, cl_0, cl_alpha, cl_beta, cl_p, cl_q, cl_r].
4452
coefficients: dict, optional
4553
List of coefficients. If a coefficient is omitted, it is set to 0.
4654
The valid coefficients are:\n
@@ -157,6 +165,36 @@ def __init__(
157165
name : str
158166
Name of the aerodynamic surface. Default is 'GenericSurface'.
159167
"""
168+
self.coefficient_constants = coefficient_constants
169+
# Populate the coefficients from the list of constants if they are not defined
170+
if coefficients is None:
171+
coefficients = self._get_default_coefficients()
172+
if coefficient_constants is not None:
173+
# helper to build a 7‑input callable returning a fixed value
174+
def _constant_factory(value):
175+
def _constant(
176+
alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate
177+
):
178+
"""Return the captured constant regardless of inputs."""
179+
return value
180+
181+
return _constant
182+
183+
for i, key in enumerate(self._get_default_coefficients().keys()):
184+
const = coefficient_constants[i]
185+
coefficients[key] = Function(
186+
_constant_factory(const),
187+
inputs=[
188+
"alpha",
189+
"beta",
190+
"mach",
191+
"reynolds",
192+
"pitch_rate",
193+
"yaw_rate",
194+
"roll_rate",
195+
],
196+
outputs=[key],
197+
)
160198

161199
super().__init__(
162200
reference_area=reference_area,

rocketpy/stochastic/stochastic_aero_surfaces.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from rocketpy.rocket.aero_surface import (
77
AirBrakes,
88
EllipticalFins,
9+
LinearGenericSurface,
910
NoseCone,
1011
RailButtons,
1112
Tail,
@@ -546,3 +547,91 @@ def create_object(self):
546547
)
547548
air_brakes.drag_coefficient *= generated_dict["drag_coefficient_curve_factor"]
548549
return air_brakes
550+
551+
552+
class StochasticLinearGenericSurface(StochasticModel):
553+
"""A Stochastic Linear Generic Surface class that inherits from StochasticModel.
554+
555+
See Also
556+
--------
557+
:ref:`stochastic_model` and
558+
:class:`LinearGenericSurface <rocketpy.LinearGenericSurface>`
559+
560+
Attributes
561+
----------
562+
object : LinearGenericSurface
563+
LinearGenericSurface object to be used for validation.
564+
reference_area : tuple, list, int, float
565+
Reference area of the aerodynamic surface. Has the unit of meters
566+
squared. Commonly defined as the rocket's cross-sectional area.
567+
reference_length : tuple, list, int, float
568+
Reference length of the aerodynamic surface. Has the unit of meters.
569+
Commonly defined as the rocket's diameter.
570+
center_of_pressure : tuple, optional
571+
Application point of the aerodynamic forces and moments. The
572+
center of pressure is defined in the local coordinate system of the
573+
aerodynamic surface.
574+
coefficient_curve_factor : tuple, list, int, float, optional
575+
The drag curve factor of the air brakes. This value scales the
576+
drag coefficient curve to introduce stochastic variability.
577+
name : list[str]
578+
List with the name of the object. This attribute can not be randomized.
579+
"""
580+
581+
def __init__(
582+
self,
583+
linear_generic_surface,
584+
reference_area=None,
585+
reference_length=None,
586+
coefficient_constants=None,
587+
center_of_pressure=None,
588+
):
589+
"""Initializes the Stochastic Linear Generic Surface class.
590+
591+
See Also
592+
--------
593+
:ref:`stochastic_model`
594+
595+
Parameters
596+
----------
597+
linear_generic_surface : LinearGenericSurface
598+
LinearGenericSurface object to be used for validation.
599+
reference_area : int, float
600+
Reference area of the aerodynamic surface. Has the unit of meters
601+
squared. Commonly defined as the rocket's cross-sectional area.
602+
reference_length : int, float
603+
Reference length of the aerodynamic surface. Has the unit of meters.
604+
Commonly defined as the rocket's diameter.
605+
coefficients : dict
606+
Dictionary containing the aerodynamic coefficients of the surface.
607+
center_of_pressure : tuple, optional
608+
Application point of the aerodynamic forces and moments. The center of pressure is defined in the local coordinate system of the
609+
coefficient_curve_factor : tuple, list, int, float, optional
610+
The drag curve factor of the air brakes. This value scales the
611+
drag coefficient curve to introduce stochastic variability.
612+
"""
613+
super().__init__(
614+
linear_generic_surface,
615+
reference_area=reference_area,
616+
reference_length=reference_length,
617+
coefficient_constants=coefficient_constants,
618+
center_of_pressure=center_of_pressure,
619+
name=None,
620+
)
621+
622+
def create_object(self):
623+
"""Creates and returns a LinearGenericSurface object from the randomly generated input arguments.
624+
625+
Returns
626+
-------
627+
linear_generic_surface : LinearGenericSurface
628+
LinearGenericSurface object with the randomly generated input arguments.
629+
"""
630+
generated_dict = next(self.dict_generator())
631+
linear_generic_surface = LinearGenericSurface(
632+
reference_area=generated_dict["reference_area"],
633+
reference_length=generated_dict["reference_length"],
634+
coefficient_constants=generated_dict["coefficient_constants"],
635+
center_of_pressure=generated_dict["center_of_pressure"],
636+
)
637+
return linear_generic_surface

rocketpy/stochastic/stochastic_rocket.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from rocketpy.rocket.aero_surface import (
1212
AirBrakes,
1313
EllipticalFins,
14+
LinearGenericSurface,
1415
NoseCone,
1516
RailButtons,
1617
Tail,
@@ -25,6 +26,7 @@
2526
from .stochastic_aero_surfaces import (
2627
StochasticAirBrakes,
2728
StochasticEllipticalFins,
29+
StochasticLinearGenericSurface,
2830
StochasticNoseCone,
2931
StochasticRailButtons,
3032
StochasticTail,
@@ -419,6 +421,36 @@ def add_air_brakes(self, air_brakes, controller):
419421
self.air_brakes.append(air_brakes)
420422
self.air_brake_controller = controller
421423

424+
def add_linear_generic_surface(self, linear_generic_surface, position=None):
425+
"""Adds a stochastic linear generic surface to the stochastic rocket.
426+
427+
Parameters
428+
----------
429+
linear_generic_surface : StochasticLinearGenericSurface or LinearGenericSurface
430+
The linear generic surface to be added to the stochastic rocket.
431+
position : tuple, list, int, float, optional
432+
The position of the linear generic surface.
433+
"""
434+
if not isinstance(
435+
linear_generic_surface,
436+
(StochasticLinearGenericSurface, LinearGenericSurface),
437+
):
438+
raise TypeError(
439+
"`linear_generic_surface` must be of LinearGenericSurface or "
440+
"StochasticLinearGenericSurface type"
441+
)
442+
if isinstance(linear_generic_surface, LinearGenericSurface):
443+
linear_generic_surface = StochasticLinearGenericSurface(
444+
linear_generic_surface=linear_generic_surface
445+
)
446+
self._add_surfaces(
447+
linear_generic_surface,
448+
position,
449+
LinearGenericSurface,
450+
StochasticLinearGenericSurface,
451+
"`linear_generic_surface` must be of LinearGenericSurface or StochasticLinearGenericSurface type",
452+
)
453+
422454
def add_cp_eccentricity(self, x=None, y=None):
423455
"""Moves line of action of aerodynamic forces to simulate an
424456
eccentricity in the position of the center of pressure relative

0 commit comments

Comments
 (0)