def _create_winglet(self): """Create winglet. Returns ------- aerosandbox.Wing """ # Extract winglet configuration parameters = self.winglet_parameters dimensions = self.winglet_dimensions location_tip = self.__get_winglet_vector__( length=dimensions["length"], sweep=parameters[W_ANGLE_SWEEP], cant=parameters[W_ANGLE_CANT], ) # Slightly separete from the wing _epsilon_winglet_wing = Point([0, 0, 0.01]) # Get wing tip section _section = self.__wingtip_section__ _coordinates = list(_section[LE_LOCATION]) coordinates_weld = _coordinates + _epsilon_winglet_wing # Match TE of wing tip and winglet root chord chord_root = dimensions["chord_root"] chord_tip = dimensions["chord_tip"] coordinates_weld.x += _section[CHORD] - chord_root winglet_airfoil = sbx.Airfoil(name=parameters[W_AIRFOIL]) twist_root = parameters[W_ANGLE_TWIST_ROOT] twist_tip = parameters[W_ANGLE_TWIST_TIP] winglet = sbx.Wing( name="Winglet", xyz_le=list(coordinates_weld), symmetric=True, xsecs=[ sbx.WingXSec( xyz_le=[0, 0, 0], chord=chord_root, twist=twist_root, airfoil=winglet_airfoil, ), sbx.WingXSec( xyz_le=list(location_tip), chord=chord_tip, twist=twist_tip, airfoil=winglet_airfoil, ), ], ) self.winglet = [winglet] return winglet
def get_aero(alpha, taper_ratio): airplane = asb.Airplane(wings=[ asb.Wing(symmetric=True, xsecs=[ asb.WingXSec( xyz_le=[-0.25, 0, 0], chord=1, ), asb.WingXSec( xyz_le=[-0.25 * taper_ratio, 1, 0], chord=taper_ratio, ) ]) ]) op_point = asb.OperatingPoint( velocity=1, alpha=alpha, ) vlm = asb.VortexLatticeMethod( airplane, op_point, chordwise_resolution=6, spanwise_resolution=6, ) return vlm.run()
def create_wing_planform(self): """Create planform object. Returns ------- aerosanbox.Wing """ # Create sections sections = [] for _section in self.sections: _coordinates = list(_section[LE_LOCATION]) _airfoil = sbx.Airfoil(name=_section[AIRFOIL]) _sbx_section = sbx.WingXSec( xyz_le= _coordinates, # Coordinates of the XSec's leading edge, **relative** to the wing's leading edge. chord=_section[CHORD], twist=_section[TWIST], # degrees airfoil=_airfoil, ) sections.append(_sbx_section) # Create wing planform = sbx.Wing( name=self.NAME, xyz_le=[0.0, 0.0, 0.0], # Coordinates of the wing's leading edge symmetric=True, xsecs=sections, ) self.planform = planform return planform
import aerosandbox as asb import aerosandbox.numpy as np airfoil = asb.Airfoil("naca0008") airplane = asb.Airplane(name="Flat Plate", xyz_ref=[0, 0, 0], wings=[ asb.Wing(name="Wing", symmetric=True, xsecs=[ asb.WingXSec( xyz_le=[0, 0, 0], chord=1, twist=0, airfoil=airfoil, ), asb.WingXSec( xyz_le=[0, 5, 0], chord=1, twist=0, airfoil=airfoil, ), ]) ]) if __name__ == '__main__': airplane.draw()
airplane = asb.Airplane( name="Vanilla", xyz_ref=[0.5, 0, 0], s_ref=9, c_ref=0.9, b_ref=10, wings=[ asb.Wing(name="Wing", symmetric=True, xsecs=[ asb.WingXSec( xyz_le=[0, 0, 0], chord=1, twist=2, airfoil=sd7037, ), asb.WingXSec( xyz_le=[0.2, 5, 1], chord=0.6, twist=2, airfoil=sd7037, ) ]), asb.Wing(name="H-stab", symmetric=True, xyz_le=[4, 0, 0], xsecs=[ asb.WingXSec( xyz_le=[0, 0, 0], chord=0.7, ),
wings=[ asb.Wing( name="Main Wing", symmetric=True, # Should this wing be mirrored across the XZ plane? xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root xyz_le=[0, 0, 0], # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=0.18, twist=0, # degrees airfoil=wing_airfoil, # Airfoils are blended between a given XSec and the next one. control_surface_is_symmetric=True, # Flap (ctrl. surfs. applied between this XSec and the next one.) control_surface_deflection=0, # degrees ), asb.WingXSec( # Mid xyz_le=[0.01, 0.5, 0], chord=0.16, twist=0, airfoil=wing_airfoil, control_surface_is_symmetric=False, # Aileron control_surface_deflection=0, ), asb.WingXSec( # Tip xyz_le=[0.08, 1, 0.1], chord=0.08, twist=0, airfoil=wing_airfoil, ), ] ), asb.Wing(
wing = asb.Wing( name="Main Wing", # x_le=-0.05 * wing_root_chord, # Coordinates of the wing's leading edge x_le=wing_x_quarter_chord, # Coordinates of the wing's leading edge y_le=0, # Coordinates of the wing's leading edge z_le=0, # Coordinates of the wing's leading edge symmetric=True, xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root x_le=-wing_root_chord / 4, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. y_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. z_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=wing_root_chord, twist=0, # degrees airfoil= e216, # Airfoils are blended between a given XSec and the next one. control_surface_type='symmetric', # Flap # Control surfaces are applied between a given XSec and the next one. control_surface_deflection=0, # degrees ), asb.WingXSec( # Tip x_le=-wing_root_chord * 0.5 / 4, y_le=wing_span / 2, z_le=0, # wing_span / 2 * cas.pi / 180 * 5, chord=wing_root_chord * 0.5, twist=0, airfoil=e216, ), ])
import aerosandbox as asb import aerosandbox.numpy as np import pytest airplane = asb.Airplane(wings=[ asb.Wing(xsecs=[ asb.WingXSec( xyz_le=[0, 0, 0], chord=1, airfoil=asb.Airfoil("naca0001")), asb.WingXSec( xyz_le=[0, 1, 0], chord=1, airfoil=asb.Airfoil("naca0001")) ]) ]) def LD_from_alpha(alpha): op_point = asb.OperatingPoint( velocity=1, alpha=alpha, ) vlm = asb.VortexLatticeMethod(airplane, op_point, align_trailing_vortices_with_wind=True) aero = vlm.run() CD0 = 0.01 LD = aero["CL"] / (aero["CD"] + CD0) return LD
asb.Wing( name="Main Wing", xyz_le=np.array([0, 0, 0]), # Coordinates of the wing's leading edge symmetric=True, xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root xyz_le=np.array([0, 0, 0]), # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=0.18, twist_angle=2, # degrees airfoil= e216, # Airfoils are blended between a given XSec and the next one. control_surface_is_symmetric=True, # Flap control_surface_deflection=0, # degrees ), asb.WingXSec( # Mid xyz_le=np.array([0.01, 0.5, 0]), chord=0.16, twist_angle=0, airfoil=e216, control_surface_is_symmetric=False, # Aileron control_surface_deflection=0, ), asb.WingXSec( # Tip xyz_le=np.array([0.08, 1, 0.1]), chord=0.08, twist_angle=-2, airfoil=e216, ), ]),
ae.Wing( name="Main Wing", xyz_le=[0, 0, 0], # Coordinates of the wing's leading edge symmetric=True, xsecs=[ # The wing's cross ("X") sections ae.WingXSec( # Root xyz_le=[ 0, 0, x_trans[0] ], # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=CHORD, twist=0, # degrees airfoil=ae.Airfoil(name="naca4412"), control_surface_type='symmetric', # Flap # Control surfaces are applied between a given XSec and the next one. control_surface_deflection=0, # degrees control_surface_hinge_point=0.75 # as chord fraction ), ae.WingXSec( # Mid xyz_le=[0, x_trans[1], 0], chord=CHORD, twist=0, airfoil=ae.Airfoil(name="naca4412"), control_surface_type='asymmetric', # Aileron control_surface_deflection=0, control_surface_hinge_point=0.75), ae.WingXSec( # Tip xyz_le=[0, 1, x_trans[2]], chord=CHORD, twist=0, airfoil=ae.Airfoil(name="naca4412"), ) ])
def make_airplane( n_booms, wing_span, ): # n_booms = 3 # wing # wing_span = 37.126 wing_root_chord = 2.316 wing_x_quarter_chord = -0.1 # hstab hstab_span = 2.867 hstab_chord = 1.085 hstab_twist_angle = -7 # vstab vstab_span = 2.397 vstab_chord = 1.134 # fuselage boom_length = 6.181 nose_length = 1.5 fuse_diameter = 0.6 boom_diameter = 0.2 wing = asb.Wing( name="Main Wing", # x_le=-0.05 * wing_root_chord, # Coordinates of the wing's leading edge # TODO make this a free parameter? x_le= wing_x_quarter_chord, # Coordinates of the wing's leading edge # TODO make this a free parameter? y_le=0, # Coordinates of the wing's leading edge z_le=0, # Coordinates of the wing's leading edge symmetric=True, xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root x_le=-wing_root_chord / 4, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. y_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. z_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=wing_root_chord, twist=0, # degrees airfoil= e216, # Airfoils are blended between a given XSec and the next one. control_surface_type="symmetric", # Flap # Control surfaces are applied between a given XSec and the next one. control_surface_deflection=0, # degrees spanwise_panels=30, ), asb.WingXSec( # Tip x_le=-wing_root_chord * 0.5 / 4, y_le=wing_span / 2, z_le=0, # wing_span / 2 * cas.pi / 180 * 5, chord=wing_root_chord * 0.5, twist=0, airfoil=e216, ), ], ) hstab = asb.Wing( name="Horizontal Stabilizer", x_le=boom_length - vstab_chord * 0.75 - hstab_chord, # Coordinates of the wing's leading edge y_le=0, # Coordinates of the wing's leading edge z_le=0.1, # Coordinates of the wing's leading edge symmetric=True, xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root x_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. y_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. z_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=hstab_chord, twist=-3, # degrees # TODO fix airfoil= naca0008, # Airfoils are blended between a given XSec and the next one. control_surface_type="symmetric", # Flap # Control surfaces are applied between a given XSec and the next one. control_surface_deflection=0, # degrees spanwise_panels=8, ), asb.WingXSec( # Tip x_le=0, y_le=hstab_span / 2, z_le=0, chord=hstab_chord, twist=-3, # TODO fix airfoil=naca0008, ), ], ) vstab = asb.Wing( name="Vertical Stabilizer", x_le=boom_length - vstab_chord * 0.75, # Coordinates of the wing's leading edge y_le=0, # Coordinates of the wing's leading edge z_le=-vstab_span / 2 + vstab_span * 0.15, # Coordinates of the wing's leading edge symmetric=False, xsecs=[ # The wing's cross ("X") sections asb.WingXSec( # Root x_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. y_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. z_le= 0, # Coordinates of the XSec's leading edge, relative to the wing's leading edge. chord=vstab_chord, twist=0, # degrees airfoil= naca0008, # Airfoils are blended between a given XSec and the next one. control_surface_type="symmetric", # Flap # Control surfaces are applied between a given XSec and the next one. control_surface_deflection=0, # degrees spanwise_panels=8, ), asb.WingXSec( # Tip x_le=0, y_le=0, z_le=vstab_span, chord=vstab_chord, twist=0, airfoil=naca0008, ), ], ) ### Build the fuselage geometry blend = lambda x: (1 - np.cos(np.pi * x)) / 2 fuse_x_c = [] fuse_z_c = [] fuse_radius = [] fuse_resolution = 10 # Nose geometry fuse_nose_theta = np.linspace(0, np.pi / 2, fuse_resolution) fuse_x_c.extend([(wing_x_quarter_chord - wing_root_chord / 4) - nose_length * np.cos(theta) for theta in fuse_nose_theta]) fuse_z_c.extend([-fuse_diameter / 2] * fuse_resolution) fuse_radius.extend( [fuse_diameter / 2 * np.sin(theta) for theta in fuse_nose_theta]) # Taper fuse_taper_x_nondim = np.linspace(0, 1, fuse_resolution) fuse_x_c.extend([ 0.0 * boom_length + (0.6 - 0.0) * boom_length * x_nd for x_nd in fuse_taper_x_nondim ]) fuse_z_c.extend([ -fuse_diameter / 2 * blend(1 - x_nd) - boom_diameter / 2 * blend(x_nd) for x_nd in fuse_taper_x_nondim ]) fuse_radius.extend([ fuse_diameter / 2 * blend(1 - x_nd) + boom_diameter / 2 * blend(x_nd) for x_nd in fuse_taper_x_nondim ]) # Tail # fuse_tail_x_nondim = np.linspace(0, 1, fuse_resolution)[1:] # fuse_x_c.extend([ # 0.9 * boom_length + (1 - 0.9) * boom_length * x_nd for x_nd in fuse_taper_x_nondim # ]) # fuse_z_c.extend([ # -boom_diameter / 2 * blend(1 - x_nd) for x_nd in fuse_taper_x_nondim # ]) # fuse_radius.extend([ # boom_diameter / 2 * blend(1 - x_nd) for x_nd in fuse_taper_x_nondim # ]) fuse_straight_resolution = 4 fuse_x_c.extend([ 0.6 * boom_length + (1 - 0.6) * boom_length * x_nd for x_nd in np.linspace(0, 1, fuse_straight_resolution)[1:] ]) fuse_z_c.extend([-boom_diameter / 2] * (fuse_straight_resolution - 1)) fuse_radius.extend([boom_diameter / 2] * (fuse_straight_resolution - 1)) fuse = asb.Fuselage( name="Fuselage", x_le=0, y_le=0, z_le=0, xsecs=[ asb.FuselageXSec(x_c=fuse_x_c[i], z_c=fuse_z_c[i], radius=fuse_radius[i]) for i in range(len(fuse_x_c)) ], ) # Assemble the airplane fuses = [] hstabs = [] vstabs = [] if n_booms == 1: fuses.append(fuse) hstabs.append(hstab) vstabs.append(vstab) elif n_booms == 2: boom_location = 0.40 # as a fraction of the half-span left_fuse = copy.deepcopy(fuse) right_fuse = copy.deepcopy(fuse) left_fuse.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_fuse.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) fuses.extend([left_fuse, right_fuse]) left_hstab = copy.deepcopy(hstab) right_hstab = copy.deepcopy(hstab) left_hstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_hstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) hstabs.extend([left_hstab, right_hstab]) left_vstab = copy.deepcopy(vstab) right_vstab = copy.deepcopy(vstab) left_vstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_vstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) vstabs.extend([left_vstab, right_vstab]) elif n_booms == 3: boom_location = 0.57 # as a fraction of the half-span left_fuse = copy.deepcopy(fuse) center_fuse = copy.deepcopy(fuse) right_fuse = copy.deepcopy(fuse) left_fuse.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_fuse.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) fuses.extend([left_fuse, center_fuse, right_fuse]) left_hstab = copy.deepcopy(hstab) center_hstab = copy.deepcopy(hstab) right_hstab = copy.deepcopy(hstab) left_hstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_hstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) hstabs.extend([left_hstab, center_hstab, right_hstab]) left_vstab = copy.deepcopy(vstab) center_vstab = copy.deepcopy(vstab) right_vstab = copy.deepcopy(vstab) left_vstab.xyz_le += cas.vertcat(0, -wing_span / 2 * boom_location, 0) right_vstab.xyz_le += cas.vertcat(0, wing_span / 2 * boom_location, 0) vstabs.extend([left_vstab, center_vstab, right_vstab]) else: raise ValueError("Bad value of n_booms!") airplane = asb.Airplane( name="Solar1", x_ref=0, y_ref=0, z_ref=0, wings=[wing] + hstabs + vstabs, fuselages=fuses, ) return airplane
def CD_function(alpha, Re, mach, deflection): return 0 * Re**0 def CM_function(alpha, Re, mach, deflection): return 0 * alpha ideal_airfoil = asb.Airfoil(name="Ideal Airfoil", coordinates=get_NACA_coordinates('naca0012'), CL_function=CL_function, CD_function=CD_function, CM_function=CM_function) wing = asb.Wing(xsecs=[ asb.WingXSec(xyz_le=[0, y_i, 0], chord=1, airfoil=ideal_airfoil) for y_i in [0, 10] ], symmetric=True) airplane = asb.Airplane(wings=[wing]) op_point = asb.OperatingPoint(velocity=340, alpha=0) aero = asb.AeroBuildup(airplane=airplane, op_point=op_point).run() from pprint import pprint pprint(aero)
naca2412.generate_polars(cache_filename="assets/naca2412.json") naca0012.generate_polars(cache_filename="assets/naca0012.json") airplane = asb.Airplane( name="Cessna 152", wings=[ asb.Wing(name="Wing", xsecs=[ asb.WingXSec(xyz_le=[0, 0, 0], chord=ft_to_m(5, 4), airfoil=naca2412), asb.WingXSec( xyz_le=[0, ft_to_m(7), ft_to_m(7) * np.sind(1)], chord=ft_to_m(5, 4), airfoil=naca2412), asb.WingXSec(xyz_le=[ ft_to_m(4, 3 / 4) - ft_to_m(3, 8 + 1 / 2), ft_to_m(33, 4) / 2, ft_to_m(33, 4) / 2 * np.sind(1) ], chord=ft_to_m(3, 8 + 1 / 2), airfoil=naca0012) ], symmetric=True), asb.Wing(name="Horizontal Stabilizer", xsecs=[ asb.WingXSec(xyz_le=[0, 0, 0], chord=ft_to_m(3, 8), airfoil=naca0012, twist=-2),