Пример #1
0
def vehicle_setup():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'Concorde'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------

    # mass properties
    vehicle.mass_properties.max_takeoff = 185000.  # kg
    vehicle.mass_properties.operating_empty = 78700.  # kg
    vehicle.mass_properties.takeoff = 183000.  # kg, adjusted due to significant fuel burn on runway
    vehicle.mass_properties.cargo = 1000. * Units.kilogram
    vehicle.mass_properties.max_zero_fuel = 92000.

    # envelope properties
    vehicle.envelope.ultimate_load = 3.75
    vehicle.envelope.limit_load = 2.5

    # basic parameters
    vehicle.reference_area = 358.25
    vehicle.passengers = 100
    vehicle.systems.control = "fully powered"
    vehicle.systems.accessories = "sst"
    vehicle.maximum_cross_sectional_area = 13.9
    vehicle.total_length = 61.66
    vehicle.design_mach_number = 2.02
    vehicle.design_range = 4505 * Units.miles
    vehicle.design_cruise_alt = 60000.0 * Units.ft

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'

    wing.aspect_ratio = 1.83
    wing.sweeps.quarter_chord = 59.5 * Units.deg
    wing.sweeps.leading_edge = 66.5 * Units.deg
    wing.thickness_to_chord = 0.03
    wing.taper = 0.

    wing.spans.projected = 25.6

    wing.chords.root = 33.8
    wing.total_length = 33.8
    wing.chords.tip = 1.1
    wing.chords.mean_aerodynamic = 18.4

    wing.areas.reference = 358.25
    wing.areas.wetted = 601.
    wing.areas.exposed = 326.5
    wing.areas.affected = .6 * wing.areas.reference

    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees

    wing.origin = [[14, 0, -.8]]
    wing.aerodynamic_center = [35, 0, 0]

    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = True
    wing.vortex_lift = True
    wing.high_mach = True

    wing.dynamic_pressure_ratio = 1.0

    wing_airfoil = SUAVE.Components.Airfoils.Airfoil()

    # This airfoil is not a true Concorde airfoil
    wing_airfoil.coordinate_file = '../Vehicles/Airfoils/NACA65-203.txt'

    wing.append_airfoil(wing_airfoil)

    # set root sweep with inner section
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_1'
    segment.percent_span_location = 0.
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 33.8 / 33.8
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 67. * Units.deg
    segment.thickness_to_chord = 0.03
    #segment.append_airfoil(wing_airfoil)
    wing.Segments.append(segment)

    # set section 2 start point
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_2'
    segment.percent_span_location = 6.15 / (
        25.6 / 2) + wing.Segments['section_1'].percent_span_location
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 13.8 / 33.8
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 48. * Units.deg
    segment.thickness_to_chord = 0.03
    segment.append_airfoil(wing_airfoil)
    wing.Segments.append(segment)

    # set section 3 start point
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_3'
    segment.percent_span_location = 5.95 / (
        25.6 / 2) + wing.Segments['section_2'].percent_span_location
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 4.4 / 33.8
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 71. * Units.deg
    segment.thickness_to_chord = 0.03
    segment.append_airfoil(wing_airfoil)
    wing.Segments.append(segment)

    # set tip
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'tip'
    segment.percent_span_location = 1.
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 1.1 / 33.8
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = 0.03
    segment.append_airfoil(wing_airfoil)
    wing.Segments.append(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # CG locations are approximate
    # Masses from http://www.concordesst.com/fuelsys.html
    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_9'
    fuel_tank.mass_properties.center_of_gravity = np.array([[26.5, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 11096
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_10'
    fuel_tank.mass_properties.center_of_gravity = np.array([[28.7, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 11943
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_1_and_4'
    fuel_tank.mass_properties.center_of_gravity = np.array([[31.0, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 4198 + 4198
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_5_and_8'
    fuel_tank.mass_properties.center_of_gravity = np.array([[32.9, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 7200 + 12838
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_6_and_7'
    fuel_tank.mass_properties.center_of_gravity = np.array([[37.4, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 11587 + 7405
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_5A_and_7A'
    fuel_tank.mass_properties.center_of_gravity = np.array([[40.2, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 2225 + 2225
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_2_and_3'
    fuel_tank.mass_properties.center_of_gravity = np.array([[40.2, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 4570 + 4570
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    wing.Fuel_Tanks.append(fuel_tank)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Vertical Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Vertical_Tail()
    wing.tag = 'vertical_stabilizer'

    wing.aspect_ratio = 0.74  #
    wing.sweeps.quarter_chord = 60 * Units.deg
    wing.thickness_to_chord = 0.04
    wing.taper = 0.14

    wing.spans.projected = 6.0  #

    wing.chords.root = 14.5
    wing.total_length = 14.5
    wing.chords.tip = 2.7
    wing.chords.mean_aerodynamic = 8.66

    wing.areas.reference = 33.91  #
    wing.areas.wetted = 76.
    wing.areas.exposed = 38.
    wing.areas.affected = 33.91

    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees

    wing.origin = [[42., 0, 1.]]
    wing.aerodynamic_center = [50, 0, 0]

    wing.vertical = True
    wing.symmetric = False
    wing.t_tail = False
    wing.high_mach = True

    wing.dynamic_pressure_ratio = 1.0

    tail_airfoil = SUAVE.Components.Airfoils.Airfoil()
    # This airfoil is not a true Concorde airfoil
    tail_airfoil.coordinate_file = '../Vehicles/Airfoils/supersonic_tail.txt'

    wing.append_airfoil(tail_airfoil)

    # set root sweep with inner section
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_1'
    segment.percent_span_location = 0.0
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 14.5 / 14.5
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 63. * Units.deg
    segment.thickness_to_chord = 0.04
    segment.append_airfoil(tail_airfoil)
    wing.Segments.append(segment)

    # set mid section start point
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_2'
    segment.percent_span_location = 2.4 / (
        6.0) + wing.Segments['section_1'].percent_span_location
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 7.5 / 14.5
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 40. * Units.deg
    segment.thickness_to_chord = 0.04
    segment.append_airfoil(tail_airfoil)
    wing.Segments.append(segment)

    # set tip
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'tip'
    segment.percent_span_location = 1.
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 2.7 / 14.5
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = 0.04
    segment.append_airfoil(tail_airfoil)
    wing.Segments.append(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Fuselage
    # ------------------------------------------------------------------

    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'

    fuselage.seats_abreast = 4
    fuselage.seat_pitch = 38. * Units.inches

    fuselage.fineness.nose = 4.3
    fuselage.fineness.tail = 6.4

    fuselage.lengths.total = 61.66

    fuselage.width = 2.88

    fuselage.heights.maximum = 3.32  #

    fuselage.heights.maximum = 3.32  #
    fuselage.heights.at_quarter_length = 3.32  #
    fuselage.heights.at_wing_root_quarter_chord = 3.32  #
    fuselage.heights.at_three_quarters_length = 3.32  #

    fuselage.areas.wetted = 442.
    fuselage.areas.front_projected = 11.9

    fuselage.effective_diameter = 3.1

    fuselage.differential_pressure = 7.4e4 * Units.pascal  # Maximum differential pressure

    fuselage.OpenVSP_values = Data()  # VSP uses degrees directly

    fuselage.OpenVSP_values.nose = Data()
    fuselage.OpenVSP_values.nose.top = Data()
    fuselage.OpenVSP_values.nose.side = Data()
    fuselage.OpenVSP_values.nose.top.angle = 20.0
    fuselage.OpenVSP_values.nose.top.strength = 0.75
    fuselage.OpenVSP_values.nose.side.angle = 20.0
    fuselage.OpenVSP_values.nose.side.strength = 0.75
    fuselage.OpenVSP_values.nose.TB_Sym = True
    fuselage.OpenVSP_values.nose.z_pos = -.01

    fuselage.OpenVSP_values.tail = Data()
    fuselage.OpenVSP_values.tail.top = Data()
    fuselage.OpenVSP_values.tail.side = Data()
    fuselage.OpenVSP_values.tail.bottom = Data()
    fuselage.OpenVSP_values.tail.top.angle = 0.0
    fuselage.OpenVSP_values.tail.top.strength = 0.0

    # CG locations are approximate
    # Masses from http://www.concordesst.com/fuelsys.html
    fuel_tank = SUAVE.Components.Energy.Storages.Fuel_Tanks.Fuel_Tank()
    fuel_tank.tag = 'tank_11'
    fuel_tank.mass_properties.center_of_gravity = np.array([[49.8, 0, 0]])
    fuel_tank.mass_properties.fuel_mass_when_full = 10415
    fuel_tank.fuel_type = SUAVE.Attributes.Propellants.Jet_A()
    fuselage.Fuel_Tanks.append(fuel_tank)

    # add to vehicle
    vehicle.append_component(fuselage)

    # ------------------------------------------------------------------
    # the nacelle
    # ------------------------------------------------------------------
    nacelle = SUAVE.Components.Nacelles.Nacelle()
    nacelle.diameter = 1.3
    nacelle.tag = 'nacelle_L1'
    nacelle.origin = [[36.56, 22, -1.9]]
    nacelle.length = 12.0
    nacelle.inlet_diameter = 1.1
    nacelle.areas.wetted = 30.
    vehicle.append_component(nacelle)

    nacelle_2 = deepcopy(nacelle)
    nacelle_2.tag = 'nacelle_2'
    nacelle_2.origin = [[37., 5.3, -1.3]]
    vehicle.append_component(nacelle_2)

    nacelle_3 = deepcopy(nacelle)
    nacelle_3.tag = 'nacelle_3'
    nacelle_3.origin = [[37., -5.3, -1.3]]
    vehicle.append_component(nacelle_3)

    nacelle_4 = deepcopy(nacelle)
    nacelle_4.tag = 'nacelle_4'
    nacelle_4.origin = [[37., -6., -1.3]]
    vehicle.append_component(nacelle_4)

    # ------------------------------------------------------------------
    #   Turbojet Network
    # ------------------------------------------------------------------

    # instantiate the gas turbine network
    turbojet = SUAVE.Components.Energy.Networks.Turbojet_Super()
    turbojet.tag = 'turbojet'

    # setup
    turbojet.number_of_engines = 4.0
    turbojet.engine_length = 12.0
    turbojet.nacelle_diameter = 1.3
    turbojet.inlet_diameter = 1.1
    turbojet.areas = Data()
    turbojet.areas.wetted = 120. / turbojet.number_of_engines
    turbojet.origin = [[37., 6., -1.3], [37., 5.3, -1.3], [37., -5.3, -1.3],
                       [37., -6., -1.3]]

    # working fluid
    turbojet.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1 - Ram

    # to convert freestream static to stagnation quantities

    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    # add to the network
    turbojet.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'

    # setup
    inlet_nozzle.polytropic_efficiency = 1.0
    inlet_nozzle.pressure_ratio = 1.0
    inlet_nozzle.pressure_recovery = 0.94

    # add to network
    turbojet.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 3 - Low Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'low_pressure_compressor'

    # setup
    compressor.polytropic_efficiency = 0.88
    compressor.pressure_ratio = 3.1

    # add to network
    turbojet.append(compressor)

    # ------------------------------------------------------------------
    #  Component 4 - High Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'high_pressure_compressor'

    # setup
    compressor.polytropic_efficiency = 0.88
    compressor.pressure_ratio = 5.0

    # add to network
    turbojet.append(compressor)

    # ------------------------------------------------------------------
    #  Component 5 - Low Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'low_pressure_turbine'

    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.89

    # add to network
    turbojet.append(turbine)

    # ------------------------------------------------------------------
    #  Component 6 - High Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'high_pressure_turbine'

    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.87

    # add to network
    turbojet.append(turbine)

    # ------------------------------------------------------------------
    #  Component 7 - Combustor

    # instantiate
    combustor = SUAVE.Components.Energy.Converters.Combustor()
    combustor.tag = 'combustor'

    # setup
    combustor.efficiency = 0.94
    combustor.alphac = 1.0
    combustor.turbine_inlet_temperature = 1440.
    combustor.pressure_ratio = 0.92
    combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A()

    # add to network
    turbojet.append(combustor)

    # ------------------------------------------------------------------
    #  Afterburner

    # instantiate
    afterburner = SUAVE.Components.Energy.Converters.Combustor()
    afterburner.tag = 'afterburner'

    # setup
    afterburner.efficiency = 0.9
    afterburner.alphac = 1.0
    afterburner.turbine_inlet_temperature = 1500
    afterburner.pressure_ratio = 1.0
    afterburner.fuel_data = SUAVE.Attributes.Propellants.Jet_A()

    # add to network
    turbojet.append(afterburner)

    # ------------------------------------------------------------------
    #  Component 8 - Core Nozzle

    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Supersonic_Nozzle()
    nozzle.tag = 'core_nozzle'

    # setup
    nozzle.pressure_recovery = 0.95
    nozzle.pressure_ratio = 1.

    # add to network
    turbojet.append(nozzle)

    # ------------------------------------------------------------------
    #Component 10 : thrust (to compute the thrust)
    thrust = SUAVE.Components.Energy.Processes.Thrust()
    thrust.tag = 'compute_thrust'

    #total design thrust (includes all the engines)
    thrust.total_design = 40000. * Units.lbf

    # Note: Sizing builds the network. It does not actually set the size of the turbojet
    #design sizing conditions
    altitude = 60000.0 * Units.ft
    mach_number = 2.02
    isa_deviation = 0.

    # add to network
    turbojet.thrust = thrust

    #size the turbojet
    turbojet_sizing(turbojet, mach_number, altitude)

    # add  gas turbine network gt_engine to the vehicle
    vehicle.append_component(turbojet)

    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle
Пример #2
0
def vsp_read_wing(wing_id, units_type='SI'):
    """This reads an OpenVSP wing vehicle geometry and writes it into a SUAVE wing format.

	Assumptions:
	1. OpenVSP wing is divided into segments ("XSecs" in VSP).
	2. Written for OpenVSP 3.21.1

	Source:
	N/A

	Inputs:
	0. Pre-loaded VSP vehicle in memory, via vsp_read.
	1. VSP 10-digit geom ID for wing.
	2. units_type set to 'SI' (default) or 'Imperial'.

	Outputs:
	Writes SUAVE wing object, with these geometries, from VSP:
		Wings.Wing.    (* is all keys)
			origin                                  [m] in all three dimensions
			spans.projected                         [m]
			chords.root                             [m]
			chords.tip                              [m]
			aspect_ratio                            [-]
			sweeps.quarter_chord                    [radians]
			twists.root                             [radians]
			twists.tip                              [radians]
			thickness_to_chord                      [-]
			dihedral                                [radians]
			symmetric                               <boolean>
			tag                                     <string>
			areas.exposed                           [m^2]
			areas.reference                         [m^2]
			areas.wetted                            [m^2]
			Segments.
			  tag                                   <string>
			  twist                                 [radians]
			  percent_span_location                 [-]  .1 is 10%
			  root_chord_percent                    [-]  .1 is 10%
			  dihedral_outboard                     [radians]
			  sweeps.quarter_chord                  [radians]
			  thickness_to_chord                    [-]
			  airfoil                               <NACA 4-series, 6 series, or airfoil file>

	Properties Used:
	N/A
	"""

    # Check if this is vertical tail, this seems like a weird first step but it's necessary
    # Get the initial rotation to get the dihedral angles
    x_rot = vsp.GetParmVal(wing_id, 'X_Rotation', 'XForm')
    if x_rot >= 70:
        wing = SUAVE.Components.Wings.Vertical_Tail()
        wing.vertical = True
        x_rot = (90 - x_rot) * Units.deg
    else:
        # Instantiate a wing
        wing = SUAVE.Components.Wings.Wing()

    # Set the units
    if units_type == 'SI':
        units_factor = Units.meter * 1.
    else:
        units_factor = Units.foot * 1.

    # Apply a tag to the wing
    if vsp.GetGeomName(wing_id):
        tag = vsp.GetGeomName(wing_id)
        tag = tag.translate(t_table)
        wing.tag = tag
    else:
        wing.tag = 'winggeom'

    # Top level wing parameters
    # Wing origin
    wing.origin[0][0] = vsp.GetParmVal(wing_id, 'X_Location',
                                       'XForm') * units_factor
    wing.origin[0][1] = vsp.GetParmVal(wing_id, 'Y_Location',
                                       'XForm') * units_factor
    wing.origin[0][2] = vsp.GetParmVal(wing_id, 'Z_Location',
                                       'XForm') * units_factor

    # Wing Symmetry
    sym_planar = vsp.GetParmVal(wing_id, 'Sym_Planar_Flag', 'Sym')
    sym_origin = vsp.GetParmVal(wing_id, 'Sym_Ancestor', 'Sym')

    # Check for symmetry
    if sym_planar == 2. and sym_origin == 1.:  #origin at wing, not vehicle
        wing.symmetric = True
    else:
        wing.symmetric = False

    #More top level parameters
    total_proj_span = vsp.GetParmVal(wing_id, 'TotalProjectedSpan',
                                     'WingGeom') * units_factor
    wing.aspect_ratio = vsp.GetParmVal(wing_id, 'TotalAR', 'WingGeom')
    wing.areas.reference = vsp.GetParmVal(wing_id, 'TotalArea',
                                          'WingGeom') * units_factor**2
    wing.spans.projected = total_proj_span

    # Check if this is a single segment wing
    xsec_surf_id = vsp.GetXSecSurf(wing_id,
                                   0)  # This is how VSP stores surfaces.
    x_sec_1 = vsp.GetXSec(xsec_surf_id, 1)
    x_sec_1_span_parm = vsp.GetXSecParm(x_sec_1, 'Span')
    x_sec_1_span = vsp.GetParmVal(x_sec_1_span_parm) * (
        1 + wing.symmetric) * units_factor

    if x_sec_1_span == wing.spans.projected:
        single_seg = True
    else:
        single_seg = False

    segment_num = vsp.GetNumXSec(
        xsec_surf_id
    )  # Get number of wing segments (is one more than the VSP GUI shows).
    x_sec = vsp.GetXSec(xsec_surf_id, 0)
    chord_parm = vsp.GetXSecParm(x_sec, 'Root_Chord')

    total_chord = vsp.GetParmVal(chord_parm)

    span_sum = 0.  # Non-projected.
    proj_span_sum = 0.  # Projected.
    segment_spans = [None] * (segment_num)  # Non-projected.
    segment_dihedral = [None] * (segment_num)
    segment_sweeps_quarter_chord = [None] * (segment_num)

    # Check for wing segment *inside* fuselage, then skip XSec_0 to start at first exposed segment.
    if total_chord == 1.:
        start = 1
        xsec_surf_id = vsp.GetXSecSurf(wing_id, 1)
        x_sec = vsp.GetXSec(xsec_surf_id, 0)
        chord_parm = vsp.GetXSecParm(x_sec, 'Tip_Chord')
        root_chord = vsp.GetParmVal(chord_parm) * units_factor
    else:
        start = 0
        root_chord = total_chord * units_factor

    # -------------
    # Wing segments
    # -------------

    if single_seg == False:

        # Convert VSP XSecs to SUAVE segments. (Wing segments are defined by outboard sections in VSP, but inboard sections in SUAVE.)
        for i in range(start, segment_num + 1):
            segment = SUAVE.Components.Wings.Segment()
            segment.tag = 'Section_' + str(i)
            thick_cord = vsp.GetParmVal(wing_id, 'ThickChord',
                                        'XSecCurve_' + str(i - 1))
            segment.thickness_to_chord = thick_cord  # Thick_cord stored for use in airfoil, below.
            segment_root_chord = vsp.GetParmVal(
                wing_id, 'Root_Chord', 'XSec_' + str(i)) * units_factor
            segment.root_chord_percent = segment_root_chord / root_chord
            segment.percent_span_location = proj_span_sum / (total_proj_span /
                                                             2)
            segment.twist = vsp.GetParmVal(wing_id, 'Twist',
                                           'XSec_' + str(i - 1)) * Units.deg

            if i == start:
                wing.thickness_to_chord = thick_cord

            if i < segment_num:  # This excludes the tip xsec, but we need a segment in SUAVE to store airfoil.
                sweep = vsp.GetParmVal(wing_id, 'Sweep',
                                       'XSec_' + str(i)) * Units.deg
                sweep_loc = vsp.GetParmVal(wing_id, 'Sweep_Location',
                                           'XSec_' + str(i))
                AR = vsp.GetParmVal(wing_id, 'Aspect', 'XSec_' + str(i))
                taper = vsp.GetParmVal(wing_id, 'Taper', 'XSec_' + str(i))

                segment_sweeps_quarter_chord[i] = convert_sweep(
                    sweep, sweep_loc, 0.25, AR, taper)
                segment.sweeps.quarter_chord = segment_sweeps_quarter_chord[
                    i]  # Used again, below

                # Used for dihedral computation, below.
                segment_dihedral[i] = vsp.GetParmVal(
                    wing_id, 'Dihedral', 'XSec_' + str(i)) * Units.deg + x_rot
                segment.dihedral_outboard = segment_dihedral[i]

                segment_spans[i] = vsp.GetParmVal(
                    wing_id, 'Span', 'XSec_' + str(i)) * units_factor
                proj_span_sum += segment_spans[i] * np.cos(segment_dihedral[i])
                span_sum += segment_spans[i]
            else:
                segment.root_chord_percent = (vsp.GetParmVal(
                    wing_id, 'Tip_Chord',
                    'XSec_' + str(i - 1))) * units_factor / total_chord

            # XSec airfoil
            jj = i - 1  # Airfoil index i-1 because VSP airfoils and sections are one index off relative to SUAVE.
            xsec_id = str(vsp.GetXSec(xsec_surf_id, jj))
            airfoil = Airfoil()
            if vsp.GetXSecShape(
                    xsec_id
            ) == vsp.XS_FOUR_SERIES:  # XSec shape: NACA 4-series
                camber = vsp.GetParmVal(wing_id, 'Camber',
                                        'XSecCurve_' + str(jj))

                if camber == 0.:
                    camber_loc = 0.
                else:
                    camber_loc = vsp.GetParmVal(wing_id, 'CamberLoc',
                                                'XSecCurve_' + str(jj))

                airfoil.thickness_to_chord = thick_cord
                camber_round = int(np.around(camber * 100))
                camber_loc_round = int(np.around(camber_loc * 10))
                thick_cord_round = int(np.around(thick_cord * 100))
                airfoil.tag = 'NACA ' + str(camber_round) + str(
                    camber_loc_round) + str(thick_cord_round)

            elif vsp.GetXSecShape(
                    xsec_id) == vsp.XS_SIX_SERIES:  # XSec shape: NACA 6-series
                thick_cord_round = int(np.around(thick_cord * 100))
                a_value = vsp.GetParmVal(wing_id, 'A', 'XSecCurve_' + str(jj))
                ideal_CL = int(
                    np.around(
                        vsp.GetParmVal(wing_id, 'IdealCl',
                                       'XSecCurve_' + str(jj)) * 10))
                series_vsp = int(
                    vsp.GetParmVal(wing_id, 'Series', 'XSecCurve_' + str(jj)))
                series_dict = {
                    0: '63',
                    1: '64',
                    2: '65',
                    3: '66',
                    4: '67',
                    5: '63A',
                    6: '64A',
                    7: '65A'
                }  # VSP series values.
                series = series_dict[series_vsp]
                airfoil.tag = 'NACA ' + series + str(ideal_CL) + str(
                    thick_cord_round) + ' a=' + str(np.around(a_value, 1))

            elif vsp.GetXSecShape(
                    xsec_id
            ) == vsp.XS_FILE_AIRFOIL:  # XSec shape: 12 is type AF_FILE
                airfoil.thickness_to_chord = thick_cord
                airfoil.points = vsp.GetAirfoilCoordinates(
                    wing_id, float(jj / segment_num))
                # VSP airfoil API calls get coordinates and write files with the final argument being the fraction of segment position, regardless of relative spans.
                # (Write the root airfoil with final arg = 0. Write 4th airfoil of 5 segments with final arg = .8)
                vsp.WriteSeligAirfoil(
                    str(wing.tag) + '_airfoil_XSec_' + str(jj) + '.dat',
                    wing_id, float(jj / segment_num))
                airfoil.coordinate_file = 'str(wing.tag)' + '_airfoil_XSec_' + str(
                    jj) + '.dat'
                airfoil.tag = 'AF_file'

                segment.append_airfoil(airfoil)

            wing.Segments.append(segment)

        # Wing dihedral
        proj_span_sum_alt = 0.
        span_sum_alt = 0.
        sweeps_sum = 0.

        for ii in range(start, segment_num):
            span_sum_alt += segment_spans[ii]
            proj_span_sum_alt += segment_spans[ii] * np.cos(
                segment_dihedral[ii]
            )  # Use projected span to find total wing dihedral.
            sweeps_sum += segment_spans[ii] * np.tan(
                segment_sweeps_quarter_chord[ii])

        wing.dihedral = np.arccos(proj_span_sum_alt / span_sum_alt)
        wing.sweeps.quarter_chord = -np.arctan(
            sweeps_sum / span_sum_alt)  # Minus sign makes it positive sweep.

        # Add a tip segment, all values are zero except the tip chord
        tc = vsp.GetParmVal(wing_id, 'Tip_Chord',
                            'XSec_' + str(segment_num - 1)) * units_factor
        segment = SUAVE.Components.Wings.Segment()
        segment.percent_span_location = 1.0
        segment.root_chord_percent = tc / root_chord

        # Chords
        wing.chords.root = vsp.GetParmVal(wing_id, 'Tip_Chord',
                                          'XSec_0') * units_factor
        wing.chords.tip = tc
        wing.chords.mean_geometric = wing.areas.reference / wing.spans.projected

        # Just double calculate and fix things:
        wing = wing_segmented_planform(wing)

    else:
        # Single segment

        # Get ID's
        x_sec_1_dih_parm = vsp.GetXSecParm(x_sec_1, 'Dihedral')
        x_sec_1_sweep_parm = vsp.GetXSecParm(x_sec_1, 'Sweep')
        x_sec_1_sweep_loc_parm = vsp.GetXSecParm(x_sec_1, 'Sweep_Location')
        x_sec_1_taper_parm = vsp.GetXSecParm(x_sec_1, 'Taper')
        x_sec_1_rc_parm = vsp.GetXSecParm(x_sec_1, 'Root_Chord')
        x_sec_1_tc_parm = vsp.GetXSecParm(x_sec_1, 'Tip_Chord')

        # Calcs
        sweep = vsp.GetParmVal(x_sec_1_sweep_parm) * Units.deg
        sweep_loc = vsp.GetParmVal(x_sec_1_sweep_loc_parm)
        taper = vsp.GetParmVal(x_sec_1_taper_parm)
        c_4_sweep = convert_sweep(sweep, sweep_loc, 0.25, wing.aspect_ratio,
                                  taper)

        # Pull and pack
        wing.sweeps.quarter_chord = c_4_sweep
        wing.taper = taper
        wing.dihedral = vsp.GetParmVal(x_sec_1_dih_parm) * Units.deg + x_rot
        wing.chords.root = vsp.GetParmVal(x_sec_1_rc_parm) * units_factor
        wing.chords.tip = vsp.GetParmVal(x_sec_1_tc_parm) * units_factor
        wing.chords.mean_geometric = wing.areas.reference / wing.spans.projected

        # Just double calculate and fix things:
        wing = wing_planform(wing)

    # Twists
    wing.twists.root = vsp.GetParmVal(wing_id, 'Twist', 'XSec_0') * Units.deg
    wing.twists.tip = vsp.GetParmVal(
        wing_id, 'Twist', 'XSec_' + str(segment_num - 1)) * Units.deg

    return wing
Пример #3
0
def vehicle_setup():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------
    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'Lift_Cruise_CRM'
    vehicle.configuration = 'eVTOL'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------
    # mass properties
    vehicle.mass_properties.takeoff = 2450. * Units.lb
    vehicle.mass_properties.operating_empty = 2250. * Units.lb  # Approximate
    vehicle.mass_properties.max_takeoff = 2450. * Units.lb  # Approximate
    vehicle.mass_properties.max_payload = 200. * Units.lb
    vehicle.mass_properties.center_of_gravity = [[2.0144, 0.,
                                                  0.]]  # Approximate

    # basic parameters
    vehicle.reference_area = 10.76
    vehicle.envelope.ultimate_load = 5.7
    vehicle.envelope.limit_load = 3.

    # ------------------------------------------------------------------
    # WINGS
    # ------------------------------------------------------------------
    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'
    wing.aspect_ratio = 10.76
    wing.sweeps.quarter_chord = 0.0 * Units.degrees
    wing.thickness_to_chord = 0.18
    wing.taper = 1.
    wing.spans.projected = 35.0 * Units.feet
    wing.chords.root = 3.25 * Units.feet
    wing.total_length = 3.25 * Units.feet
    wing.chords.tip = 3.25 * Units.feet
    wing.chords.mean_aerodynamic = 3.25 * Units.feet
    wing.dihedral = 1.0 * Units.degrees
    wing.areas.reference = 113.75 * Units.feet**2
    wing.areas.wetted = 227.5 * Units.feet**2
    wing.areas.exposed = 227.5 * Units.feet**2
    wing.twists.root = 4.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[1.5, 0., 0.]]
    wing.aerodynamic_center = [1.975, 0., 0.]
    wing.winglet_fraction = 0.0
    wing.symmetric = True
    wing.vertical = False

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Section_1'
    segment.percent_span_location = 0.
    segment.twist = 0.
    segment.root_chord_percent = 1.5
    segment.dihedral_outboard = 1.0 * Units.degrees
    segment.sweeps.quarter_chord = 8.5 * Units.degrees
    segment.thickness_to_chord = 0.18
    wing.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Section_2'
    segment.percent_span_location = 0.227
    segment.twist = 0.
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 1.0 * Units.degrees
    segment.sweeps.quarter_chord = 0.0 * Units.degrees
    segment.thickness_to_chord = 0.12
    wing.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Section_3'
    segment.percent_span_location = 1.0
    segment.twist = 0.
    segment.root_chord_percent = 1.0
    segment.dihedral_outboard = 1.0 * Units.degrees
    segment.sweeps.quarter_chord = 0.0 * Units.degrees
    segment.thickness_to_chord = 0.12
    wing.Segments.append(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'horizontal_tail'
    wing.aspect_ratio = 4.0
    wing.sweeps.quarter_chord = 0.0
    wing.thickness_to_chord = 0.12
    wing.taper = 1.0
    wing.spans.projected = 8.0 * Units.feet
    wing.chords.root = 2.0 * Units.feet
    wing.total_length = 2.0 * Units.feet
    wing.chords.tip = 2.0 * Units.feet
    wing.chords.mean_aerodynamic = 2.0 * Units.feet
    wing.dihedral = 0. * Units.degrees
    wing.areas.reference = 16.0 * Units.feet**2
    wing.areas.wetted = 32.0 * Units.feet**2
    wing.areas.exposed = 32.0 * Units.feet**2
    wing.twists.root = 0. * Units.degrees
    wing.twists.tip = 0. * Units.degrees
    wing.origin = [[4.0, 0.0, 0.205]]
    wing.aerodynamic_center = [4.2, 0., 0.]
    wing.symmetric = True

    # add to vehicle
    vehicle.append_component(wing)

    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'vertical_tail_1'
    wing.aspect_ratio = 2.
    wing.sweeps.quarter_chord = 20.0 * Units.degrees
    wing.thickness_to_chord = 0.12
    wing.taper = 0.5
    wing.spans.projected = 3.0 * Units.feet
    wing.chords.root = 2.0 * Units.feet
    wing.total_length = 2.0 * Units.feet
    wing.chords.tip = 1.0 * Units.feet
    wing.chords.mean_aerodynamic = 1.5 * Units.feet
    wing.areas.reference = 4.5 * Units.feet**2
    wing.areas.wetted = 9.0 * Units.feet**2
    wing.areas.exposed = 9.0 * Units.feet**2
    wing.twists.root = 0. * Units.degrees
    wing.twists.tip = 0. * Units.degrees
    wing.origin = [[4.0, 4.0 * 0.3048, 0.205]]
    wing.aerodynamic_center = [4.2, 0, 0]
    wing.winglet_fraction = 0.0
    wing.vertical = True
    wing.symmetric = False

    # add to vehicle
    vehicle.append_component(wing)

    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'vertical_tail_2'
    wing.aspect_ratio = 2.
    wing.sweeps.quarter_chord = 20.0 * Units.degrees
    wing.thickness_to_chord = 0.12
    wing.taper = 0.5
    wing.spans.projected = 3.0 * Units.feet
    wing.chords.root = 2.0 * Units.feet
    wing.total_length = 2.0 * Units.feet
    wing.chords.tip = 1.0 * Units.feet
    wing.chords.mean_aerodynamic = 1.5 * Units.feet
    wing.areas.reference = 4.5 * Units.feet**2
    wing.areas.wetted = 9.0 * Units.feet**2
    wing.areas.exposed = 9.0 * Units.feet**2
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[4.0, -4.0 * 0.3048, 0.205]]
    wing.aerodynamic_center = [4.2, 0, 0]
    wing.winglet_fraction = 0.0
    wing.vertical = True
    wing.symmetric = False

    # add to vehicle
    vehicle.append_component(wing)

    # ---------------------------------------------------------------
    # FUSELAGE
    # ---------------------------------------------------------------
    # FUSELAGE PROPERTIES
    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'
    fuselage.configuration = 'Tube_Wing'
    fuselage.seats_abreast = 2.
    fuselage.seat_pitch = 3.
    fuselage.fineness.nose = 0.88
    fuselage.fineness.tail = 1.13
    fuselage.lengths.nose = 3.2 * Units.feet
    fuselage.lengths.tail = 6.4 * Units.feet
    fuselage.lengths.cabin = 6.4 * Units.feet
    fuselage.lengths.total = 5.1
    fuselage.width = 5.85 * Units.feet
    fuselage.heights.maximum = 4.65 * Units.feet
    fuselage.heights.at_quarter_length = 3.75 * Units.feet
    fuselage.heights.at_wing_root_quarter_chord = 4.65 * Units.feet
    fuselage.heights.at_three_quarters_length = 4.26 * Units.feet
    fuselage.areas.wetted = 236. * Units.feet**2
    fuselage.areas.front_projected = 0.14 * Units.feet**2
    fuselage.effective_diameter = 5.85 * Units.feet
    fuselage.differential_pressure = 0.

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_0'
    segment.percent_x_location = 0.
    segment.percent_z_location = -0.267 / 4.10534
    segment.height = 0.1
    segment.width = 0.1
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.2579 / 4.10534
    segment.percent_z_location = -0.05881 / 1.372
    segment.height = 0.5201
    segment.width = 0.75
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.9939 / 4.10534
    segment.percent_z_location = -0.0446 / 4.10534
    segment.height = 1.18940
    segment.width = 1.42045
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 1.95060 / 4.10534
    segment.percent_z_location = 0
    segment.height = 1.37248
    segment.width = 1.35312
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 3.02797 / 4.10534
    segment.percent_z_location = 0.25 / 4.10534
    segment.height = 0.6
    segment.width = 0.4
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_5'
    segment.percent_x_location = 1.
    segment.percent_z_location = 0.42522 / 4.10534
    segment.height = 0.05
    segment.width = 0.05
    fuselage.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(fuselage)

    #-------------------------------------------------------------------
    # INNER BOOMS
    #-------------------------------------------------------------------
    long_boom = SUAVE.Components.Fuselages.Fuselage()
    long_boom.tag = 'boom_1r'
    long_boom.configuration = 'boom'
    long_boom.origin = [[0.543, 1.630, -0.326]]
    long_boom.seats_abreast = 0.
    long_boom.seat_pitch = 0.0
    long_boom.fineness.nose = 0.950
    long_boom.fineness.tail = 1.029
    long_boom.lengths.nose = 0.2
    long_boom.lengths.tail = 0.2
    long_boom.lengths.cabin = 2.5
    long_boom.lengths.total = 3.5
    long_boom.width = 0.15
    long_boom.heights.maximum = 0.15
    long_boom.heights.at_quarter_length = 0.15
    long_boom.heights.at_three_quarters_length = 0.15
    long_boom.heights.at_wing_root_quarter_chord = 0.15
    long_boom.areas.wetted = 0.018
    long_boom.areas.front_projected = 0.018
    long_boom.effective_diameter = 0.15
    long_boom.differential_pressure = 0.
    long_boom.symmetric = True
    long_boom.index = 1

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.
    segment.percent_z_location = 0.0
    segment.height = 0.05
    segment.width = 0.05
    long_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.2 / 5.6
    segment.percent_z_location = 0.
    segment.height = 0.15
    segment.width = 0.15
    long_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 5.4 / 5.6
    segment.percent_z_location = 0.
    segment.height = 0.15
    segment.width = 0.15
    long_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 1.
    segment.percent_z_location = 0.
    segment.height = 0.05
    segment.width = 0.05
    long_boom.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(long_boom)

    # add left long boom
    long_boom = deepcopy(vehicle.fuselages.boom_1r)
    long_boom.origin[0][1] = -long_boom.origin[0][1]
    long_boom.tag = 'Boom_1L'
    long_boom.index = 1
    vehicle.append_component(long_boom)

    #-------------------------------------------------------------------
    # OUTER BOOMS
    #-------------------------------------------------------------------
    short_boom = SUAVE.Components.Fuselages.Fuselage()
    short_boom.tag = 'boom_2r'
    short_boom.configuration = 'boom'
    short_boom.origin = [[0.543, 2.826, -0.326]]
    short_boom.seats_abreast = 0.
    short_boom.seat_pitch = 0.0
    short_boom.fineness.nose = 0.950
    short_boom.fineness.tail = 1.029
    short_boom.lengths.nose = 0.2
    short_boom.lengths.tail = 0.2
    short_boom.lengths.cabin = 2.0
    short_boom.lengths.total = 3.3
    short_boom.width = 0.15
    short_boom.heights.maximum = 0.15
    short_boom.heights.at_quarter_length = 0.15
    short_boom.heights.at_three_quarters_length = 0.15
    short_boom.heights.at_wing_root_quarter_chord = 0.15
    short_boom.areas.wetted = 0.018
    short_boom.areas.front_projected = 0.018
    short_boom.effective_diameter = 0.15
    short_boom.differential_pressure = 0.
    short_boom.y_pitch_count = 2
    short_boom.y_pitch = 1.196
    short_boom.symmetric = True
    short_boom.index = 1

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.
    segment.percent_z_location = 0.0
    segment.height = 0.05
    segment.width = 0.05
    short_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.2 / 3.3
    segment.percent_z_location = 0.
    segment.height = 0.15
    segment.width = 0.15
    short_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 3.1 / 3.3
    segment.percent_z_location = 0.
    segment.height = 0.15
    segment.width = 0.15
    short_boom.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 1.
    segment.percent_z_location = 0.
    segment.height = 0.05
    segment.width = 0.05
    short_boom.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(short_boom)

    # add outer right boom
    short_boom = deepcopy(vehicle.fuselages.boom_2r)
    short_boom.origin[0][1] = short_boom.y_pitch + short_boom.origin[0][1]
    short_boom.tag = 'boom_3r'
    short_boom.index = 1
    vehicle.append_component(short_boom)

    # add inner left boom
    short_boom = deepcopy(vehicle.fuselages.boom_2r)
    short_boom.origin[0][1] = -(short_boom.origin[0][1])
    short_boom.tag = 'boom_2l'
    short_boom.index = 1
    vehicle.append_component(short_boom)

    short_boom = deepcopy(vehicle.fuselages.boom_2r)
    short_boom.origin[0][1] = -(short_boom.origin[0][1] + short_boom.y_pitch)
    short_boom.tag = 'boom_3l'
    short_boom.index = 1
    vehicle.append_component(short_boom)

    #------------------------------------------------------------------
    # Nacelles
    #------------------------------------------------------------------
    rotor_nacelle = SUAVE.Components.Nacelles.Nacelle()
    rotor_nacelle.tag = 'rotor_nacelle'
    rotor_nacelle_origins = [[0.543, 1.63, -0.126], [0.543, -1.63, -0.126],
                             [3.843, 1.63, -0.126], [3.843, -1.63, -0.126],
                             [0.543, 2.826, -0.126], [0.543, -2.826, -0.126],
                             [3.843, 2.826, -0.126], [3.843, -2.826, -0.126],
                             [0.543, 4.022, -0.126], [0.543, -4.022, -0.126],
                             [3.843, 4.022, -0.126], [3.843, -4.022, -0.126]]
    rotor_nacelle.length = 0.25
    rotor_nacelle.diameter = 0.25
    rotor_nacelle.orientation_euler_angles = [0, -90 * Units.degrees, 0.]
    rotor_nacelle.flow_through = False

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_1'
    nac_segment.percent_x_location = 0.0
    nac_segment.height = 0.2
    nac_segment.width = 0.2
    rotor_nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_2'
    nac_segment.percent_x_location = 0.25
    nac_segment.height = 0.25
    nac_segment.width = 0.25
    rotor_nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_3'
    nac_segment.percent_x_location = 0.5
    nac_segment.height = 0.3
    nac_segment.width = 0.3
    rotor_nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_4'
    nac_segment.percent_x_location = 0.75
    nac_segment.height = 0.25
    nac_segment.width = 0.25
    rotor_nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_5'
    nac_segment.percent_x_location = 1.0
    nac_segment.height = 0.2
    nac_segment.width = 0.2
    rotor_nacelle.append_segment(nac_segment)

    rotor_nacelle.areas.wetted = np.pi * rotor_nacelle.diameter * rotor_nacelle.length + 0.5 * np.pi * rotor_nacelle.diameter**2

    for idx in range(12):
        nacelle = deepcopy(rotor_nacelle)
        nacelle.tag = 'nacelle_' + str(idx)
        nacelle.origin = [rotor_nacelle_origins[idx]]
        vehicle.append_component(nacelle)

    #------------------------------------------------------------------
    # network
    #------------------------------------------------------------------
    net = Lift_Cruise()
    net.number_of_lift_rotor_engines = 12
    net.number_of_propeller_engines = 1
    net.nacelle_diameter = 0.6 * Units.feet
    net.engine_length = 0.5 * Units.feet
    net.areas = Data()
    net.areas.wetted = np.pi * net.nacelle_diameter * net.engine_length + 0.5 * np.pi * net.nacelle_diameter**2
    net.voltage = 500.

    #------------------------------------------------------------------
    # Design Electronic Speed Controller
    #------------------------------------------------------------------
    lift_rotor_esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller(
    )
    lift_rotor_esc.efficiency = 0.95
    net.lift_rotor_esc = lift_rotor_esc

    propeller_esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller(
    )
    propeller_esc.efficiency = 0.95
    net.propeller_esc = propeller_esc

    #------------------------------------------------------------------
    # Design Payload
    #------------------------------------------------------------------
    payload = SUAVE.Components.Energy.Peripherals.Avionics()
    payload.power_draw = 0.
    payload.mass_properties.mass = 200. * Units.kg
    net.payload = payload

    #------------------------------------------------------------------
    # Design Avionics
    #------------------------------------------------------------------
    avionics = SUAVE.Components.Energy.Peripherals.Avionics()
    avionics.power_draw = 200. * Units.watts
    net.avionics = avionics

    #------------------------------------------------------------------
    # Design Battery
    #------------------------------------------------------------------
    bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion_LiNiMnCoO2_18650(
    )
    bat.mass_properties.mass = 500. * Units.kg
    bat.max_voltage = net.voltage
    initialize_from_mass(bat)

    # Here we, are going to assume a battery pack module shape. This step is optional but
    # required for thermal analysis of tge pack
    number_of_modules = 10
    bat.module_config.total = int(
        np.ceil(bat.pack_config.total / number_of_modules))
    bat.module_config.normal_count = int(
        np.ceil(bat.module_config.total / bat.pack_config.series))
    bat.module_config.parallel_count = int(
        np.ceil(bat.module_config.total / bat.pack_config.parallel))
    net.battery = bat

    #------------------------------------------------------------------
    # Design Rotors and Propellers
    #------------------------------------------------------------------
    # atmosphere and flight conditions for propeller/rotor design
    g = 9.81  # gravitational acceleration
    S = vehicle.reference_area  # reference area
    speed_of_sound = 340  # speed of sound
    rho = 1.22  # reference density
    fligth_CL = 0.75  # cruise target lift coefficient
    AR = vehicle.wings.main_wing.aspect_ratio  # aspect ratio
    Cd0 = 0.06  # profile drag
    Cdi = fligth_CL**2 / (np.pi * AR * 0.98)  # induced drag
    Cd = Cd0 + Cdi  # total drag
    V_inf = 110. * Units['mph']  # freestream velocity
    Drag = S * (0.5 * rho * V_inf**2) * Cd  # cruise drag
    Hover_Load = vehicle.mass_properties.takeoff * g  # hover load
    net.identical_propellers = True
    net.identical_lift_rotors = True

    # Thrust Propeller
    propeller = SUAVE.Components.Energy.Converters.Propeller()
    propeller.number_of_blades = 3
    propeller.freestream_velocity = V_inf
    propeller.tip_radius = 1.0668
    propeller.hub_radius = 0.21336
    propeller.design_tip_mach = 0.5
    propeller.angular_velocity = propeller.design_tip_mach * speed_of_sound / propeller.tip_radius
    propeller.design_Cl = 0.7
    propeller.design_altitude = 1000 * Units.feet
    propeller.design_thrust = (Drag * 2.5) / net.number_of_propeller_engines
    propeller.variable_pitch = True

    propeller.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt']
    propeller.airfoil_polars = [[
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_50000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_100000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_200000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_500000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_1000000.txt'
    ]]

    propeller.airfoil_polar_stations = [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ]
    propeller = propeller_design(propeller,
                                 number_of_airfoil_section_points=50)
    propeller.origin = [[16. * 0.3048, 0., 2.02 * 0.3048]]
    net.propellers.append(propeller)

    # Lift Rotors
    lift_rotor = SUAVE.Components.Energy.Converters.Lift_Rotor()
    lift_rotor.tip_radius = 2.8 * Units.feet
    lift_rotor.hub_radius = 0.35 * Units.feet
    lift_rotor.number_of_blades = 2
    lift_rotor.design_tip_mach = 0.65
    lift_rotor.disc_area = np.pi * (lift_rotor.tip_radius**2)
    lift_rotor.freestream_velocity = 500. * Units['ft/min']
    lift_rotor.angular_velocity = lift_rotor.design_tip_mach * speed_of_sound / lift_rotor.tip_radius
    lift_rotor.design_Cl = 0.7
    lift_rotor.design_altitude = 20 * Units.feet
    lift_rotor.design_thrust = Hover_Load / (
        net.number_of_lift_rotor_engines - 1
    )  # contingency for one-engine-inoperative condition
    lift_rotor.variable_pitch = True

    lift_rotor.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt']
    lift_rotor.airfoil_polars = [[
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_50000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_100000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_200000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_500000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_1000000.txt'
    ]]

    lift_rotor.airfoil_polar_stations = [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ]
    lift_rotor = propeller_design(lift_rotor)

    # Appending rotors with different origins
    rotations = [1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1]
    origins = [[0.543, 1.63, -0.126], [0.543, -1.63, -0.126],
               [3.843, 1.63, -0.126], [3.843, -1.63, -0.126],
               [0.543, 2.826, -0.126], [0.543, -2.826, -0.126],
               [3.843, 2.826, -0.126], [3.843, -2.826, -0.126],
               [0.543, 4.022, -0.126], [0.543, -4.022, -0.126],
               [3.843, 4.022, -0.126], [3.843, -4.022, -0.126]]

    for ii in range(12):
        lift_rotor = deepcopy(lift_rotor)
        lift_rotor.tag = 'lift_rotor'
        lift_rotor.rotation = rotations[ii]
        lift_rotor.origin = [origins[ii]]
        net.lift_rotors.append(lift_rotor)

    net.number_of_lift_rotor_engines = 12

    # append propellers to vehicle
    net.lift_rotor = lift_rotor

    #------------------------------------------------------------------
    # Design Motors
    #------------------------------------------------------------------
    # Propeller (Thrust) motor
    propeller_motor = SUAVE.Components.Energy.Converters.Motor()
    propeller_motor.efficiency = 0.95
    propeller_motor.nominal_voltage = bat.max_voltage
    propeller_motor.mass_properties.mass = 2.0 * Units.kg
    propeller_motor.origin = propeller.origin
    propeller_motor.propeller_radius = propeller.tip_radius
    propeller_motor.no_load_current = 2.0
    propeller_motor = size_optimal_motor(propeller_motor, propeller)
    net.propeller_motors.append(propeller_motor)

    # Rotor (Lift) Motor
    lift_rotor_motor = SUAVE.Components.Energy.Converters.Motor()
    lift_rotor_motor.efficiency = 0.85
    lift_rotor_motor.nominal_voltage = bat.max_voltage * 3 / 4
    lift_rotor_motor.mass_properties.mass = 3. * Units.kg
    lift_rotor_motor.origin = lift_rotor.origin
    lift_rotor_motor.propeller_radius = lift_rotor.tip_radius
    lift_rotor_motor.gearbox_efficiency = 1.0
    lift_rotor_motor.no_load_current = 4.0
    lift_rotor_motor = size_optimal_motor(lift_rotor_motor, lift_rotor)

    # Appending motors with different origins
    for _ in range(12):
        lift_rotor_motor = deepcopy(lift_rotor_motor)
        lift_rotor_motor.tag = 'motor'
        net.lift_rotor_motors.append(lift_rotor_motor)

    # append motor origin spanwise locations onto wing data structure
    vehicle.append_component(net)

    # Add extra drag sources from motors, props, and landing gear. All of these hand measured
    motor_height = .25 * Units.feet
    motor_width = 1.6 * Units.feet
    propeller_width = 1. * Units.inches
    propeller_height = propeller_width * .12
    main_gear_width = 1.5 * Units.inches
    main_gear_length = 2.5 * Units.feet
    nose_gear_width = 2. * Units.inches
    nose_gear_length = 2. * Units.feet
    nose_tire_height = (0.7 + 0.4) * Units.feet
    nose_tire_width = 0.4 * Units.feet
    main_tire_height = (0.75 + 0.5) * Units.feet
    main_tire_width = 4. * Units.inches
    total_excrescence_area_spin      = 12.*motor_height*motor_width + 2.*main_gear_length*main_gear_width \
        + nose_gear_width*nose_gear_length + 2*main_tire_height*main_tire_width\
        + nose_tire_height*nose_tire_width
    total_excrescence_area_no_spin = total_excrescence_area_spin + 12 * propeller_height * propeller_width
    vehicle.excrescence_area_no_spin = total_excrescence_area_no_spin
    vehicle.excrescence_area_spin = total_excrescence_area_spin

    vehicle.wings['main_wing'].motor_spanwise_locations = np.multiply(
        2. / 36.25, [
            -5.435, -5.435, -9.891, -9.891, -14.157, -14.157, 5.435, 5.435,
            9.891, 9.891, 14.157, 14.157
        ])

    vehicle.wings['main_wing'].winglet_fraction = 0.0
    vehicle.wings['main_wing'].thickness_to_chord = 0.18
    vehicle.wings['main_wing'].chords.mean_aerodynamic = 0.9644599977664836

    vehicle.weight_breakdown = empty(vehicle)
    compute_component_centers_of_gravity(vehicle)
    vehicle.center_of_gravity()

    return vehicle
def setup_vehicle():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

    # Create a vehicle and set level properties
    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'eVTOL'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------
    # mass properties
    vehicle.mass_properties.takeoff = 2500. * Units.lb
    vehicle.mass_properties.operating_empty = 2150. * Units.lb
    vehicle.mass_properties.max_takeoff = 2500. * Units.lb
    vehicle.mass_properties.max_payload = 100. * Units.lb
    vehicle.mass_properties.center_of_gravity = [[2.0, 0.,
                                                  0.]]  # I made this up

    # basic parameters
    vehicle.envelope.ultimate_load = 5.7
    vehicle.envelope.limit_load = 3.

    # ------------------------------------------------------------------
    # WINGS
    # ------------------------------------------------------------------
    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'
    wing.origin = [[1.5, 0., -0.5]]
    wing.spans.projected = 35.0 * Units.feet
    wing.chords.root = 3.25 * Units.feet

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Root'
    segment.percent_span_location = 0.
    segment.twist = 0.
    segment.root_chord_percent = 1.5
    segment.dihedral_outboard = 1.0 * Units.degrees
    segment.sweeps.quarter_chord = 8.5 * Units.degrees
    segment.thickness_to_chord = 0.18
    wing.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Section_2'
    segment.percent_span_location = 0.227
    segment.twist = 0.
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 1.0 * Units.degrees
    segment.sweeps.quarter_chord = 0.0 * Units.degrees
    segment.thickness_to_chord = 0.12
    wing.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Tip'
    segment.percent_span_location = 1.0
    segment.twist = 0.
    segment.root_chord_percent = 1.0
    segment.dihedral_outboard = 0.0 * Units.degrees
    segment.sweeps.quarter_chord = 0.0 * Units.degrees
    segment.thickness_to_chord = 0.12
    wing.Segments.append(segment)

    # Fill out more segment properties automatically
    wing = segment_properties(wing)
    wing = wing_segmented_planform(wing)

    ## ALSO SET THE VEHICLE REFERENCE AREA
    vehicle.reference_area = wing.areas.reference

    # add to vehicle
    vehicle.append_component(wing)

    # Add a horizontal tail
    # WING PROPERTIES
    wing = SUAVE.Components.Wings.Horizontal_Tail()
    wing.tag = 'horizontal_tail'
    wing.areas.reference = 2.0
    wing.taper = 0.5
    wing.sweeps.quarter_chord = 20. * Units.degrees
    wing.aspect_ratio = 5.0
    wing.thickness_to_chord = 0.12
    wing.dihedral = 5. * Units.degrees
    wing.origin = [[5.5, 0.0, 0.65]]

    # Fill out more segment properties automatically
    wing = wing_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # Add a vertical tail
    wing = SUAVE.Components.Wings.Vertical_Tail()
    wing.tag = 'vertical_tail'
    wing.areas.reference = 1.0
    wing.taper = 0.5
    wing.sweeps.quarter_chord = 30 * Units.degrees
    wing.aspect_ratio = 2.5
    wing.thickness_to_chord = 0.12
    wing.origin = [[5.5, 0.0, 0.65]]

    # Fill out more segment properties automatically
    wing = wing_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # Add a fuseelage

    # ---------------------------------------------------------------
    # FUSELAGE
    # ---------------------------------------------------------------
    # FUSELAGE PROPERTIES
    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'
    fuselage.seats_abreast = 2.
    fuselage.fineness.nose = 0.88
    fuselage.fineness.tail = 1.13
    fuselage.lengths.nose = 3.2 * Units.feet
    fuselage.lengths.tail = 6.4 * Units.feet
    fuselage.lengths.cabin = 6.4 * Units.feet
    fuselage.lengths.total = 6.0
    fuselage.width = 5.85 * Units.feet
    fuselage.heights.maximum = 4.65 * Units.feet
    fuselage.heights.at_quarter_length = 3.75 * Units.feet
    fuselage.heights.at_wing_root_quarter_chord = 4.65 * Units.feet
    fuselage.heights.at_three_quarters_length = 4.26 * Units.feet
    fuselage.areas.wetted = 236. * Units.feet**2
    fuselage.areas.front_projected = 0.14 * Units.feet**2
    fuselage.effective_diameter = 5.85 * Units.feet
    fuselage.differential_pressure = 0.

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_0'
    segment.percent_x_location = 0.
    segment.percent_z_location = -0.05
    segment.height = 0.1
    segment.width = 0.1
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.06
    segment.percent_z_location = -0.05
    segment.height = 0.52
    segment.width = 0.75
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.25
    segment.percent_z_location = -.01
    segment.height = 1.2
    segment.width = 1.43
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 0.475
    segment.percent_z_location = 0
    segment.height = 1.4
    segment.width = 1.4
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 0.75
    segment.percent_z_location = 0.06
    segment.height = 0.6
    segment.width = 0.4
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_5'
    segment.percent_x_location = 1.
    segment.percent_z_location = 0.1
    segment.height = 0.05
    segment.width = 0.05
    fuselage.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(fuselage)

    #-------------------------------------------------------------------
    # Booms
    #-------------------------------------------------------------------
    # Add booms for the motors
    boom = SUAVE.Components.Fuselages.Fuselage()
    boom.tag = 'boom_R'
    boom.origin = [[0.525, 3.0, -0.35]]
    boom.lengths.nose = 0.2
    boom.lengths.tail = 0.2
    boom.lengths.total = 4
    boom.width = 0.15
    boom.heights.maximum = 0.15
    boom.heights.at_quarter_length = 0.15
    boom.heights.at_three_quarters_length = 0.15
    boom.heights.at_wing_root_quarter_chord = 0.15
    boom.effective_diameter = 0.15
    boom.areas.wetted = 2 * np.pi * (0.075) * 3.5
    boom.areas.front_projected = np.pi * 0.15
    boom.fineness.nose = 0.15 / 0.2
    boom.fineness.tail = 0.15 / 0.2

    vehicle.append_component(boom)

    # Now attach the mirrored boom
    other_boom = deepcopy(boom)
    other_boom.origin[0][1] = -boom.origin[0][1]
    other_boom.tag = 'boom_L'
    vehicle.append_component(other_boom)

    #------------------------------------------------------------------
    # Network
    #------------------------------------------------------------------
    net = SUAVE.Components.Energy.Networks.Lift_Cruise()
    net.number_of_lift_rotor_engines = 4
    net.number_of_propeller_engines = 1
    net.identical_propellers = True
    net.identical_lift_rotors = True
    net.voltage = 400.

    #------------------------------------------------------------------
    # Electronic Speed Controller
    #------------------------------------------------------------------
    lift_rotor_esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller(
    )
    lift_rotor_esc.efficiency = 0.95
    net.lift_rotor_esc = lift_rotor_esc

    propeller_esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller(
    )
    propeller_esc.efficiency = 0.95
    net.propeller_esc = propeller_esc

    #------------------------------------------------------------------
    # Payload
    #------------------------------------------------------------------
    payload = SUAVE.Components.Energy.Peripherals.Avionics()
    payload.power_draw = 0.
    net.payload = payload

    #------------------------------------------------------------------
    # Avionics
    #------------------------------------------------------------------
    avionics = SUAVE.Components.Energy.Peripherals.Avionics()
    avionics.power_draw = 300. * Units.watts
    net.avionics = avionics

    #------------------------------------------------------------------
    # Design Battery
    #------------------------------------------------------------------
    bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion_LiNiMnCoO2_18650(
    )
    bat.mass_properties.mass = 1000. * Units.lb
    bat.max_voltage = net.voltage
    initialize_from_mass(bat)
    net.battery = bat

    #------------------------------------------------------------------
    # Design Rotors and Propellers
    #------------------------------------------------------------------

    # The tractor propeller
    propeller = SUAVE.Components.Energy.Converters.Propeller()
    propeller.origin = [[0, 0, -0.325]]
    propeller.number_of_blades = 3
    propeller.tip_radius = 0.9
    propeller.hub_radius = 0.1
    propeller.angular_velocity = 2200 * Units.rpm
    propeller.freestream_velocity = 100. * Units.knots
    propeller.design_Cl = 0.7
    propeller.design_altitude = 5000. * Units.feet
    propeller.design_thrust = 500. * Units.lbf
    propeller.airfoil_geometry = ['./Airfoils/NACA_4412.txt']
    propeller.airfoil_polars = [[
        './Airfoils/Polars/NACA_4412_polar_Re_50000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_100000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_200000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_500000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_1000000.txt'
    ]]
    propeller.airfoil_polar_stations = np.zeros((20), dtype=np.int8).tolist()
    propeller = propeller_design(propeller)
    net.propellers.append(propeller)

    # The lift rotors
    lift_rotor = SUAVE.Components.Energy.Converters.Lift_Rotor()
    lift_rotor.tip_radius = 1.5
    lift_rotor.hub_radius = 0.15
    lift_rotor.number_of_blades = 4
    lift_rotor.design_tip_mach = 0.65
    lift_rotor.freestream_velocity = 500. * Units['ft/min']
    lift_rotor.angular_velocity = lift_rotor.design_tip_mach * Air(
    ).compute_speed_of_sound() / lift_rotor.tip_radius
    lift_rotor.design_Cl = 0.7
    lift_rotor.design_altitude = 3000. * Units.feet
    lift_rotor.design_thrust = 2500 * Units.lbf / 4
    lift_rotor.variable_pitch = False
    lift_rotor.airfoil_geometry = ['./Airfoils/NACA_4412.txt']
    lift_rotor.airfoil_polars = [[
        './Airfoils/Polars/NACA_4412_polar_Re_50000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_100000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_200000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_500000.txt',
        './Airfoils/Polars/NACA_4412_polar_Re_1000000.txt'
    ]]

    lift_rotor.airfoil_polar_stations = np.zeros((20), dtype=np.int8).tolist()
    lift_rotor = propeller_design(lift_rotor)

    # Appending rotors with different origins
    rotations = [1, -1, -1, 1]
    origins = [[0.6, 3., -0.125], [4.5, 3., -0.125], [0.6, -3., -0.125],
               [4.5, -3., -0.125]]

    for ii in range(4):
        lift_rotor = deepcopy(lift_rotor)
        lift_rotor.tag = 'lift_rotor'
        lift_rotor.rotation = rotations[ii]
        lift_rotor.origin = [origins[ii]]
        net.lift_rotors.append(lift_rotor)

    #------------------------------------------------------------------
    # Design Motors
    #------------------------------------------------------------------
    # Propeller (Thrust) motor
    propeller_motor = SUAVE.Components.Energy.Converters.Motor()
    propeller_motor.efficiency = 0.95
    propeller_motor.nominal_voltage = bat.max_voltage
    propeller_motor.mass_properties.mass = 2.0 * Units.kg
    propeller_motor.origin = propeller.origin
    propeller_motor.propeller_radius = propeller.tip_radius
    propeller_motor.no_load_current = 2.0
    propeller_motor = size_optimal_motor(propeller_motor, propeller)
    net.propeller_motors.append(propeller_motor)

    # Rotor (Lift) Motor
    lift_rotor_motor = SUAVE.Components.Energy.Converters.Motor()
    lift_rotor_motor.efficiency = 0.85
    lift_rotor_motor.nominal_voltage = bat.max_voltage * 3 / 4
    lift_rotor_motor.mass_properties.mass = 3. * Units.kg
    lift_rotor_motor.origin = lift_rotor.origin
    lift_rotor_motor.propeller_radius = lift_rotor.tip_radius
    lift_rotor_motor.gearbox_efficiency = 1.0
    lift_rotor_motor.no_load_current = 4.0
    lift_rotor_motor = size_optimal_motor(lift_rotor_motor, lift_rotor)

    for _ in range(4):
        lift_rotor_motor = deepcopy(lift_rotor_motor)
        lift_rotor_motor.tag = 'motor'
        net.lift_rotor_motors.append(lift_rotor_motor)

    vehicle.append_component(net)

    # Now account for things that have been overlooked for now:
    vehicle.excrescence_area = 0.1

    return vehicle
Пример #5
0
def read_vsp_wing(wing_id, units_type='SI',write_airfoil_file=True): 	
    """This reads an OpenVSP wing vehicle geometry and writes it into a SUAVE wing format.

    Assumptions:
    1. OpenVSP wing is divided into segments ("XSecs" in VSP).
    2. Written for OpenVSP 3.21.1

    Source:
    N/A

    Inputs:
    1. VSP 10-digit geom ID for wing.
    2. units_type set to 'SI' (default) or 'Imperial'.

    Outputs:
    Writes SUAVE wing object, with these geometries, from VSP:
    	Wings.Wing.    (* is all keys)
    		origin                                  [m] in all three dimensions
    		spans.projected                         [m]
    		chords.root                             [m]
    		chords.tip                              [m]
    		aspect_ratio                            [-]
    		sweeps.quarter_chord                    [radians]
    		twists.root                             [radians]
    		twists.tip                              [radians]
    		thickness_to_chord                      [-]
    		dihedral                                [radians]
    		symmetric                               <boolean>
    		tag                                     <string>
    		areas.reference                         [m^2]
    		areas.wetted                            [m^2]
    		Segments.
    		  tag                                   <string>
    		  twist                                 [radians]
    		  percent_span_location                 [-]  .1 is 10%
    		  root_chord_percent                    [-]  .1 is 10%
    		  dihedral_outboard                     [radians]
    		  sweeps.quarter_chord                  [radians]
    		  thickness_to_chord                    [-]
    		  airfoil                               <NACA 4-series, 6 series, or airfoil file>

    Properties Used:
    N/A
    """  

    # Check if this is vertical tail, this seems like a weird first step but it's necessary
    # Get the initial rotation to get the dihedral angles
    x_rot = vsp.GetParmVal( wing_id,'X_Rotation','XForm')		
    if  x_rot >=70:
        wing = SUAVE.Components.Wings.Vertical_Tail()
        wing.vertical = True
        x_rot = (90-x_rot) * Units.deg
    else:
        # Instantiate a wing
        wing = SUAVE.Components.Wings.Wing()	
        x_rot =  x_rot  * Units.deg	

    # Set the units
    if units_type == 'SI':
        units_factor = Units.meter * 1.
    elif units_type == 'imperial':
        units_factor = Units.foot * 1.
    elif units_type == 'inches':
        units_factor = Units.inch * 1.		

    # Apply a tag to the wing
    if vsp.GetGeomName(wing_id):
        tag = vsp.GetGeomName(wing_id)
        tag = tag.translate(t_table)
        wing.tag = tag
    else: 
        wing.tag = 'winggeom'
    
    scaling           = vsp.GetParmVal(wing_id, 'Scale', 'XForm')  
    units_factor      = units_factor*scaling
        
    # Top level wing parameters
    # Wing origin
    wing.origin[0][0] = vsp.GetParmVal(wing_id, 'X_Location', 'XForm') * units_factor 
    wing.origin[0][1] = vsp.GetParmVal(wing_id, 'Y_Location', 'XForm') * units_factor 
    wing.origin[0][2] = vsp.GetParmVal(wing_id, 'Z_Location', 'XForm') * units_factor 

    # Wing Symmetry
    sym_planar = vsp.GetParmVal(wing_id, 'Sym_Planar_Flag', 'Sym')
    sym_origin = vsp.GetParmVal(wing_id, 'Sym_Ancestor_Origin_Flag', 'Sym')

    # Check for symmetry
    if sym_planar == 2. and sym_origin == 1.: #origin at wing, not vehicle
        wing.symmetric = True	
    else:
        wing.symmetric = False 

    #More top level parameters
    total_proj_span      = vsp.GetParmVal(wing_id, 'TotalProjectedSpan', 'WingGeom') * units_factor
    wing.aspect_ratio    = vsp.GetParmVal(wing_id, 'TotalAR', 'WingGeom')
    wing.areas.reference = vsp.GetParmVal(wing_id, 'TotalArea', 'WingGeom') * units_factor**2 
    wing.spans.projected = total_proj_span 

    # Check if this is a single segment wing
    xsec_surf_id      = vsp.GetXSecSurf(wing_id, 0)   # This is how VSP stores surfaces.
    x_sec_1           = vsp.GetXSec(xsec_surf_id, 1) 

    if vsp.GetNumXSec(xsec_surf_id) == 2:
        single_seg = True
    else:
        single_seg = False
    
    segment_num = vsp.GetNumXSec(xsec_surf_id) # Get number of segments

    span_sum         = 0.				# Non-projected.
    proj_span_sum    = 0.				# Projected.
    segment_spans    = [None] * (segment_num) 	        # Non-projected.
    segment_dihedral = [None] * (segment_num)
    segment_sweeps_quarter_chord = [None] * (segment_num) 

    # Necessary wing segment definitions start at XSec_1 (XSec_0 exists mainly to hold the root airfoil)
    xsec_surf_id = vsp.GetXSecSurf(wing_id, 0)
    x_sec = vsp.GetXSec(xsec_surf_id, 1)
    chord_parm = vsp.GetXSecParm(x_sec,'Root_Chord')
    root_chord = vsp.GetParmVal(chord_parm) * units_factor

    # -------------
    # Wing segments
    # -------------

    if single_seg == False:

        # Convert VSP XSecs to SUAVE segments. (Wing segments are defined by outboard sections in VSP, but inboard sections in SUAVE.) 
        for i in range(1, segment_num+1):	
            # XSec airfoil
            jj = i-1  # Airfoil index i-1 because VSP airfoils and sections are one index off relative to SUAVE.
		
            segment = SUAVE.Components.Wings.Segment()
            segment.tag                   = 'Section_' + str(i)
            thick_cord                    = vsp.GetParmVal(wing_id, 'ThickChord', 'XSecCurve_' + str(jj))
            segment.thickness_to_chord    = thick_cord	# Thick_cord stored for use in airfoil, below.		
            if i!=segment_num:
                segment_root_chord    = vsp.GetParmVal(wing_id, 'Root_Chord', 'XSec_' + str(i)) * units_factor
            else:
                segment_root_chord    = 0.0
            segment.root_chord_percent    = segment_root_chord / root_chord		
            segment.percent_span_location = proj_span_sum / (total_proj_span/(1+wing.symmetric))
            segment.twist                 = vsp.GetParmVal(wing_id, 'Twist', 'XSec_' + str(jj)) * Units.deg

            if i==1:
                wing.thickness_to_chord = thick_cord

            if i < segment_num:      # This excludes the tip xsec, but we need a segment in SUAVE to store airfoil.
                sweep     = vsp.GetParmVal(wing_id, 'Sweep', 'XSec_' + str(i)) * Units.deg
                sweep_loc = vsp.GetParmVal(wing_id, 'Sweep_Location', 'XSec_' + str(i))
                AR        = 2*vsp.GetParmVal(wing_id, 'Aspect', 'XSec_' + str(i))
                taper     = vsp.GetParmVal(wing_id, 'Taper', 'XSec_' + str(i))

                segment_sweeps_quarter_chord[i] = convert_sweep(sweep,sweep_loc,0.25,AR,taper)
                segment.sweeps.quarter_chord    = segment_sweeps_quarter_chord[i]  # Used again, below

                # Used for dihedral computation, below.
                segment_dihedral[i]	      = vsp.GetParmVal(wing_id, 'Dihedral', 'XSec_' + str(i)) * Units.deg  + x_rot
                segment.dihedral_outboard     = segment_dihedral[i]

                segment_spans[i] 	      = vsp.GetParmVal(wing_id, 'Span', 'XSec_' + str(i)) * units_factor
                proj_span_sum += segment_spans[i] * np.cos(segment_dihedral[i])	
                span_sum      += segment_spans[i]
            else:
                segment.root_chord_percent    = (vsp.GetParmVal(wing_id, 'Tip_Chord', 'XSec_' + str(i-1))) * units_factor /root_chord


            xsec_id = str(vsp.GetXSec(xsec_surf_id, jj))
            airfoil = Airfoil()
            if vsp.GetXSecShape(xsec_id) == vsp.XS_FOUR_SERIES: 	# XSec shape: NACA 4-series
                camber = vsp.GetParmVal(wing_id, 'Camber', 'XSecCurve_' + str(jj)) 

                if camber == 0.:
                    camber_loc = 0.
                else:
                    camber_loc = vsp.GetParmVal(wing_id, 'CamberLoc', 'XSecCurve_' + str(jj))

                airfoil.thickness_to_chord = thick_cord
                camber_round               = int(np.around(camber*100))
                camber_loc_round           = int(np.around(camber_loc*10)) 
                thick_cord_round           = int(np.around(thick_cord*100))
                airfoil.tag                = 'NACA ' + str(camber_round) + str(camber_loc_round) + str(thick_cord_round)	

            elif vsp.GetXSecShape(xsec_id) == vsp.XS_SIX_SERIES: 	# XSec shape: NACA 6-series
                thick_cord_round = int(np.around(thick_cord*100))
                a_value          = vsp.GetParmVal(wing_id, 'A', 'XSecCurve_' + str(jj))
                ideal_CL         = int(np.around(vsp.GetParmVal(wing_id, 'IdealCl', 'XSecCurve_' + str(jj))*10))
                series_vsp       = int(vsp.GetParmVal(wing_id, 'Series', 'XSecCurve_' + str(jj)))
                series_dict      = {0:'63',1:'64',2:'65',3:'66',4:'67',5:'63A',6:'64A',7:'65A'} # VSP series values.
                series           = series_dict[series_vsp]
                airfoil.tag      = 'NACA ' + series + str(ideal_CL) + str(thick_cord_round) + ' a=' + str(np.around(a_value,1))			


            elif vsp.GetXSecShape(xsec_id) == vsp.XS_FILE_AIRFOIL:	# XSec shape: 12 is type AF_FILE
                airfoil.thickness_to_chord = thick_cord
                # VSP airfoil API calls get coordinates and write files with the final argument being the fraction of segment position, regardless of relative spans. 
                # (Write the root airfoil with final arg = 0. Write 4th airfoil of 5 segments with final arg = .8)

            if write_airfoil_file==True:
                vsp.WriteSeligAirfoil(str(wing.tag) + '_airfoil_XSec_' + str(jj) +'.dat', wing_id, float(jj/segment_num))
                airfoil.coordinate_file    = str(wing.tag) + '_airfoil_XSec_' + str(jj) +'.dat'
                airfoil.tag                = 'airfoil'	

                segment.append_airfoil(airfoil)

            wing.Segments.append(segment)

        # Wing dihedral 
        proj_span_sum_alt = 0.
        span_sum_alt      = 0.
        sweeps_sum        = 0.			

        for ii in range(1, segment_num):
            span_sum_alt += segment_spans[ii]
            proj_span_sum_alt += segment_spans[ii] * np.cos(segment_dihedral[ii])  # Use projected span to find total wing dihedral.
            sweeps_sum += segment_spans[ii] * np.tan(segment_sweeps_quarter_chord[ii])	

        wing.dihedral              = np.arccos(proj_span_sum_alt / span_sum_alt) 
        wing.sweeps.quarter_chord  = -np.arctan(sweeps_sum / span_sum_alt)  # Minus sign makes it positive sweep.

        # Add a tip segment, all values are zero except the tip chord
        tc = vsp.GetParmVal(wing_id, 'Tip_Chord', 'XSec_' + str(segment_num-1)) * units_factor

        # Chords
        wing.chords.root              = vsp.GetParmVal(wing_id, 'Tip_Chord', 'XSec_0') * units_factor
        wing.chords.tip               = tc
        wing.chords.mean_geometric    = wing.areas.reference / wing.spans.projected

        # Just double calculate and fix things:
        wing = wing_segmented_planform(wing)


    else:
        # Single segment

        # Get ID's
        x_sec_1_dih_parm       = vsp.GetXSecParm(x_sec_1,'Dihedral')
        x_sec_1_sweep_parm     = vsp.GetXSecParm(x_sec_1,'Sweep')
        x_sec_1_sweep_loc_parm = vsp.GetXSecParm(x_sec_1,'Sweep_Location')
        x_sec_1_taper_parm     = vsp.GetXSecParm(x_sec_1,'Taper')
        x_sec_1_rc_parm        = vsp.GetXSecParm(x_sec_1,'Root_Chord')
        x_sec_1_tc_parm        = vsp.GetXSecParm(x_sec_1,'Tip_Chord')
        x_sec_1_t_parm        = vsp.GetXSecParm(x_sec_1,'ThickChord')
     
        # Calcs
        sweep     = vsp.GetParmVal(x_sec_1_sweep_parm) * Units.deg
        sweep_loc = vsp.GetParmVal(x_sec_1_sweep_loc_parm)
        taper     = vsp.GetParmVal(x_sec_1_taper_parm)
        c_4_sweep = convert_sweep(sweep,sweep_loc,0.25,wing.aspect_ratio,taper)		

        # Pull and pack
        wing.sweeps.quarter_chord  = c_4_sweep
        wing.taper                 = taper
        wing.dihedral              = vsp.GetParmVal(x_sec_1_dih_parm) * Units.deg + x_rot
        wing.chords.root           = vsp.GetParmVal(x_sec_1_rc_parm)* units_factor
        wing.chords.tip            = vsp.GetParmVal(x_sec_1_tc_parm) * units_factor	
        wing.chords.mean_geometric = wing.areas.reference / wing.spans.projected
        wing.thickness_to_chord    = vsp.GetParmVal(x_sec_1_t_parm) 

        # Just double calculate and fix things:
        wing = wing_planform(wing)		


    # Twists
    wing.twists.root      = vsp.GetParmVal(wing_id, 'Twist', 'XSec_0') * Units.deg
    wing.twists.tip       = vsp.GetParmVal(wing_id, 'Twist', 'XSec_' + str(segment_num-1)) * Units.deg

    # check if control surface (sub surfaces) are defined
    tags                 = []
    LE_flags             = []
    span_fraction_starts = []
    span_fraction_ends   = []
    chord_fractions      = []
    
    num_cs = vsp.GetNumSubSurf(wing_id)
    
    # loop through wing and get all control surface parameters 
    for cs_idx in range(num_cs):
        cs_id   = vsp.GetSubSurf(wing_id,cs_idx)
        param_names = vsp.GetSubSurfParmIDs(cs_id)
        tags.append(vsp.GetSubSurfName(cs_id))
        for p_idx in range(len(param_names)):
            if 'LE_Flag' == vsp.GetParmName(param_names[p_idx]):
                LE_flags.append(vsp.GetParmVal(param_names[p_idx]))
            if 'UStart' == vsp.GetParmName(param_names[p_idx]):
                span_fraction_starts.append(vsp.GetParmVal(param_names[p_idx]))
            if 'UEnd' == vsp.GetParmName(param_names[p_idx]):
                span_fraction_ends.append(vsp.GetParmVal(param_names[p_idx]))
            if 'Length_C_Start' == vsp.GetParmName(param_names[p_idx]):
                chord_fractions.append(vsp.GetParmVal(param_names[p_idx]))
                
    # assign control surface parameters to wings. Outer most control surface on main/horizontal wing is assigned a aileron
    for cs_idx in range(num_cs):   
        aileron_present = False
        if num_cs > 1:
            aileron_loc = np.argmax(np.array(span_fraction_starts))   
            if cs_idx == aileron_loc: 
                aileron_present = True
        if LE_flags[cs_idx] == 1.0:
            CS = SUAVE.Components.Wings.Control_Surfaces.Slat()
        else:
            if wing.vertical == True:
                CS = SUAVE.Components.Wings.Control_Surfaces.Rudder()
            else:
                if aileron_present:
                    CS = SUAVE.Components.Wings.Control_Surfaces.Aileron()
                else: 
                    CS = SUAVE.Components.Wings.Control_Surfaces.Flap()
        CS.tag                 = tags[cs_idx]
        CS.span_fraction_start = span_fraction_starts[cs_idx]*3 - 1
        CS.span_fraction_end   = span_fraction_ends[cs_idx]*3 - 1
        CS.chord_fraction      = chord_fractions[cs_idx]
        CS.span                = (CS.span_fraction_end - CS.span_fraction_start)*wing.spans.projected
        wing.append_control_surface(CS)
    
    return wing
Пример #6
0
def vehicle_setup():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'Boeing_737800'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------

    # mass properties
    vehicle.mass_properties.max_takeoff = 79015.8  # kg
    vehicle.mass_properties.takeoff = 79015.8  # kg
    vehicle.mass_properties.operating_empty = 62746.4  # kg
    vehicle.mass_properties.takeoff = 79015.8  # kg
    vehicle.mass_properties.max_zero_fuel = 62732.0  # kg
    vehicle.mass_properties.cargo = 10000. * Units.kilogram
    vehicle.mass_properties.center_of_gravity = [[
        15.30987849, 0., -0.48023939
    ]]
    vehicle.mass_properties.moments_of_inertia.tensor = [[
        3173074.17, 0, 28752.77565
    ], [0, 3019041.443, 0], [0, 0, 5730017.433]]  # estimated, not correct
    vehicle.design_mach_number = 0.78
    vehicle.design_range = 3582 * Units.miles
    vehicle.design_cruise_alt = 35000.0 * Units.ft

    # envelope properties
    vehicle.envelope.ultimate_load = 3.75
    vehicle.envelope.limit_load = 1.5

    # basic parameters
    vehicle.reference_area = 124.862
    vehicle.passengers = 170
    vehicle.systems.control = "fully powered"
    vehicle.systems.accessories = "medium range"

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'

    wing.aspect_ratio = 10.18
    wing.sweeps.quarter_chord = 25 * Units.deg
    wing.thickness_to_chord = 0.1
    wing.taper = 0.1

    wing.spans.projected = 34.32

    wing.chords.root = 7.760 * Units.meter
    wing.chords.tip = 0.782 * Units.meter
    wing.chords.mean_aerodynamic = 4.235 * Units.meter

    wing.areas.reference = 124.862
    wing.areas.wetted = 225.08

    wing.twists.root = 4.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees

    wing.origin = [[13.61, 0, -0.93]]
    wing.aerodynamic_center = [0, 0, 0]

    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = True

    wing.dynamic_pressure_ratio = 1.0

    # Wing Segments
    root_airfoil = SUAVE.Components.Airfoils.Airfoil()
    root_airfoil.coordinate_file = '../Vehicles/Airfoils/B737a.txt'
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Root'
    segment.percent_span_location = 0.0
    segment.twist = 4. * Units.deg
    segment.root_chord_percent = 1.
    segment.thickness_to_chord = 0.1
    segment.dihedral_outboard = 2.5 * Units.degrees
    segment.sweeps.quarter_chord = 28.225 * Units.degrees
    segment.thickness_to_chord = .1
    segment.append_airfoil(root_airfoil)
    wing.append_segment(segment)

    yehudi_airfoil = SUAVE.Components.Airfoils.Airfoil()
    yehudi_airfoil.coordinate_file = '../Vehicles/Airfoils/B737b.txt'
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Yehudi'
    segment.percent_span_location = 0.324
    segment.twist = 0.047193 * Units.deg
    segment.root_chord_percent = 0.5
    segment.thickness_to_chord = 0.1
    segment.dihedral_outboard = 5.5 * Units.degrees
    segment.sweeps.quarter_chord = 25. * Units.degrees
    segment.thickness_to_chord = .1
    segment.append_airfoil(yehudi_airfoil)
    wing.append_segment(segment)

    mid_airfoil = SUAVE.Components.Airfoils.Airfoil()
    mid_airfoil.coordinate_file = '../Vehicles/Airfoils/B737c.txt'
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Section_2'
    segment.percent_span_location = 0.963
    segment.twist = 0.00258 * Units.deg
    segment.root_chord_percent = 0.220
    segment.thickness_to_chord = 0.1
    segment.dihedral_outboard = 5.5 * Units.degrees
    segment.sweeps.quarter_chord = 56.75 * Units.degrees
    segment.thickness_to_chord = .1
    segment.append_airfoil(mid_airfoil)
    wing.append_segment(segment)

    tip_airfoil = SUAVE.Components.Airfoils.Airfoil()
    tip_airfoil.coordinate_file = '../Vehicles/Airfoils/B737d.txt'
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Tip'
    segment.percent_span_location = 1.
    segment.twist = 0. * Units.degrees
    segment.root_chord_percent = 0.10077
    segment.thickness_to_chord = 0.1
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = .1
    segment.append_airfoil(tip_airfoil)
    wing.append_segment(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # control surfaces -------------------------------------------
    slat = SUAVE.Components.Wings.Control_Surfaces.Slat()
    slat.tag = 'slat'
    slat.span_fraction_start = 0.2
    slat.span_fraction_end = 0.963
    slat.deflection = 0.0 * Units.degrees
    slat.chord_fraction = 0.075
    wing.append_control_surface(slat)

    flap = SUAVE.Components.Wings.Control_Surfaces.Flap()
    flap.tag = 'flap'
    flap.span_fraction_start = 0.2
    flap.span_fraction_end = 0.7
    flap.deflection = 0.0 * Units.degrees
    flap.configuration_type = 'double_slotted'
    flap.chord_fraction = 0.30
    wing.append_control_surface(flap)

    aileron = SUAVE.Components.Wings.Control_Surfaces.Aileron()
    aileron.tag = 'aileron'
    aileron.span_fraction_start = 0.7
    aileron.span_fraction_end = 0.963
    aileron.deflection = 0.0 * Units.degrees
    aileron.chord_fraction = 0.16
    wing.append_control_surface(aileron)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Horizontal Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Horizontal_Tail()
    wing.tag = 'horizontal_stabilizer'

    wing.aspect_ratio = 4.99
    wing.sweeps.quarter_chord = 28.2250 * Units.deg
    wing.thickness_to_chord = 0.08
    wing.taper = 0.3333

    wing.spans.projected = 14.4

    wing.chords.root = 4.2731
    wing.chords.tip = 1.4243
    wing.chords.mean_aerodynamic = 8.0

    wing.areas.reference = 41.49
    wing.areas.exposed = 59.354  # Exposed area of the horizontal tail
    wing.areas.wetted = 71.81  # Wetted area of the horizontal tail
    wing.twists.root = 3.0 * Units.degrees
    wing.twists.tip = 3.0 * Units.degrees

    wing.origin = [[33.02, 0, 1.466]]
    wing.aerodynamic_center = [0, 0, 0]

    wing.vertical = False
    wing.symmetric = True

    wing.dynamic_pressure_ratio = 0.9

    # Wing Segments
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'root_segment'
    segment.percent_span_location = 0.0
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 1.0
    segment.dihedral_outboard = 8.63 * Units.degrees
    segment.sweeps.quarter_chord = 28.2250 * Units.degrees
    segment.thickness_to_chord = .1
    wing.append_segment(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'tip_segment'
    segment.percent_span_location = 1.
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.3333
    segment.dihedral_outboard = 0 * Units.degrees
    segment.sweeps.quarter_chord = 0 * Units.degrees
    segment.thickness_to_chord = .1
    wing.append_segment(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # control surfaces -------------------------------------------
    elevator = SUAVE.Components.Wings.Control_Surfaces.Elevator()
    elevator.tag = 'elevator'
    elevator.span_fraction_start = 0.09
    elevator.span_fraction_end = 0.92
    elevator.deflection = 0.0 * Units.deg
    elevator.chord_fraction = 0.3
    wing.append_control_surface(elevator)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Vertical Stabilizer
    # ------------------------------------------------------------------

    wing = SUAVE.Components.Wings.Vertical_Tail()
    wing.tag = 'vertical_stabilizer'

    wing.aspect_ratio = 1.98865
    wing.sweeps.quarter_chord = 31.2 * Units.deg
    wing.thickness_to_chord = 0.08
    wing.taper = 0.1183

    wing.spans.projected = 8.33
    wing.total_length = wing.spans.projected

    wing.chords.root = 10.1
    wing.chords.tip = 1.20
    wing.chords.mean_aerodynamic = 4.0

    wing.areas.reference = 34.89
    wing.areas.wetted = 57.25

    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees

    wing.origin = [[26.944, 0, 1.54]]
    wing.aerodynamic_center = [0, 0, 0]

    wing.vertical = True
    wing.symmetric = False
    wing.t_tail = False

    wing.dynamic_pressure_ratio = 1.0

    # Wing Segments
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'root'
    segment.percent_span_location = 0.0
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 0 * Units.degrees
    segment.sweeps.quarter_chord = 61.485 * Units.degrees
    segment.thickness_to_chord = .1
    wing.append_segment(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'segment_1'
    segment.percent_span_location = 0.2962
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.45
    segment.dihedral_outboard = 0. * Units.degrees
    segment.sweeps.quarter_chord = 31.2 * Units.degrees
    segment.thickness_to_chord = .1
    wing.append_segment(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'segment_2'
    segment.percent_span_location = 1.0
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.1183
    segment.dihedral_outboard = 0.0 * Units.degrees
    segment.sweeps.quarter_chord = 0.0
    segment.thickness_to_chord = .1
    wing.append_segment(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Fuselage
    # ------------------------------------------------------------------

    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'

    fuselage.number_coach_seats = vehicle.passengers
    fuselage.seats_abreast = 6
    fuselage.seat_pitch = 31. * Units.inches
    fuselage.fineness.nose = 1.6
    fuselage.fineness.tail = 2.

    fuselage.lengths.nose = 6.4
    fuselage.lengths.tail = 8.0
    fuselage.lengths.cabin = 28.85
    fuselage.lengths.total = 38.02
    fuselage.lengths.fore_space = 6.
    fuselage.lengths.aft_space = 5.

    fuselage.width = 3.74

    fuselage.heights.maximum = 3.74
    fuselage.heights.at_quarter_length = 3.74
    fuselage.heights.at_three_quarters_length = 3.65
    fuselage.heights.at_wing_root_quarter_chord = 3.74

    fuselage.areas.side_projected = 142.1948
    fuselage.areas.wetted = 385.51
    fuselage.areas.front_projected = 12.57

    fuselage.effective_diameter = 3.74

    fuselage.differential_pressure = 5.0e4 * Units.pascal  # Maximum differential pressure

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_0'
    segment.percent_x_location = 0.0000
    segment.percent_z_location = -0.00144
    segment.height = 0.0100
    segment.width = 0.0100
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.00576
    segment.percent_z_location = -0.00144
    segment.height = 0.7500
    segment.width = 0.6500
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.02017
    segment.percent_z_location = 0.00000
    segment.height = 1.52783
    segment.width = 1.20043
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 0.03170
    segment.percent_z_location = 0.00000
    segment.height = 1.96435
    segment.width = 1.52783
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 0.04899
    segment.percent_z_location = 0.00431
    segment.height = 2.72826
    segment.width = 1.96435
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_5'
    segment.percent_x_location = 0.07781
    segment.percent_z_location = 0.00861
    segment.height = 3.49217
    segment.width = 2.61913
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_6'
    segment.percent_x_location = 0.10375
    segment.percent_z_location = 0.01005
    segment.height = 3.70130
    segment.width = 3.05565
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_7'
    segment.percent_x_location = 0.16427
    segment.percent_z_location = 0.01148
    segment.height = 3.92870
    segment.width = 3.71043
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_8'
    segment.percent_x_location = 0.22478
    segment.percent_z_location = 0.01148
    segment.height = 3.92870
    segment.width = 3.92870
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_9'
    segment.percent_x_location = 0.69164
    segment.percent_z_location = 0.01292
    segment.height = 3.81957
    segment.width = 3.81957
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_10'
    segment.percent_x_location = 0.71758
    segment.percent_z_location = 0.01292
    segment.height = 3.81957
    segment.width = 3.81957
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_11'
    segment.percent_x_location = 0.78098
    segment.percent_z_location = 0.01722
    segment.height = 3.49217
    segment.width = 3.71043
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_12'
    segment.percent_x_location = 0.85303
    segment.percent_z_location = 0.02296
    segment.height = 3.05565
    segment.width = 3.16478
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_13'
    segment.percent_x_location = 0.91931
    segment.percent_z_location = 0.03157
    segment.height = 2.40087
    segment.width = 1.96435
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_14'
    segment.percent_x_location = 1.00
    segment.percent_z_location = 0.04593
    segment.height = 1.09130
    segment.width = 0.21826
    fuselage.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(fuselage)

    # ------------------------------------------------------------------
    #   Nacelles
    # ------------------------------------------------------------------
    nacelle = SUAVE.Components.Nacelles.Nacelle()
    nacelle.tag = 'nacelle_1'
    nacelle.length = 2.71
    nacelle.inlet_diameter = 1.90
    nacelle.diameter = 2.05
    nacelle.areas.wetted = 1.1 * np.pi * nacelle.diameter * nacelle.length
    nacelle.origin = [[13.72, -4.86, -1.9]]
    nacelle.flow_through = True
    nacelle.Airfoil.naca_4_series_airfoil = '2410'

    nacelle_2 = deepcopy(nacelle)
    nacelle_2.tag = 'nacelle_2'
    nacelle_2.origin = [[13.72, 4.86, -1.9]]

    vehicle.append_component(nacelle)
    vehicle.append_component(nacelle_2)

    # ------------------------------------------------------------------
    #   Turbofan Network
    # ------------------------------------------------------------------

    #instantiate the gas turbine network
    turbofan = SUAVE.Components.Energy.Networks.Turbofan()
    turbofan.tag = 'turbofan'

    # setup
    turbofan.number_of_engines = 2.0
    turbofan.bypass_ratio = 5.4
    turbofan.engine_length = 2.71

    # This origin is overwritten by compute_component_centers_of_gravity(base,compute_propulsor_origin=True)
    turbofan.origin = [[13.72, 4.86, -1.9], [13.72, -4.86, -1.9]]

    # working fluid
    turbofan.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1 - Ram

    # to convert freestream static to stagnation quantities

    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    # add to the network
    turbofan.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'

    # setup
    inlet_nozzle.polytropic_efficiency = 0.98
    inlet_nozzle.pressure_ratio = 0.98

    # add to network
    turbofan.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 3 - Low Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'low_pressure_compressor'

    # setup
    compressor.polytropic_efficiency = 0.91
    compressor.pressure_ratio = 1.14

    # add to network
    turbofan.append(compressor)

    # ------------------------------------------------------------------
    #  Component 4 - High Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'high_pressure_compressor'

    # setup
    compressor.polytropic_efficiency = 0.91
    compressor.pressure_ratio = 13.415

    # add to network
    turbofan.append(compressor)

    # ------------------------------------------------------------------
    #  Component 5 - Low Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'low_pressure_turbine'

    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.93

    # add to network
    turbofan.append(turbine)

    # ------------------------------------------------------------------
    #  Component 6 - High Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'high_pressure_turbine'

    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.93

    # add to network
    turbofan.append(turbine)

    # ------------------------------------------------------------------
    #  Component 7 - Combustor

    # instantiate
    combustor = SUAVE.Components.Energy.Converters.Combustor()
    combustor.tag = 'combustor'

    # setup
    combustor.efficiency = 0.99
    combustor.alphac = 1.0
    combustor.turbine_inlet_temperature = 1450
    combustor.pressure_ratio = 0.95
    combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A()

    # add to network
    turbofan.append(combustor)

    # ------------------------------------------------------------------
    #  Component 8 - Core Nozzle

    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    nozzle.tag = 'core_nozzle'

    # setup
    nozzle.polytropic_efficiency = 0.95
    nozzle.pressure_ratio = 0.99

    # add to network
    turbofan.append(nozzle)

    # ------------------------------------------------------------------
    #  Component 9 - Fan Nozzle

    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    nozzle.tag = 'fan_nozzle'

    # setup
    nozzle.polytropic_efficiency = 0.95
    nozzle.pressure_ratio = 0.99

    # add to network
    turbofan.append(nozzle)

    # ------------------------------------------------------------------
    #  Component 10 - Fan

    # instantiate
    fan = SUAVE.Components.Energy.Converters.Fan()
    fan.tag = 'fan'

    # setup
    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio = 1.7

    # add to network
    turbofan.append(fan)

    # ------------------------------------------------------------------
    #Component 10 : thrust (to compute the thrust)
    thrust = SUAVE.Components.Energy.Processes.Thrust()
    thrust.tag = 'compute_thrust'

    #total design thrust (includes all the engines)
    thrust.total_design = 2 * 24000. * Units.N  #Newtons

    #design sizing conditions
    altitude = 35000.0 * Units.ft
    mach_number = 0.78
    isa_deviation = 0.

    #Engine setup for noise module

    # add to network
    turbofan.thrust = thrust

    turbofan.core_nozzle_diameter = 0.92
    turbofan.fan_nozzle_diameter = 1.659
    turbofan.engine_height = 0.5  #Engine centerline heigh above the ground plane
    turbofan.exa = 1  #distance from fan face to fan exit/ fan diameter)
    turbofan.plug_diameter = 0.1  #dimater of the engine plug
    turbofan.geometry_xe = 1.  # Geometry information for the installation effects function
    turbofan.geometry_ye = 1.  # Geometry information for the installation effects function
    turbofan.geometry_Ce = 2.  # Geometry information for the installation effects function

    #size the turbofan
    turbofan_sizing(turbofan, mach_number, altitude)

    # add  gas turbine network turbofan to the vehicle
    vehicle.append_component(turbofan)

    # ------------------------------------------------------------------
    #  Fuel
    # ------------------------------------------------------------------
    fuel = SUAVE.Components.Physical_Component()
    vehicle.fuel = fuel
    fuel.mass_properties.mass = vehicle.mass_properties.max_takeoff - vehicle.mass_properties.max_fuel
    fuel.origin = vehicle.wings.main_wing.mass_properties.center_of_gravity
    fuel.mass_properties.center_of_gravity = vehicle.wings.main_wing.aerodynamic_center

    # ------------------------------------------------------------------
    #  Landing Gear
    # ------------------------------------------------------------------
    landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear()
    landing_gear.tag = "main_landing_gear"
    landing_gear.main_tire_diameter = 1.12000 * Units.m
    landing_gear.nose_tire_diameter = 0.6858 * Units.m
    landing_gear.main_strut_length = 1.8 * Units.m
    landing_gear.nose_strut_length = 1.3 * Units.m
    landing_gear.main_units = 1  #number of nose landing gear
    landing_gear.nose_units = 1  #number of nose landing gear
    landing_gear.main_wheels = 2  #number of wheels on the main landing gear
    landing_gear.nose_wheels = 2  #number of wheels on the nose landing gear
    vehicle.landing_gear = landing_gear

    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle
Пример #7
0
def vehicle_setup():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------
    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'Boeing_BWB_450'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------
    # mass properties
    vehicle.mass_properties.max_takeoff = 823000. * Units.lb
    vehicle.mass_properties.takeoff = 823000. * Units.lb
    vehicle.mass_properties.max_zero_fuel = 0.9 * vehicle.mass_properties.max_takeoff
    vehicle.mass_properties.cargo = 00. * Units.kilogram

    # envelope properties
    vehicle.envelope.ultimate_load = 2.5
    vehicle.envelope.limit_load = 1.5

    # basic parameters
    vehicle.reference_area = 7840. * 2 * Units.feet**2
    vehicle.passengers = 450.
    vehicle.systems.control = "fully powered"
    vehicle.systems.accessories = "medium range"

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------
    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'

    wing.aspect_ratio = 289.**2 / (7840. * 2)
    wing.thickness_to_chord = 0.15
    wing.taper = 0.0138
    wing.spans.projected = 289.0 * Units.feet
    wing.chords.root = 145.0 * Units.feet
    wing.chords.tip = 3.5 * Units.feet
    wing.chords.mean_aerodynamic = 80. * Units.feet
    wing.areas.reference = 7840. * 2 * Units.feet**2
    wing.sweeps.quarter_chord = 33. * Units.degrees
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.dihedral = 2.5 * Units.degrees
    wing.origin = [[0., 0., 0]]
    wing.aerodynamic_center = [0, 0, 0]
    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = True
    wing.dynamic_pressure_ratio = 1.0

    segment = SUAVE.Components.Wings.Segment()

    segment.tag = 'section_1'
    segment.percent_span_location = 0.0
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 0. * Units.degrees
    segment.sweeps.quarter_chord = 40.0 * Units.degrees
    segment.thickness_to_chord = 0.165
    segment.vsp_mesh = Data()
    segment.vsp_mesh.inner_radius = 4.
    segment.vsp_mesh.outer_radius = 4.
    segment.vsp_mesh.inner_length = .14
    segment.vsp_mesh.outer_length = .14
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_2'
    segment.percent_span_location = 0.052
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.921
    segment.dihedral_outboard = 0. * Units.degrees
    segment.sweeps.quarter_chord = 52.5 * Units.degrees
    segment.thickness_to_chord = 0.167
    segment.vsp_mesh = Data()
    segment.vsp_mesh.inner_radius = 4.
    segment.vsp_mesh.outer_radius = 4.
    segment.vsp_mesh.inner_length = .14
    segment.vsp_mesh.outer_length = .14
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_3'
    segment.percent_span_location = 0.138
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.76
    segment.dihedral_outboard = 1.85 * Units.degrees
    segment.sweeps.quarter_chord = 36.9 * Units.degrees
    segment.thickness_to_chord = 0.171
    segment.vsp_mesh = Data()
    segment.vsp_mesh.inner_radius = 4.
    segment.vsp_mesh.outer_radius = 4.
    segment.vsp_mesh.inner_length = .14
    segment.vsp_mesh.outer_length = .14
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_4'
    segment.percent_span_location = 0.221
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.624
    segment.dihedral_outboard = 1.85 * Units.degrees
    segment.sweeps.quarter_chord = 30.4 * Units.degrees
    segment.thickness_to_chord = 0.175
    segment.vsp_mesh = Data()
    segment.vsp_mesh.inner_radius = 4.
    segment.vsp_mesh.outer_radius = 2.8
    segment.vsp_mesh.inner_length = .14
    segment.vsp_mesh.outer_length = .14
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_5'
    segment.percent_span_location = 0.457
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.313
    segment.dihedral_outboard = 1.85 * Units.degrees
    segment.sweeps.quarter_chord = 30.85 * Units.degrees
    segment.thickness_to_chord = 0.118
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_6'
    segment.percent_span_location = 0.568
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.197
    segment.dihedral_outboard = 1.85 * Units.degrees
    segment.sweeps.quarter_chord = 34.3 * Units.degrees
    segment.thickness_to_chord = 0.10
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_7'
    segment.percent_span_location = 0.97
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.086
    segment.dihedral_outboard = 73. * Units.degrees
    segment.sweeps.quarter_chord = 55. * Units.degrees
    segment.thickness_to_chord = 0.10
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'tip'
    segment.percent_span_location = 1
    segment.twist = 0. * Units.deg
    segment.root_chord_percent = 0.0241
    segment.dihedral_outboard = 0. * Units.degrees
    segment.sweeps.quarter_chord = 0. * Units.degrees
    segment.thickness_to_chord = 0.10
    wing.Segments.append(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Nacelle
    # ------------------------------------------------------------------
    nacelle = SUAVE.Components.Nacelles.Nacelle()
    nacelle.diameter = 3.96 * Units.meters
    nacelle.length = 289. * Units.inches
    nacelle.tag = 'nacelle'
    nacelle.origin = [[
        133.0 * Units.feet, 25.0 * Units.feet, 6.5 * Units.feet
    ]]
    nacelle.areas.wetted = nacelle.length * (2 * np.pi * nacelle.diameter / 2.)

    nacelle_2 = deepcopy(nacelle)
    nacelle_2.tag = 'nacelle_2'
    nacelle_2.origin = [[
        145.0 * Units.feet, 0.0 * Units.feet, 6.5 * Units.feet
    ]]

    nacelle_3 = deepcopy(nacelle)
    nacelle_3.tag = 'nacelle_3'
    nacelle_3.origin = [[
        133.0 * Units.feet, -25.0 * Units.feet, 6.5 * Units.feet
    ]]

    vehicle.append_component(nacelle)
    vehicle.append_component(nacelle_2)
    vehicle.append_component(nacelle_3)

    # ------------------------------------------------------------------
    #   Turbofan Network
    # ------------------------------------------------------------------
    #instantiate the gas turbine network
    turbofan = SUAVE.Components.Energy.Networks.Turbofan()
    turbofan.tag = 'turbofan1'

    # setup
    turbofan.number_of_engines = 3.0
    turbofan.bypass_ratio = 8.1
    turbofan.engine_length = 289. * Units.inches
    turbofan.origin = [
        [133.0 * Units.feet, 25.0 * Units.feet, 6.5 * Units.feet],
        [145.0 * Units.feet, 0.0 * Units.feet, 6.5 * Units.feet],
        [133.0 * Units.feet, -25.0 * Units.feet, 6.5 * Units.feet]
    ]

    # working fluid
    turbofan.working_fluid = SUAVE.Attributes.Gases.Air()

    # ------------------------------------------------------------------
    #   Component 1 - Ram

    # to convert freestream static to stagnation quantities
    # instantiate
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'
    # add to the network
    turbofan.append(ram)

    # ------------------------------------------------------------------
    #  Component 2 - Inlet Nozzle

    # instantiate
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet_nozzle'
    # setup
    inlet_nozzle.polytropic_efficiency = 1.0
    inlet_nozzle.pressure_ratio = 1.0
    # add to network
    turbofan.append(inlet_nozzle)

    # ------------------------------------------------------------------
    #  Component 3 - Low Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'low_pressure_compressor'
    # setup
    compressor.polytropic_efficiency = 0.91
    compressor.pressure_ratio = 1.1
    # add to network
    turbofan.append(compressor)

    # ------------------------------------------------------------------
    #  Component 4 - High Pressure Compressor

    # instantiate
    compressor = SUAVE.Components.Energy.Converters.Compressor()
    compressor.tag = 'high_pressure_compressor'
    # setup
    compressor.polytropic_efficiency = 0.91
    compressor.pressure_ratio = 23.0
    #compressor.hub_to_tip_ratio      = 0.325
    # add to network
    turbofan.append(compressor)

    # ------------------------------------------------------------------
    #  Component 5 - Low Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'low_pressure_turbine'
    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.93
    # add to network
    turbofan.append(turbine)

    # ------------------------------------------------------------------
    #  Component 6 - High Pressure Turbine

    # instantiate
    turbine = SUAVE.Components.Energy.Converters.Turbine()
    turbine.tag = 'high_pressure_turbine'
    # setup
    turbine.mechanical_efficiency = 0.99
    turbine.polytropic_efficiency = 0.93
    # add to network
    turbofan.append(turbine)

    # ------------------------------------------------------------------
    #  Component 7 - Combustor

    # instantiate
    combustor = SUAVE.Components.Energy.Converters.Combustor()
    combustor.tag = 'combustor'
    # setup
    combustor.efficiency = 1.0
    combustor.alphac = 1.0
    combustor.turbine_inlet_temperature = 1592. * Units.kelvin
    combustor.pressure_ratio = 0.95
    combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A()
    # add to network
    turbofan.append(combustor)

    # ------------------------------------------------------------------
    #  Component 8 - Core Nozzle

    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    nozzle.tag = 'core_nozzle'
    # setup
    nozzle.polytropic_efficiency = 0.95
    nozzle.pressure_ratio = 0.99
    # add to network
    turbofan.append(nozzle)

    # ------------------------------------------------------------------
    #  Component 9 - Fan Nozzle

    # instantiate
    nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    nozzle.tag = 'fan_nozzle'
    # setup
    nozzle.polytropic_efficiency = 0.95
    nozzle.pressure_ratio = 0.99
    # add to network
    turbofan.append(nozzle)

    # ------------------------------------------------------------------
    #  Component 10 - Fan

    # instantiate
    fan = SUAVE.Components.Energy.Converters.Fan()
    fan.tag = 'fan'
    # setup
    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio = 1.58
    # add to network
    turbofan.append(fan)

    # ------------------------------------------------------------------
    #Component 10 : thrust (to compute the thrust)
    thrust = SUAVE.Components.Energy.Processes.Thrust()
    thrust.tag = 'compute_thrust'

    #total design thrust (includes all the engines)
    thrust.total_design = 2.0 * 512000 * Units.N
    thrust.bypass_ratio = 8.4

    #design sizing conditions
    altitude = 0. * Units.km
    mach_number = 0.01
    isa_deviation = 0.

    # add to network
    turbofan.thrust = thrust

    #size the turbofan
    turbofan_sizing(turbofan, mach_number, altitude)
    #turbofan.size(mach_number,altitude)

    #computing the engine length and diameter
    for nac in vehicle.nacelles:
        compute_turbofan_geometry(turbofan, nac)

    vehicle.append_component(turbofan)

    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle
Пример #8
0
def vehicle_setup():

    # ------------------------------------------------------------------
    #   Initialize the Vehicle
    # ------------------------------------------------------------------

    vehicle = SUAVE.Vehicle()
    vehicle.tag = 'X57_Maxwell_Mod2'

    # ------------------------------------------------------------------
    #   Vehicle-level Properties
    # ------------------------------------------------------------------

    # mass properties
    vehicle.mass_properties.max_takeoff = 2550. * Units.pounds
    vehicle.mass_properties.takeoff = 2550. * Units.pounds
    vehicle.mass_properties.max_zero_fuel = 2550. * Units.pounds
    vehicle.envelope.ultimate_load = 5.7
    vehicle.envelope.limit_load = 3.8
    vehicle.reference_area = 14.76
    vehicle.passengers = 4
    vehicle.systems.control = "fully powered"
    vehicle.systems.accessories = "commuter"

    cruise_speed = 135. * Units['mph']
    altitude = 2500. * Units.ft
    atmo = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    freestream = atmo.compute_values(0.)
    freestream0 = atmo.compute_values(altitude)
    mach_number = (cruise_speed / freestream.speed_of_sound)[0][0]
    vehicle.design_dynamic_pressure = (.5 * freestream0.density *
                                       (cruise_speed * cruise_speed))[0][0]
    vehicle.design_mach_number = mach_number

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------
    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'
    wing.sweeps.quarter_chord = 0.0 * Units.deg
    wing.thickness_to_chord = 0.12
    wing.areas.reference = 14.76
    wing.spans.projected = 11.4
    wing.chords.root = 1.46
    wing.chords.tip = 0.92
    wing.chords.mean_aerodynamic = 1.19
    wing.taper = wing.chords.root / wing.chords.tip
    wing.aspect_ratio = wing.spans.projected**2. / wing.areas.reference
    wing.twists.root = 3.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[2.93, 0., 1.01]]
    wing.aerodynamic_center = [3., 0., 1.01]
    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = True
    wing.winglet_fraction = 0.0
    wing.dynamic_pressure_ratio = 1.0
    airfoil = SUAVE.Components.Airfoils.Airfoil()
    airfoil.coordinate_file = '../Vehicles/Airfoils/NACA_63_412.txt'

    cg_x = wing.origin[0][0] + 0.25 * wing.chords.mean_aerodynamic
    cg_z = wing.origin[0][2] - 0.2 * wing.chords.mean_aerodynamic
    vehicle.mass_properties.center_of_gravity = [
        [cg_x, 0., cg_z]
    ]  # SOURCE: Design and aerodynamic analysis of a twin-engine commuter aircraft

    # Wing Segments
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'inboard'
    segment.percent_span_location = 0.0
    segment.twist = 3. * Units.degrees
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = 0.12
    segment.append_airfoil(airfoil)
    wing.append_segment(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'outboard'
    segment.percent_span_location = 0.5438
    segment.twist = 2. * Units.degrees
    segment.root_chord_percent = 1.
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = 0.12
    segment.append_airfoil(airfoil)
    wing.append_segment(segment)

    # Wing Segments
    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'winglet'
    segment.percent_span_location = 0.98
    segment.twist = 1. * Units.degrees
    segment.root_chord_percent = 0.630
    segment.dihedral_outboard = 75. * Units.degrees
    segment.sweeps.quarter_chord = 82. * Units.degrees
    segment.thickness_to_chord = 0.12
    segment.append_airfoil(airfoil)
    wing.append_segment(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'tip'
    segment.percent_span_location = 1.
    segment.twist = 0. * Units.degrees
    segment.root_chord_percent = 0.12
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    segment.thickness_to_chord = 0.12
    segment.append_airfoil(airfoil)
    wing.append_segment(segment)

    # Fill out more segment properties automatically
    wing = wing_segmented_planform(wing)

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Horizontal Stabilizer
    # ------------------------------------------------------------------
    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'horizontal_stabilizer'
    wing.sweeps.quarter_chord = 0.0 * Units.deg
    wing.thickness_to_chord = 0.12
    wing.areas.reference = 2.540
    wing.spans.projected = 3.3 * Units.meter
    wing.sweeps.quarter_chord = 0 * Units.deg
    wing.chords.root = 0.769 * Units.meter
    wing.chords.tip = 0.769 * Units.meter
    wing.chords.mean_aerodynamic = 0.769 * Units.meter
    wing.taper = 1.
    wing.aspect_ratio = wing.spans.projected**2. / wing.areas.reference
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[7.7, 0., 0.25]]
    wing.aerodynamic_center = [7.8, 0., 0.25]
    wing.vertical = False
    wing.winglet_fraction = 0.0
    wing.symmetric = True
    wing.high_lift = False
    wing.dynamic_pressure_ratio = 0.9

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #   Vertical Stabilizer
    # ------------------------------------------------------------------
    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'vertical_stabilizer'
    wing.sweeps.quarter_chord = 25. * Units.deg
    wing.thickness_to_chord = 0.12
    wing.areas.reference = 2.258 * Units['meters**2']
    wing.spans.projected = 1.854 * Units.meter
    wing.chords.root = 1.6764 * Units.meter
    wing.chords.tip = 0.6858 * Units.meter
    wing.chords.mean_aerodynamic = 1.21 * Units.meter
    wing.taper = wing.chords.tip / wing.chords.root
    wing.aspect_ratio = wing.spans.projected**2. / wing.areas.reference
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.origin = [[6.75, 0, 0.623]]
    wing.aerodynamic_center = [0.508, 0, 0]
    wing.vertical = True
    wing.symmetric = False
    wing.t_tail = False
    wing.winglet_fraction = 0.0
    wing.dynamic_pressure_ratio = 1.0

    # add to vehicle
    vehicle.append_component(wing)

    # ------------------------------------------------------------------
    #  Fuselage
    # ------------------------------------------------------------------
    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'
    fuselage.seats_abreast = 2.
    fuselage.fineness.nose = 1.6
    fuselage.fineness.tail = 2.
    fuselage.lengths.nose = 60. * Units.inches
    fuselage.lengths.tail = 161. * Units.inches
    fuselage.lengths.cabin = 105. * Units.inches
    fuselage.lengths.total = 332.2 * Units.inches
    fuselage.lengths.fore_space = 0.
    fuselage.lengths.aft_space = 0.
    fuselage.width = 42. * Units.inches
    fuselage.heights.maximum = 62. * Units.inches
    fuselage.heights.at_quarter_length = 62. * Units.inches
    fuselage.heights.at_three_quarters_length = 62. * Units.inches
    fuselage.heights.at_wing_root_quarter_chord = 23. * Units.inches
    fuselage.areas.side_projected = 8000. * Units.inches**2.
    fuselage.areas.wetted = 30000. * Units.inches**2.
    fuselage.areas.front_projected = 42. * 62. * Units.inches**2.
    fuselage.effective_diameter = 50. * Units.inches

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_0'
    segment.percent_x_location = 0
    segment.percent_z_location = 0
    segment.height = 0.01
    segment.width = 0.01
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_1'
    segment.percent_x_location = 0.007279116466
    segment.percent_z_location = 0.002502014453
    segment.height = 0.1669064748
    segment.width = 0.2780205877
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_2'
    segment.percent_x_location = 0.01941097724
    segment.percent_z_location = 0.001216095397
    segment.height = 0.3129496403
    segment.width = 0.4365777215
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_3'
    segment.percent_x_location = 0.06308567604
    segment.percent_z_location = 0.007395489231
    segment.height = 0.5841726619
    segment.width = 0.6735119903
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_4'
    segment.percent_x_location = 0.1653761217
    segment.percent_z_location = 0.02891281352
    segment.height = 1.064028777
    segment.width = 1.067200529
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_5'
    segment.percent_x_location = 0.2426372155
    segment.percent_z_location = 0.04214148761
    segment.height = 1.293766653
    segment.width = 1.183058255
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_6'
    segment.percent_x_location = 0.2960174029
    segment.percent_z_location = 0.04705241831
    segment.height = 1.377026712
    segment.width = 1.181540054
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_7'
    segment.percent_x_location = 0.3809404284
    segment.percent_z_location = 0.05313580461
    segment.height = 1.439568345
    segment.width = 1.178218989
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_8'
    segment.percent_x_location = 0.5046854083
    segment.percent_z_location = 0.04655492473
    segment.height = 1.29352518
    segment.width = 1.054390707
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_9'
    segment.percent_x_location = 0.6454149933
    segment.percent_z_location = 0.03741966266
    segment.height = 0.8971223022
    segment.width = 0.8501926505
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_10'
    segment.percent_x_location = 0.985107095
    segment.percent_z_location = 0.04540283436
    segment.height = 0.2920863309
    segment.width = 0.2012565415
    fuselage.Segments.append(segment)

    # Segment
    segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    segment.tag = 'segment_11'
    segment.percent_x_location = 1
    segment.percent_z_location = 0.04787575562
    segment.height = 0.1251798561
    segment.width = 0.1206021048
    fuselage.Segments.append(segment)

    # add to vehicle
    vehicle.append_component(fuselage)

    # ------------------------------------------------------------------
    #   Nacelles
    # ------------------------------------------------------------------
    nacelle = SUAVE.Components.Nacelles.Nacelle()
    nacelle.tag = 'nacelle_1'
    nacelle.length = 2
    nacelle.diameter = 42 * Units.inches
    nacelle.areas.wetted = 0.01 * (2 * np.pi * 0.01 / 2)
    nacelle.origin = [[2.5, 2.5, 1.0]]
    nacelle.flow_through = False

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_1'
    nac_segment.percent_x_location = 0.0
    nac_segment.height = 0.0
    nac_segment.width = 0.0
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_2'
    nac_segment.percent_x_location = 0.1
    nac_segment.height = 0.5
    nac_segment.width = 0.65
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_3'
    nac_segment.percent_x_location = 0.3
    nac_segment.height = 0.52
    nac_segment.width = 0.7
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_4'
    nac_segment.percent_x_location = 0.5
    nac_segment.height = 0.5
    nac_segment.width = 0.65
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_5'
    nac_segment.percent_x_location = 0.7
    nac_segment.height = 0.4
    nac_segment.width = 0.6
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_6'
    nac_segment.percent_x_location = 0.9
    nac_segment.height = 0.3
    nac_segment.width = 0.5
    nacelle.append_segment(nac_segment)

    nac_segment = SUAVE.Components.Lofted_Body_Segment.Segment()
    nac_segment.tag = 'segment_7'
    nac_segment.percent_x_location = 1.0
    nac_segment.height = 0.0
    nac_segment.width = 0.0
    nacelle.append_segment(nac_segment)

    vehicle.append_component(nacelle)

    nacelle_2 = deepcopy(nacelle)
    nacelle_2.tag = 'nacelle_2'
    nacelle_2.origin = [[2.5, -2.5, 1.0]]
    vehicle.append_component(nacelle_2)

    #---------------------------------------------------------------------------------------------
    # DEFINE PROPELLER
    #---------------------------------------------------------------------------------------------
    # build network
    net = Battery_Propeller()
    net.number_of_propeller_engines = 2.
    net.identical_propellers = True

    # Component 1 the ESC
    esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller()
    esc.efficiency = 0.95  # Gundlach for brushless motors
    net.esc = esc

    # Component 2 the Propeller
    prop = SUAVE.Components.Energy.Converters.Propeller()
    prop.tag = 'propeller_1'
    prop.number_of_blades = 3.0
    prop.freestream_velocity = 150. * Units.knots
    prop.angular_velocity = 2400. * Units.rpm
    prop.tip_radius = 1.72 / 2
    prop.hub_radius = 10. * Units.inches
    prop.design_Cl = 0.8
    prop.design_altitude = 9000. * Units.feet
    prop.design_power = 98 * 0.65 * Units.hp  # assume 65 BHP at cruise
    prop.origin = [[2., 2.5, 0.784]]
    prop.rotation = -1
    prop.symmetry = True
    prop.variable_pitch = True
    prop.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt']
    prop.airfoil_polars = [[
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_50000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_100000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_200000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_500000.txt',
        '../Vehicles/Airfoils/Polars/NACA_4412_polar_Re_1000000.txt'
    ]]

    prop.airfoil_polar_stations = [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    ]
    prop = propeller_design(prop, number_of_airfoil_section_points=102)

    prop_left = deepcopy(prop)
    prop_left.tag = 'propeller_2'
    prop_left.origin = [[2., -2.5, 0.784]]
    prop_left.rotation = 1

    net.propellers.append(prop)
    net.propellers.append(prop_left)

    # Component 3 the Battery
    bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion_LiNiMnCoO2_18650(
    )
    bat.mass_properties.mass = 500. * Units.kg
    bat.max_voltage = 400.
    initialize_from_mass(bat)
    net.battery = bat
    net.voltage = bat.max_voltage

    # Component 4 Miscellaneous Systems
    sys = SUAVE.Components.Systems.System()
    sys.mass_properties.mass = 5  # kg

    # Component 5 the Motor
    motor = SUAVE.Components.Energy.Converters.Motor()
    motor.efficiency = 0.95
    motor.gearbox_efficiency = 1.
    motor.origin = [[2., 2.5, 0.95]]
    motor.nominal_voltage = bat.max_voltage * 0.8
    motor.propeller_radius = prop.tip_radius
    motor.no_load_current = 0.1
    motor = size_optimal_motor(motor, prop)
    motor.mass_properties.mass = 10. * Units.kg

    # append right motor
    net.propeller_motors.append(motor)

    # append left motor
    motor_left = deepcopy(motor)
    motor_left.origin = [[2., -2.5, 0.95]]
    net.propeller_motors.append(motor_left)

    # Component 6 the Payload
    payload = SUAVE.Components.Energy.Peripherals.Payload()
    payload.power_draw = 10.  # Watts
    payload.mass_properties.mass = 1.0 * Units.kg
    net.payload = payload

    # Component 7 the Avionics
    avionics = SUAVE.Components.Energy.Peripherals.Avionics()
    avionics.power_draw = 20.  # Watts
    net.avionics = avionics

    # add the solar network to the vehicle
    vehicle.append_component(net)

    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle