def vertical_tail_planform_raymer(vertical_stabilizer, wing, l_vt, c_vt):
    """Adjusts reference area before calling generic wing planform function to compute wing planform values.

    Assumptions:
    None

    Source:
    Raymer

    Inputs:
    vertical_stabilizer                    [SUAVE data structure]
    wing                                   [SUAVE data structure]  (should be the main wing)
    l_vt                                   [m] length from wing mean aerodynamic chord (MAC) to horizontal stabilizer MAC
    c_vt                                   [-] horizontal tail coefficient (Raymer specific) .02 = Sailplane, .04 = homebuilt, 
                                               .04 = GA single engine, .07 = GA twin engine, .04 = agricultural, 
                                               .08 = twin turboprop, .06 = flying boat, .06 = jet trainer, .07 = jet fighter
                                               .08 = military cargo/bomber, .09 = jet transport

    Outputs:
    vertical_stabilier.areas.reference     [m^2]
    Other changes to vertical_stabilizer (see wing_planform)

    Properties Used:
    N/A
    """

    vertical_stabilizer.areas.reference = wing.spans.projected * c_vt * wing.areas.reference / l_vt

    wing_planform(vertical_stabilizer)

    return 0
def vertical_tail_planform_raymer(vertical_stabilizer, wing,  l_vt,c_vt):
    """
    by M. Vegh
    Based on a tail sizing correlation from Raymer
    inputs:
    Vtail =vertical stabilizer
    Wing  =main wing
    l_vt  =length from wing mac to vtail mac [m]
    c_vt  =vertical tail coefficient
    
    sample c_ht values: .02=Sailplane, .04=homebuilt, .04=GA single engine, .07 GA twin engine
    .04=agricultural, .08=twin turboprop, .06=flying boat, .06=jet trainer, .07=jet fighter
    .08= military cargo/bomber, .09= jet transport
    """
    vertical_stabilizer.areas.reference = wing.spans.projected*c_vt*wing.areas.reference/l_vt
  
    wing_planform(vertical_stabilizer)
    
    return 0
예제 #3
0
def vertical_tail_planform_raymer(vertical_stabilizer, wing, l_vt, c_vt):
    """
    by M. Vegh
    Based on a tail sizing correlation from Raymer
    inputs:
    Vtail =vertical stabilizer
    Wing  =main wing
    l_vt  =length from wing mac to vtail mac [m]
    c_vt  =vertical tail coefficient
    
    sample c_ht values: .02=Sailplane, .04=homebuilt, .04=GA single engine, .07 GA twin engine
    .04=agricultural, .08=twin turboprop, .06=flying boat, .06=jet trainer, .07=jet fighter
    .08= military cargo/bomber, .09= jet transport
    """
    vertical_stabilizer.areas.reference = wing.spans.projected * c_vt * wing.areas.reference / l_vt

    wing_planform(vertical_stabilizer)

    return 0
예제 #4
0
def B737_full_setup():

    # vehicle data
    vehicle = B737_vehicle_setup()
    vehicle.wings.main_wing.control_surfaces.flap.configuration_type = 'triple_slotted'
    vehicle.wings.main_wing.high_lift = True
    vehicle.wings.main_wing = wing_planform(vehicle.wings.main_wing)

    # Set up configs
    configs = B737_configs_setup(vehicle)

    # vehicle analyses
    configs_analyses = analyses_setup(configs)

    # mission analyses
    mission = B737_mission_setup(configs_analyses)
    missions_analyses = B737_missions_setup(mission, configs_analyses)

    analyses = SUAVE.Analyses.Analysis.Container()
    analyses.configs = configs_analyses
    analyses.missions = missions_analyses

    return configs, analyses
예제 #5
0
def vehicle_setup():

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

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

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

    # mass properties (http://www.embraercommercialaviation.com/AircraftPDF/E190_Weights.pdf)
    vehicle.mass_properties.max_takeoff = 51800.  # kg
    vehicle.mass_properties.operating_empty = 27837.  # kg
    vehicle.mass_properties.takeoff = 51800.  # kg
    vehicle.mass_properties.max_zero_fuel = 40900.  # kg
    vehicle.mass_properties.max_payload = 13063.  # kg
    vehicle.mass_properties.max_fuel = 12971.  # kg
    vehicle.mass_properties.cargo = 0.0  # kg

    vehicle.mass_properties.center_of_gravity = [[16.8, 0, 1.6]]
    vehicle.mass_properties.moments_of_inertia.tensor = [[10**5, 0, 0],
                                                         [
                                                             0,
                                                             10**6,
                                                             0,
                                                         ], [0, 0, 10**7]]

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

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

    # ------------------------------------------------------------------
    #   Main Wing
    # ------------------------------------------------------------------
    wing = SUAVE.Components.Wings.Main_Wing()
    wing.tag = 'main_wing'
    wing.areas.reference = 92.0
    wing.aspect_ratio = 8.4
    wing.chords.root = 6.2
    wing.chords.tip = 1.44
    wing.sweeps.quarter_chord = 23.0 * Units.deg
    wing.thickness_to_chord = 0.11
    wing.taper = 0.28
    wing.dihedral = 5.00 * Units.deg
    wing.spans.projected = 28.72
    wing.origin = [[13.0, 0, -1.50]]
    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = True
    wing.areas.exposed = 0.80 * wing.areas.wetted
    wing.twists.root = 2.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.dynamic_pressure_ratio = 1.0

    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 = .11
    segment.dihedral_outboard = 5. * Units.degrees
    segment.sweeps.quarter_chord = 20.6 * Units.degrees
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'yehudi'
    segment.percent_span_location = 0.348
    segment.twist = (4. - segment.percent_span_location * 4.) * Units.deg
    segment.root_chord_percent = 0.60
    segment.thickness_to_chord = .11
    segment.dihedral_outboard = 4 * Units.degrees
    segment.sweeps.quarter_chord = 24.1 * Units.degrees
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'section_2'
    segment.percent_span_location = 0.961
    segment.twist = (4. - segment.percent_span_location * 4.) * Units.deg
    segment.root_chord_percent = 0.25
    segment.thickness_to_chord = .11
    segment.dihedral_outboard = 70. * Units.degrees
    segment.sweeps.quarter_chord = 50. * Units.degrees
    wing.Segments.append(segment)

    segment = SUAVE.Components.Wings.Segment()
    segment.tag = 'Tip'
    segment.percent_span_location = 1.
    segment.twist = (4. - segment.percent_span_location * 4.) * Units.deg
    segment.root_chord_percent = 0.070
    segment.thickness_to_chord = .11
    segment.dihedral_outboard = 0.
    segment.sweeps.quarter_chord = 0.
    wing.Segments.append(segment)

    # control surfaces -------------------------------------------
    flap = SUAVE.Components.Wings.Control_Surfaces.Flap()
    flap.tag = 'flap'
    flap.span_fraction_start = 0.11
    flap.span_fraction_end = 0.85
    flap.deflection = 0.0 * Units.deg
    flap.chord_fraction = 0.28
    flap.configuration_type = 'double_slotted'
    wing.append_control_surface(flap)

    slat = SUAVE.Components.Wings.Control_Surfaces.Slat()
    slat.tag = 'slat'
    slat.span_fraction_start = 0.324
    slat.span_fraction_end = 0.963
    slat.deflection = 1.0 * Units.deg
    slat.chord_fraction = 0.1
    wing.append_control_surface(slat)

    wing = wing_planform(wing)

    wing.areas.exposed = 0.80 * wing.areas.wetted
    wing.twists.root = 2.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.dynamic_pressure_ratio = 1.0

    # add to vehicle
    vehicle.append_component(wing)

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

    wing = SUAVE.Components.Wings.Horizontal_Tail()
    wing.tag = 'horizontal_stabilizer'
    wing.areas.reference = 26.0
    wing.aspect_ratio = 5.5
    wing.sweeps.quarter_chord = 34.5 * Units.deg
    wing.thickness_to_chord = 0.11
    wing.taper = 0.11
    wing.dihedral = 8.4 * Units.degrees
    wing.origin = [[31, 0, 0.44]]
    wing.vertical = False
    wing.symmetric = True
    wing.high_lift = False
    wing = wing_planform(wing)
    wing.areas.exposed = 0.9 * wing.areas.wetted
    wing.twists.root = 2.0 * Units.degrees
    wing.twists.tip = 2.0 * Units.degrees
    wing.dynamic_pressure_ratio = 0.90

    # add to vehicle
    vehicle.append_component(wing)

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

    wing = SUAVE.Components.Wings.Vertical_Tail()
    wing.tag = 'vertical_stabilizer'
    wing.areas.reference = 16.0
    wing.aspect_ratio = 1.7
    wing.sweeps.quarter_chord = 35. * Units.deg
    wing.thickness_to_chord = 0.11
    wing.taper = 0.31
    wing.dihedral = 0.00
    wing.origin = [[30.4, 0, 1.675]]
    wing.vertical = True
    wing.symmetric = False
    wing.high_lift = False
    wing = wing_planform(wing)
    wing.areas.exposed = 0.9 * wing.areas.wetted
    wing.twists.root = 0.0 * Units.degrees
    wing.twists.tip = 0.0 * Units.degrees
    wing.dynamic_pressure_ratio = 1.00

    # add to vehicle
    vehicle.append_component(wing)

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

    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag = 'fuselage'
    fuselage.origin = [[0, 0, 0]]
    fuselage.number_coach_seats = vehicle.passengers
    fuselage.seats_abreast = 4
    fuselage.seat_pitch = 30. * Units.inches

    fuselage.fineness.nose = 1.28
    fuselage.fineness.tail = 3.48

    fuselage.lengths.nose = 6.0
    fuselage.lengths.tail = 9.0
    fuselage.lengths.cabin = 21.24
    fuselage.lengths.total = 36.24
    fuselage.lengths.fore_space = 0.
    fuselage.lengths.aft_space = 0.

    fuselage.width = 3.01 * Units.meters

    fuselage.heights.maximum = 3.35
    fuselage.heights.at_quarter_length = 3.35
    fuselage.heights.at_three_quarters_length = 3.35
    fuselage.heights.at_wing_root_quarter_chord = 3.35

    fuselage.areas.side_projected = 239.20
    fuselage.areas.wetted = 327.01
    fuselage.areas.front_projected = 8.0110

    fuselage.effective_diameter = 3.18

    fuselage.differential_pressure = 10**5 * Units.pascal  # Maximum differential pressure

    # add to vehicle
    vehicle.append_component(fuselage)

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

    #initialize the gas turbine network
    gt_engine = SUAVE.Components.Energy.Networks.Turbofan()
    gt_engine.tag = 'turbofan'
    gt_engine.origin = [[12.0, 4.38, -2.1], [12.0, -4.38, -2.1]]
    gt_engine.number_of_engines = 2.0
    gt_engine.bypass_ratio = 5.4
    gt_engine.engine_length = 2.71
    gt_engine.nacelle_diameter = 2.05
    gt_engine.inlet_diameter = 2.0

    #compute engine areas)
    Amax = (np.pi / 4.) * gt_engine.nacelle_diameter**2.
    Awet = 1.1 * np.pi * gt_engine.nacelle_diameter * gt_engine.engine_length  # 1.1 is simple coefficient
    #Assign engine area
    gt_engine.areas.wetted = Awet
    #set the working fluid for the network
    working_fluid = SUAVE.Attributes.Gases.Air()

    #add working fluid to the network
    gt_engine.working_fluid = working_fluid

    #Component 1 : ram,  to convert freestream static to stagnation quantities
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'
    #add ram to the network
    gt_engine.ram = ram

    #Component 2 : inlet nozzle
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet nozzle'
    inlet_nozzle.polytropic_efficiency = 0.98
    inlet_nozzle.pressure_ratio = 0.98
    #add inlet nozzle to the network
    gt_engine.inlet_nozzle = inlet_nozzle

    #Component 3 :low pressure compressor
    low_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor()
    low_pressure_compressor.tag = 'lpc'
    low_pressure_compressor.polytropic_efficiency = 0.91
    low_pressure_compressor.pressure_ratio = 1.9
    #add low pressure compressor to the network
    gt_engine.low_pressure_compressor = low_pressure_compressor

    #Component 4 :high pressure compressor
    high_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor()
    high_pressure_compressor.tag = 'hpc'
    high_pressure_compressor.polytropic_efficiency = 0.91
    high_pressure_compressor.pressure_ratio = 10.0
    #add the high pressure compressor to the network
    gt_engine.high_pressure_compressor = high_pressure_compressor

    #Component 5 :low pressure turbine
    low_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine()
    low_pressure_turbine.tag = 'lpt'
    low_pressure_turbine.mechanical_efficiency = 0.99
    low_pressure_turbine.polytropic_efficiency = 0.93
    #add low pressure turbine to the network
    gt_engine.low_pressure_turbine = low_pressure_turbine

    #Component 5 :high pressure turbine
    high_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine()
    high_pressure_turbine.tag = 'hpt'
    high_pressure_turbine.mechanical_efficiency = 0.99
    high_pressure_turbine.polytropic_efficiency = 0.93
    #add the high pressure turbine to the network
    gt_engine.high_pressure_turbine = high_pressure_turbine

    #Component 6 :combustor
    combustor = SUAVE.Components.Energy.Converters.Combustor()
    combustor.tag = 'Comb'
    combustor.efficiency = 0.99
    combustor.alphac = 1.0
    combustor.turbine_inlet_temperature = 1500
    combustor.pressure_ratio = 0.95
    combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A()
    #add the combustor to the network
    gt_engine.combustor = combustor

    #Component 7 :core nozzle
    core_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    core_nozzle.tag = 'core nozzle'
    core_nozzle.polytropic_efficiency = 0.95
    core_nozzle.pressure_ratio = 0.99
    #add the core nozzle to the network
    gt_engine.core_nozzle = core_nozzle

    #Component 8 :fan nozzle
    fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()
    fan_nozzle.tag = 'fan nozzle'
    fan_nozzle.polytropic_efficiency = 0.95
    fan_nozzle.pressure_ratio = 0.99
    #add the fan nozzle to the network
    gt_engine.fan_nozzle = fan_nozzle

    #Component 9 : fan
    fan = SUAVE.Components.Energy.Converters.Fan()
    fan.tag = 'fan'
    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio = 1.7
    #add the fan to the network
    gt_engine.fan = 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 = 37278.0 * Units.N  #Newtons

    #design sizing conditions
    altitude = 35000.0 * Units.ft
    mach_number = 0.78
    isa_deviation = 0.
    # add thrust to the network
    gt_engine.thrust = thrust

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

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

    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
    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle
def simple_sizing(interface):
      
    from SUAVE.Methods.Geometry.Two_Dimensional.Planform import wing_planform

    # unpack
    configs  = interface.configs
    analyses = interface.analyses        
    base = configs.base
    base.pull_base()
    
##    # wing areas
##    for wing in base.wings:
##        wing.areas.wetted   = 2.00 * wing.areas.reference
##        wing.areas.affected = 0.60 * wing.areas.reference
##        wing.areas.exposed  = 0.75 * wing.areas.wetted

    # wing simple sizing function
    # size main wing
    base.wings['main_wing'] = wing_planform(base.wings['main_wing'])
    # reference values for empennage scaling, keeping tail coeff. volumes constants
    Sref = base.wings['main_wing'].areas.reference
    span = base.wings['main_wing'].spans.projected
    CMA  = base.wings['main_wing'].chords.mean_aerodynamic    
    Sh = 32.48 * (Sref * CMA)  / (124.86 * 4.1535)  # hardcoded values represent the reference airplane data
    Sv = 26.40 * (Sref * span) / (124.86 * 35.35)   # hardcoded values represent the reference airplane data
        
    # empennage scaling
    base.wings['horizontal_stabilizer'].areas.reference = Sh
    base.wings['vertical_stabilizer'].areas.reference = Sv
    # sizing of new empennages
    base.wings['horizontal_stabilizer'] = wing_planform(base.wings['horizontal_stabilizer']) 
    base.wings['vertical_stabilizer']   = wing_planform(base.wings['vertical_stabilizer'])   
    
    # wing areas
    for wing in base.wings:
        wing.areas.wetted   = 2.00 * wing.areas.reference
        wing.areas.affected = 0.60 * wing.areas.reference
        wing.areas.exposed  = 0.75 * wing.areas.wetted
         
    # fuselage seats
    base.fuselages['fuselage'].number_coach_seats = base.passengers        
    
    # Weight estimation
    breakdown = analyses.configs.base.weights.evaluate()
    
    # pack
    base.mass_properties.breakdown = breakdown
    base.mass_properties.operating_empty = breakdown.empty
       
    # diff the new data
    base.store_diff()
    
    # Update all configs with new base data    
    for config in configs:
        config.pull_base()
    
    # ------------------------------------------------------------------
    #   Landing Configuration
    # ------------------------------------------------------------------
    landing = configs.landing
    
    # make sure base data is current
    landing.pull_base()
    
    # landing weight
    landing.mass_properties.landing = 0.85 * base.mass_properties.takeoff
    
    # diff the new data
    landing.store_diff()    
        
    # done!
    return
예제 #7
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
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
예제 #9
0
파일: Embraer_190.py 프로젝트: michK/SUAVE
def vehicle_setup():

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

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

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

    # mass properties (http://www.embraercommercialaviation.com/AircraftPDF/E190_Weights.pdf)
    vehicle.mass_properties.max_takeoff               = 51800.   # kg
    vehicle.mass_properties.operating_empty           = 27837.   # kg
    vehicle.mass_properties.takeoff                   = 51800.   # kg
    vehicle.mass_properties.max_zero_fuel             = 40900.   # kg
    vehicle.mass_properties.max_payload               = 13063.   # kg
    vehicle.mass_properties.max_fuel                  = 12971.   # kg
    vehicle.mass_properties.cargo                     =     0.0  # kg

    vehicle.mass_properties.center_of_gravity         = [16.8, 0, 1.6]#[[60 * Units.feet, 0, 0]]  # Not correct
    vehicle.mass_properties.moments_of_inertia.tensor = [[10 ** 5, 0, 0],[0, 10 ** 6, 0,],[0,0, 10 ** 7]] # Not Correct

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

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

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

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

    wing.areas.reference         = 92.0
    wing.aspect_ratio            = 8.4
    wing.sweeps.quarter_chord    = 23.0 * Units.deg
    wing.thickness_to_chord      = 0.11
    wing.taper                   = 0.28
    wing.dihedral                = 5.00
    
    wing.origin                  = [13,0,0] 
    wing.vertical                = False
    wing.symmetric               = True       
    wing.high_lift               = True
    wing.flaps.type              = 'double_slotted'
    wing.flaps.chord             = 0.28
    wing.flaps.span_start        = 0.11
    wing.flaps.span_end          = 0.85
    
    wing = wing_planform(wing)
    wing.areas.exposed           = 0.80 * wing.areas.wetted
        
    wing.twists.root             = 2.0 * Units.degrees
    wing.twists.tip              = 0.0 * Units.degrees    
    wing.span_efficiency         = 1.0
    wing.dynamic_pressure_ratio  = 1.0

    # add to vehicle
    vehicle.append_component(wing)

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

    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'horizontal_stabilizer'
    
    wing.areas.reference         = 26.0
    wing.aspect_ratio            = 5.5
    wing.sweeps.quarter_chord    = 34.5 * Units.deg
    wing.thickness_to_chord      = 0.11
    wing.taper                   = 0.11
    wing.dihedral                = 8.00
    
    wing.origin                  = [32,0,0] 
    wing.vertical                = False
    wing.symmetric               = True       
    wing.high_lift               = False
    
    wing = wing_planform(wing)
    wing.areas.exposed           = 0.9 * wing.areas.wetted
    
    wing.twists.root             = 2.0 * Units.degrees
    wing.twists.tip              = 2.0 * Units.degrees    
    wing.span_efficiency         = 0.90
    wing.dynamic_pressure_ratio  = 0.90

    # add to vehicle
    vehicle.append_component(wing)

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

    wing = SUAVE.Components.Wings.Wing()
    wing.tag = 'vertical_stabilizer'
    
    wing.areas.reference         = 16.0
    wing.aspect_ratio            =  1.7
    wing.sweeps.quarter_chord    = 35. * Units.deg
    wing.thickness_to_chord      = 0.11
    wing.taper                   = 0.31
    wing.dihedral                = 0.00
    
    wing.origin                  = [32,0,0] 
    wing.vertical                = True
    wing.symmetric               = False       
    wing.high_lift               = False
    
    wing = wing_planform(wing)
    wing.areas.exposed           = 0.9 * wing.areas.wetted
    
    wing.twists.root             = 0.0 * Units.degrees
    wing.twists.tip              = 0.0 * Units.degrees    
    wing.span_efficiency         = 0.90
    wing.dynamic_pressure_ratio  = 1.00
    
    # add to vehicle
    vehicle.append_component(wing)
    
    # ------------------------------------------------------------------
    #  Fuselage
    # ------------------------------------------------------------------

    fuselage = SUAVE.Components.Fuselages.Fuselage()
    fuselage.tag    = 'fuselage'
    fuselage.origin = [[0,0,0]]
    fuselage.number_coach_seats    = vehicle.passengers
    fuselage.seats_abreast         = 4
    fuselage.seat_pitch            = 0.7455

    fuselage.fineness.nose         = 2.0
    fuselage.fineness.tail         = 3.0

    fuselage.lengths.nose          = 6.0
    fuselage.lengths.tail          = 9.0
    fuselage.lengths.cabin         = 21.24
    fuselage.lengths.total         = 36.24
    fuselage.lengths.fore_space    = 0.
    fuselage.lengths.aft_space     = 0.

    fuselage.width                 = 3.18

    fuselage.heights.maximum       = 4.18    
    fuselage.heights.at_quarter_length          = 3.18 
    fuselage.heights.at_three_quarters_length   = 3.18 
    fuselage.heights.at_wing_root_quarter_chord = 4.00 

    fuselage.areas.side_projected  = 239.20
    fuselage.areas.wetted          = 327.01
    fuselage.areas.front_projected = 8.0110

    fuselage.effective_diameter    = 3.18

    fuselage.differential_pressure = 10**5 * Units.pascal    # Maximum differential pressure

    # add to vehicle
    vehicle.append_component(fuselage)

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


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

    gt_engine.number_of_engines = 2.0
    gt_engine.bypass_ratio      = 5.4
    gt_engine.engine_length     = 2.71
    gt_engine.nacelle_diameter  = 2.05
    
    #compute engine areas)
    Amax    = (np.pi/4.)*gt_engine.nacelle_diameter**2.
    Awet    = 1.1*np.pi*gt_engine.nacelle_diameter*gt_engine.engine_length # 1.1 is simple coefficient
    
    #Assign engine areas

    gt_engine.areas.wetted  = Awet
    
    #set the working fluid for the network
    working_fluid               = SUAVE.Attributes.Gases.Air()

    #add working fluid to the network
    gt_engine.working_fluid = working_fluid


    #Component 1 : ram,  to convert freestream static to stagnation quantities
    ram = SUAVE.Components.Energy.Converters.Ram()
    ram.tag = 'ram'

    #add ram to the network
    gt_engine.ram = ram


    #Component 2 : inlet nozzle
    inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle()
    inlet_nozzle.tag = 'inlet nozzle'

    inlet_nozzle.polytropic_efficiency = 0.98
    inlet_nozzle.pressure_ratio        = 0.98

    #add inlet nozzle to the network
    gt_engine.inlet_nozzle = inlet_nozzle


    #Component 3 :low pressure compressor    
    low_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor()    
    low_pressure_compressor.tag = 'lpc'

    low_pressure_compressor.polytropic_efficiency = 0.91
    low_pressure_compressor.pressure_ratio        = 1.9    

    #add low pressure compressor to the network    
    gt_engine.low_pressure_compressor = low_pressure_compressor

    #Component 4 :high pressure compressor  
    high_pressure_compressor = SUAVE.Components.Energy.Converters.Compressor()    
    high_pressure_compressor.tag = 'hpc'

    high_pressure_compressor.polytropic_efficiency = 0.91
    high_pressure_compressor.pressure_ratio        = 10.0   

    #add the high pressure compressor to the network    
    gt_engine.high_pressure_compressor = high_pressure_compressor

    #Component 5 :low pressure turbine  
    low_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine()   
    low_pressure_turbine.tag='lpt'

    low_pressure_turbine.mechanical_efficiency = 0.99
    low_pressure_turbine.polytropic_efficiency = 0.93

    #add low pressure turbine to the network    
    gt_engine.low_pressure_turbine = low_pressure_turbine

    #Component 5 :high pressure turbine  
    high_pressure_turbine = SUAVE.Components.Energy.Converters.Turbine()   
    high_pressure_turbine.tag='hpt'

    high_pressure_turbine.mechanical_efficiency = 0.99
    high_pressure_turbine.polytropic_efficiency = 0.93

    #add the high pressure turbine to the network    
    gt_engine.high_pressure_turbine = high_pressure_turbine 

    #Component 6 :combustor  
    combustor = SUAVE.Components.Energy.Converters.Combustor()   
    combustor.tag = 'Comb'

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

    #add the combustor to the network    
    gt_engine.combustor = combustor

    #Component 7 :core nozzle
    core_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()   
    core_nozzle.tag = 'core nozzle'

    core_nozzle.polytropic_efficiency = 0.95
    core_nozzle.pressure_ratio        = 0.99    

    #add the core nozzle to the network    
    gt_engine.core_nozzle = core_nozzle

    #Component 8 :fan nozzle
    fan_nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle()   
    fan_nozzle.tag = 'fan nozzle'

    fan_nozzle.polytropic_efficiency = 0.95
    fan_nozzle.pressure_ratio        = 0.99

    #add the fan nozzle to the network
    gt_engine.fan_nozzle = fan_nozzle

    #Component 9 : fan   
    fan = SUAVE.Components.Energy.Converters.Fan()   
    fan.tag = 'fan'

    fan.polytropic_efficiency = 0.93
    fan.pressure_ratio        = 1.7    

    #add the fan to the network
    gt_engine.fan = 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             = 37278.0* Units.N #Newtons

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

    # add thrust to the network
    gt_engine.thrust = thrust

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

    # add  gas turbine network gt_engine to the vehicle
    vehicle.append_component(gt_engine)      
    
    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
    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------

    return vehicle
예제 #10
0
파일: vsp_wing.py 프로젝트: kushalam/SUAVE
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
예제 #11
0
def simple_sizing(interface, Ereq, Preq):      
    from SUAVE.Methods.Geometry.Two_Dimensional.Planform import wing_planform

    # unpack
    configs  = interface.configs
    analyses = interface.analyses   
    airport=interface.analyses.missions.base.airport
    atmo            = airport.atmosphere
    mission=interface.analyses.missions.base.segments 
    base = configs.base
    base.pull_base()
    base = configs.base
    base.pull_base()
    Vcruise=mission['cruise'].air_speed
    design_thrust=Preq*1.3/Vcruise; #approximate sealevel thrust of ducted fan
    #determine geometry of fuselage as well as wings
    fuselage=base.fuselages['fuselage']
    SUAVE.Methods.Geometry.Two_Dimensional.Planform.fuselage_planform(fuselage)
    fuselage.areas.side_projected   = fuselage.heights.maximum*fuselage.lengths.cabin*1.1 #  Not correct
    c_vt                         =.08
    c_ht                         =.6
    w2v                          =8.54
    w2h                          =8.54
    base.wings['main_wing'] = wing_planform(base.wings['main_wing'])
    SUAVE.Methods.Geometry.Two_Dimensional.Planform.vertical_tail_planform_raymer(base.wings['vertical_stabilizer'],base.wings['main_wing'], w2v, c_vt)
    SUAVE.Methods.Geometry.Two_Dimensional.Planform.horizontal_tail_planform_raymer(base.wings['horizontal_stabilizer'],base.wings['main_wing'], w2h, c_ht)
   
    base.wings['horizontal_stabilizer'] = wing_planform(base.wings['horizontal_stabilizer']) 
    base.wings['vertical_stabilizer']   = wing_planform(base.wings['vertical_stabilizer'])   
    # wing areas
    for wing in base.wings:
        wing.areas.wetted   = 2.00 * wing.areas.reference
        wing.areas.affected = 0.60 * wing.areas.reference
        wing.areas.exposed  = 0.75 * wing.areas.wetted
  
    battery=base.energy_network['battery']
    ducted_fan=base.propulsors['ducted_fan']
    #SUAVE.Methods.Power.Battery.Sizing.initialize_from_energy_and_power(battery,Ereq,Preq)
    battery.mass_properties.mass  = Ereq/battery.specific_energy
    battery.max_energy=Ereq
    battery.max_power =Preq
    battery.current_energy=[battery.max_energy] #initialize list of current energy
    from SUAVE.Methods.Power.Battery.Variable_Mass import find_mass_gain_rate
    m_air       =-find_mass_gain_rate(battery,Ereq) #normally uses power as input to find mdot, but can use E to find m 
    m_water     =battery.find_water_mass(Ereq)
    #now add the electric motor weight
    motor_mass=ducted_fan.number_of_engines*SUAVE.Methods.Weights.Correlations.Propulsion.air_cooled_motor((Preq)*Units.watts/ducted_fan.number_of_engines)
    propulsion_mass=SUAVE.Methods.Weights.Correlations.Propulsion.integrated_propulsion(motor_mass/ducted_fan.number_of_engines,ducted_fan.number_of_engines)
    
    
    #more geometry sizing of ducted fan
    cruise_altitude= mission['climb_3'].altitude_end
    conditions = atmo.compute_values(cruise_altitude)
    sizing_segment = SUAVE.Components.Propulsors.Segments.Segment()
    sizing_segment.M   = mission['cruise'].air_speed/conditions.speed_of_sound       
    sizing_segment.alt = cruise_altitude
    sizing_segment.T   = conditions.temperature        
    sizing_segment.p   = conditions.pressure
    ducted_fan.design_thrust =design_thrust
    ducted_fan.mass_properties.mass=propulsion_mass
    ducted_fan.engine_sizing_ducted_fan(sizing_segment) 
    
    #compute overall mass properties
    breakdown = analyses.configs.base.weights.evaluate()
    breakdown.battery=battery.mass_properties.mass
    breakdown.water =m_water
    breakdown.air   =m_air
    base.mass_properties.breakdown=breakdown
    #print breakdown
    m_fuel=0.
    
    base.mass_properties.operating_empty     = breakdown.empty 
    
    #weight =SUAVE.Methods.Weights.Correlations.Tube_Wing.empty_custom_eng(vehicle, ducted_fan)
    m_full=breakdown.empty+battery.mass_properties.mass+breakdown.payload+m_water
    m_end=m_full+m_air
    base.mass_properties.takeoff                 = m_full
    base.store_diff()
   
    # Update all configs with new base data    
    for config in configs:
        config.pull_base()

    
    ##############################################################################
    # ------------------------------------------------------------------
    #   Define Landing Configurations
    # ------------------------------------------------------------------
 
    landing_config=configs.landing
    
    landing_config.wings['main_wing'].flaps.angle =  50. * Units.deg
    landing_config.wings['main_wing'].slats.angle  = 25. * Units.deg
    landing_config.mass_properties.landing = m_end
    landing_config.store_diff()
        
    
    #analyses.weights=configs.base.mass_properties.takeoff
    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ---------------------------------
    return
예제 #12
0
def test():
    
    aircraft=Vehicle()
    aircraft.tag="aero_test"
    aircraft.S=125.00
    
    Wing1=Wing(tag = 'Wing1')
    
    Wing1.sref      = 125.00 #124.862
    Wing1.ar        = 9
    Wing1.span      = 35.66
    Wing1.sweep     = 20.0*numpy.pi/180
    Wing1.symmetric = True
    Wing1.t_c       = 0.1
    Wing1.taper     = 0.16
    
    wing_planform(Wing1)
    
    Wing1.chord_mac   = 12.5
    Wing1.S_exposed   = 0.8*Wing1.area_wetted
    Wing1.S_affected  = 0.6*Wing1.area_wetted 
    #Wing1.Cl         = 0.3
    Wing1.e           = 0.9
    Wing1.twist_rc    = 3.0*numpy.pi/180
    Wing1.twist_tc    = -1.0*numpy.pi/180
 
    aircraft.append_component(Wing1)
  
  
    Wing2=Wing(tag = 'Wing2')
        
    Wing2.sref      = 32.488
    Wing2.ar        =  6.16
    Wing2.span      = 14.146
    Wing2.sweep     = 35.0*numpy.pi/180
    Wing2.symmetric = True
    Wing2.t_c       = 0.08
    Wing2.taper     = 0.4
    
    wing_planform(Wing2)
    
    #Wing2.chord_mac = 12.5
    Wing2.chord_mac  = 8.0
    Wing2.S_exposed  = 0.8*Wing2.area_wetted
    Wing2.S_affected = 0.6*Wing2.area_wetted     
    #Wing2.Cl        = 0.2
    Wing2.e          = 0.9
    Wing2.twist_rc   = 3.0*numpy.pi/180
    Wing2.twist_tc   = 0.0*numpy.pi/180   
  
    aircraft.append_component(Wing2)
    
    
    Wing3=Wing(tag = 'Wing3')
        
    Wing3.sref      = 32.488
    Wing3.ar        = 1.91
    Wing3.span      = 7.877
    Wing3.sweep     = 0.0*numpy.pi/180
    Wing3.symmetric = False
    Wing3.t_c       = 0.08
    Wing3.taper     = 0.25
       
    wing_planform(Wing3)
    
    Wing3.chord_mac  = 8.0
    Wing3.S_exposed  = 0.8*Wing3.area_wetted
    Wing3.S_affected = 0.6*Wing3.area_wetted     
    #Wing3.Cl        = 0.002  
    Wing3.e          = 0.9
    Wing3.twist_rc   = 0.0*numpy.pi/180
    Wing3.twist_tc   = 0.0*numpy.pi/180   
    Wing3.vertical   = True
        
    aircraft.append_component(Wing3)
   
   
    fus=Fuselage(tag = 'fuselage1')
    
    fus.num_coach_seats = 200
    fus.seat_pitch      = 1
    fus.seats_abreast   = 6
    fus.fineness_nose   = 1.6
    fus.fineness_tail   =  2
    fus.fwdspace        = 6
    fus.aftspace        = 5
    fus.width           = 4
    fus.height          = 4   
    
    fuselage_planform(fus)
    
    aircraft.append_component(fus)

    turbofan=Turbofan()
    turbofan.nacelle_dia= 4.0
    aircraft.append_component(turbofan)

    wing_aero = SUAVE.Attributes.Aerodynamics.Fidelity_Zero()
    wing_aero.initialize(aircraft)
    aircraft.Aerodynamics = wing_aero 


    Seg=Base_Segment()
    Seg.p   = 23900.0            # Pa
    Seg.T   = 218.0            # K
    Seg.rho = 0.41          # kg/m^3
    Seg.mew = 1.8*10**-5          # Ps-s
    Seg.M   = 0.8            # dimensionless


    
    conditions = Data()
    conditions.freestream   = Data()
    conditions.aerodynamics = Data()

    # freestream conditions
    #conditions.freestream.velocity           = ones_1col * 0
    conditions.freestream.mach_number        = Seg.M
    conditions.freestream.pressure           = Seg.p   
    conditions.freestream.temperature        = Seg.T  
    conditions.freestream.density            = Seg.rho
    #conditions.freestream.speed_of_sound     = ones_1col * 0
    conditions.freestream.dynamic_viscosity          = Seg.mew
    #conditions.freestream.altitude           = ones_1col * 0
    #conditions.freestream.gravity            = ones_1col * 0
    #conditions.freestream.reynolds_number    = ones_1col * 0
    #conditions.freestream.dynamic_pressure   = ones_1col * 0
    
    # aerodynamics conditions
    conditions.aerodynamics.angle_of_attack  = 0.  
    conditions.aerodynamics.side_slip_angle  = 0.
    conditions.aerodynamics.roll_angle       = 0.
    conditions.aerodynamics.lift_coefficient = 0.
    conditions.aerodynamics.drag_coefficient = 0.
    conditions.aerodynamics.lift_breakdown   = Data()
    conditions.aerodynamics.drag_breakdown   = Data()

    
    [Cl,Cd]=aircraft.Aerodynamics(conditions)
  
    print 'Aerodynamics module test script'
    print 'aircraft Cl' , Cl
    print 'aircraft Cd' , Cd
  
    return
예제 #13
0
def simple_sizing(configs, analyses, m_guess, Ereq, Preq):
    from SUAVE.Methods.Geometry.Two_Dimensional.Planform import wing_planform
    
# ------------------------------------------------------------------
    #   Define New Gross Takeoff Weight
    # ------------------------------------------------------------------
    #now add component weights to the gross takeoff weight of the vehicle
   
    base = configs.base
    base.pull_base()
    base.mass_properties.max_takeoff=m_guess
    base.mass_properties.max_zero_fuel=m_guess  #just used for weight calculation
    mission=analyses.missions.base.segments
    airport=analyses.missions.base.airport
    atmo            = airport.atmosphere
    #determine geometry of fuselage as well as wings
    fuselage=base.fuselages['fuselage']
    SUAVE.Methods.Geometry.Two_Dimensional.Planform.fuselage_planform(fuselage)
    fuselage.areas.side_projected   = fuselage.heights.maximum*fuselage.lengths.cabin*1.1 #  Not correct
    base.wings['main_wing'] = wing_planform(base.wings['main_wing'])
    base.wings['horizontal_stabilizer'] = wing_planform(base.wings['horizontal_stabilizer']) 
    
    base.wings['vertical_stabilizer']   = wing_planform(base.wings['vertical_stabilizer'])
    #calculate position of horizontal stabilizer
    base.wings['horizontal_stabilizer'].aerodynamic_center[0]= base.w2h- \
    (base.wings['horizontal_stabilizer'].origin[0] + \
    base.wings['horizontal_stabilizer'].aerodynamic_center[0] - \
    base.wings['main_wing'].origin[0] - base.wings['main_wing'].aerodynamic_center[0])
    #wing areas
    for wing in base.wings:
        wing.areas.wetted   = 2.00 * wing.areas.reference
        wing.areas.affected = 0.60 * wing.areas.reference
        wing.areas.exposed  = 0.75 * wing.areas.wetted
  
  
    cruise_altitude= mission['climb_5'].altitude_end
    conditions = atmo.compute_values(cruise_altitude)
    sizing_segment = SUAVE.Core.Data()
    sizing_segment.M      = mission['cruise'].air_speed/conditions.speed_of_sound       
    sizing_segment.alt    = cruise_altitude
    sizing_segment.T      = conditions.temperature        
    sizing_segment.p      = conditions.pressure
    conditions0           = atmo.compute_values(12500.*Units.ft) #cabin pressure
    p0                    = conditions0.pressure
    fuselage_diff_pressure= max(conditions0.pressure-conditions.pressure,0)
    fuselage.differential_pressure = fuselage_diff_pressure
    
    battery   =base.energy_network['battery']
    ducted_fan=base.propulsors['ducted_fan']
    SUAVE.Methods.Power.Battery.Sizing.initialize_from_energy_and_power(battery,Ereq,Preq)
    
    battery.current_energy =[battery.max_energy] #initialize list of current energy
    m_air                  =SUAVE.Methods.Power.Battery.Variable_Mass.find_total_mass_gain(battery)
    #now add the electric motor weight
    motor_mass=ducted_fan.number_of_engines*SUAVE.Methods.Weights.Correlations.Propulsion.air_cooled_motor((Preq)*Units.watts/ducted_fan.number_of_engines)
    propulsion_mass=SUAVE.Methods.Weights.Correlations.Propulsion.integrated_propulsion(motor_mass/ducted_fan.number_of_engines,ducted_fan.number_of_engines)
    
    ducted_fan.mass_properties.mass=propulsion_mass
   
    breakdown = analyses.configs.base.weights.evaluate()
    breakdown.battery=battery.mass_properties.mass
    breakdown.air=m_air
    base.mass_properties.breakdown=breakdown
    m_fuel=0.
    #print breakdown
    base.mass_properties.operating_empty     = breakdown.empty 
    #weight =SUAVE.Methods.Weights.Correlations.Tube_Wing.empty_custom_eng(vehicle, ducted_fan)
    m_full=breakdown.empty+battery.mass_properties.mass+breakdown.payload
    m_end=m_full+m_air
    base.mass_properties.takeoff                 = m_full
    base.store_diff()

    # Update all configs with new base data    
    for config in configs:
        config.pull_base()

    
    ##############################################################################
    # ------------------------------------------------------------------
    #   Define Configurations
    # ------------------------------------------------------------------
    landing_config=configs.landing
    landing_config.wings['main_wing'].flaps.angle =  20. * Units.deg
    landing_config.wings['main_wing'].slats.angle  = 25. * Units.deg
    landing_config.mass_properties.landing = m_end
    landing_config.store_diff()
    # ------------------------------------------------------------------
    #   Vehicle Definition Complete
    # ------------------------------------------------------------------
    
    return