Source code for rocketpy.rocket.aero_surface.linear_generic_surface

from rocketpy.mathutils import Function
from rocketpy.plots.aero_surface_plots import _LinearGenericSurfacePlots
from rocketpy.prints.aero_surface_prints import _LinearGenericSurfacePrints
from rocketpy.rocket.aero_surface.generic_surface import GenericSurface


[docs] class LinearGenericSurface(GenericSurface): """Class that defines a generic linear aerodynamic surface. This class is used to define aerodynamic surfaces that have aerodynamic coefficients defined as linear functions of the coefficients derivatives."""
[docs] def __init__( self, reference_area, reference_length, coefficients, center_of_pressure=(0, 0, 0), name="Generic Linear Surface", ): """Create a generic linear aerodynamic surface, defined by its aerodynamic coefficients derivatives. This surface is used to model any aerodynamic surface that does not fit the predefined classes. Important --------- All the aerodynamic coefficients can be input as callable functions of angle of attack, angle of sideslip, Mach number, Reynolds number, pitch rate, yaw rate and roll rate. For CSV files, the header must contain at least one of the following: "alpha", "beta", "mach", "reynolds", "pitch_rate", "yaw_rate" and "roll_rate". See Also -------- :ref:`genericsurfaces`. Parameters ---------- reference_area : int, float Reference area of the aerodynamic surface. Has the unit of meters squared. Commonly defined as the rocket's cross-sectional area. reference_length : int, float Reference length of the aerodynamic surface. Has the unit of meters. Commonly defined as the rocket's diameter. coefficients: dict, optional List of coefficients. If a coefficient is omitted, it is set to 0. The valid coefficients are:\n cL_0: callable, str, optional Coefficient of lift at zero angle of attack. Default is 0.\n cL_alpha: callable, str, optional Coefficient of lift derivative with respect to angle of attack. Default is 0.\n cL_beta: callable, str, optional Coefficient of lift derivative with respect to sideslip angle. Default is 0.\n cL_p: callable, str, optional Coefficient of lift derivative with respect to roll rate. Default is 0.\n cL_q: callable, str, optional Coefficient of lift derivative with respect to pitch rate. Default is 0.\n cL_r: callable, str, optional Coefficient of lift derivative with respect to yaw rate. Default is 0.\n cQ_0: callable, str, optional Coefficient of side force at zero angle of attack. Default is 0.\n cQ_alpha: callable, str, optional Coefficient of side force derivative with respect to angle of attack. Default is 0.\n cQ_beta: callable, str, optional Coefficient of side force derivative with respect to sideslip angle. Default is 0.\n cQ_p: callable, str, optional Coefficient of side force derivative with respect to roll rate. Default is 0.\n cQ_q: callable, str, optional Coefficient of side force derivative with respect to pitch rate. Default is 0.\n cQ_r: callable, str, optional Coefficient of side force derivative with respect to yaw rate. Default is 0.\n cD_0: callable, str, optional Coefficient of drag at zero angle of attack. Default is 0.\n cD_alpha: callable, str, optional Coefficient of drag derivative with respect to angle of attack. Default is 0.\n cD_beta: callable, str, optional Coefficient of drag derivative with respect to sideslip angle. Default is 0.\n cD_p: callable, str, optional Coefficient of drag derivative with respect to roll rate. Default is 0.\n cD_q: callable, str, optional Coefficient of drag derivative with respect to pitch rate. Default is 0.\n cD_r: callable, str, optional Coefficient of drag derivative with respect to yaw rate. Default is 0.\n cm_0: callable, str, optional Coefficient of pitch moment at zero angle of attack. Default is 0.\n cm_alpha: callable, str, optional Coefficient of pitch moment derivative with respect to angle of attack. Default is 0.\n cm_beta: callable, str, optional Coefficient of pitch moment derivative with respect to sideslip angle. Default is 0.\n cm_p: callable, str, optional Coefficient of pitch moment derivative with respect to roll rate. Default is 0.\n cm_q: callable, str, optional Coefficient of pitch moment derivative with respect to pitch rate. Default is 0.\n cm_r: callable, str, optional Coefficient of pitch moment derivative with respect to yaw rate. Default is 0.\n cn_0: callable, str, optional Coefficient of yaw moment at zero angle of attack. Default is 0.\n cn_alpha: callable, str, optional Coefficient of yaw moment derivative with respect to angle of attack. Default is 0.\n cn_beta: callable, str, optional Coefficient of yaw moment derivative with respect to sideslip angle. Default is 0.\n cn_p: callable, str, optional Coefficient of yaw moment derivative with respect to roll rate. Default is 0.\n cn_q: callable, str, optional Coefficient of yaw moment derivative with respect to pitch rate. Default is 0.\n cn_r: callable, str, optional Coefficient of yaw moment derivative with respect to yaw rate. Default is 0.\n cl_0: callable, str, optional Coefficient of roll moment at zero angle of attack. Default is 0.\n cl_alpha: callable, str, optional Coefficient of roll moment derivative with respect to angle of attack. Default is 0.\n cl_beta: callable, str, optional Coefficient of roll moment derivative with respect to sideslip angle. Default is 0.\n cl_p: callable, str, optional Coefficient of roll moment derivative with respect to roll rate. Default is 0.\n cl_q: callable, str, optional Coefficient of roll moment derivative with respect to pitch rate. Default is 0.\n cl_r: callable, str, optional Coefficient of roll moment derivative with respect to yaw rate. Default is 0.\n center_of_pressure : tuple, optional Application point of the aerodynamic forces and moments. The center of pressure is defined in the local coordinate system of the aerodynamic surface. The default value is (0, 0, 0). name : str Name of the aerodynamic surface. Default is 'GenericSurface'. """ super().__init__( reference_area=reference_area, reference_length=reference_length, coefficients=coefficients, center_of_pressure=center_of_pressure, name=name, ) self.compute_all_coefficients() self.prints = _LinearGenericSurfacePrints(self) self.plots = _LinearGenericSurfacePlots(self)
[docs] def _get_default_coefficients(self): """Returns default coefficients Returns ------- default_coefficients: dict Dictionary whose keys are the coefficients names and keys are the default values. """ default_coefficients = { "cL_0": 0, "cL_alpha": 0, "cL_beta": 0, "cL_p": 0, "cL_q": 0, "cL_r": 0, "cQ_0": 0, "cQ_alpha": 0, "cQ_beta": 0, "cQ_p": 0, "cQ_q": 0, "cQ_r": 0, "cD_0": 0, "cD_alpha": 0, "cD_beta": 0, "cD_p": 0, "cD_q": 0, "cD_r": 0, "cm_0": 0, "cm_alpha": 0, "cm_beta": 0, "cm_p": 0, "cm_q": 0, "cm_r": 0, "cn_0": 0, "cn_alpha": 0, "cn_beta": 0, "cn_p": 0, "cn_q": 0, "cn_r": 0, "cl_0": 0, "cl_alpha": 0, "cl_beta": 0, "cl_p": 0, "cl_q": 0, "cl_r": 0, } return default_coefficients
[docs] def compute_forcing_coefficient(self, c_0, c_alpha, c_beta): """Compute the forcing coefficient from the derivatives of the aerodynamic coefficients.""" def total_coefficient( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ): return ( c_0(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) + c_alpha(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) * alpha + c_beta(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) * beta ) return Function( total_coefficient, [ "alpha", "beta", "mach", "reynolds", "pitch_rate", "yaw_rate", "roll_rate", ], ["coefficient"], )
[docs] def compute_damping_coefficient(self, c_p, c_q, c_r): """Compute the damping coefficient from the derivatives of the aerodynamic coefficients.""" def total_coefficient( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ): return ( c_p(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) * roll_rate + c_q(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) * pitch_rate + c_r(alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate) * yaw_rate ) return Function( total_coefficient, [ "alpha", "beta", "mach", "reynolds", "pitch_rate", "yaw_rate", "roll_rate", ], ["coefficient"], )
[docs] def compute_all_coefficients(self): """Compute all the aerodynamic coefficients from the derivatives.""" # pylint: disable=invalid-name self.cLf = self.compute_forcing_coefficient( self.cL_0, self.cL_alpha, self.cL_beta ) self.cLd = self.compute_damping_coefficient(self.cL_p, self.cL_q, self.cL_r) self.cQf = self.compute_forcing_coefficient( self.cQ_0, self.cQ_alpha, self.cQ_beta ) self.cQd = self.compute_damping_coefficient(self.cQ_p, self.cQ_q, self.cQ_r) self.cDf = self.compute_forcing_coefficient( self.cD_0, self.cD_alpha, self.cD_beta ) self.cDd = self.compute_damping_coefficient(self.cD_p, self.cD_q, self.cD_r) self.cmf = self.compute_forcing_coefficient( self.cm_0, self.cm_alpha, self.cm_beta ) self.cmd = self.compute_damping_coefficient(self.cm_p, self.cm_q, self.cm_r) self.cnf = self.compute_forcing_coefficient( self.cn_0, self.cn_alpha, self.cn_beta ) self.cnd = self.compute_damping_coefficient(self.cn_p, self.cn_q, self.cn_r) self.clf = self.compute_forcing_coefficient( self.cl_0, self.cl_alpha, self.cl_beta ) self.cld = self.compute_damping_coefficient(self.cl_p, self.cl_q, self.cl_r)
[docs] def _compute_from_coefficients( self, rho, stream_speed, alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate, ): """Compute the aerodynamic forces and moments from the aerodynamic coefficients. Parameters ---------- rho : float Air density. stream_speed : float Magnitude of the airflow speed. alpha : float Angle of attack in radians. beta : float Sideslip angle in radians. mach : float Mach number. reynolds : float Reynolds number. pitch_rate : float Pitch rate in radians per second. yaw_rate : float Yaw rate in radians per second. roll_rate : float Roll rate in radians per second. Returns ------- tuple of float The aerodynamic forces (lift, side_force, drag) and moments (pitch, yaw, roll) in the body frame. """ # Precompute common values dyn_pressure_area = 0.5 * rho * stream_speed**2 * self.reference_area dyn_pressure_area_damping = ( 0.5 * rho * stream_speed * self.reference_area * self.reference_length / 2 ) dyn_pressure_area_length = dyn_pressure_area * self.reference_length dyn_pressure_area_length_damping = ( 0.5 * rho * stream_speed * self.reference_area * self.reference_length**2 / 2 ) # Compute aerodynamic forces lift = dyn_pressure_area * self.cLf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_damping * self.cLd( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) side = dyn_pressure_area * self.cQf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_damping * self.cQd( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) drag = dyn_pressure_area * self.cDf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_damping * self.cDd( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) # Compute aerodynamic moments pitch = dyn_pressure_area_length * self.cmf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_length_damping * self.cmd( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) yaw = dyn_pressure_area_length * self.cnf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_length_damping * self.cnd( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) roll = dyn_pressure_area_length * self.clf( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) + dyn_pressure_area_length_damping * self.cld( alpha, beta, mach, reynolds, pitch_rate, yaw_rate, roll_rate ) return lift, side, drag, pitch, yaw, roll