def main(): # This script could fail if either the design or analysis scripts fail, # in case of failure check both. The design and analysis powers will # differ because of karman-tsien compressibility corrections in the # analysis scripts # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 50.0 prop_attributes.angular_velocity = 2000.*(2.*np.pi/60.0) prop_attributes.tip_radius = 1.5 prop_attributes.hub_radius = 0.05 prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 0.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 7000. prop_attributes = propeller_design(prop_attributes) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(prop_attributes.design_altitude) V = prop_attributes.freestream_velocity conditions = Data() conditions.freestream = Data() conditions.propulsion = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.freestream.velocity = np.array([[V]]) conditions.propulsion.throttle = np.array([[1.0]]) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.inputs.omega = prop_attributes.angular_velocity F, Q, P, Cplast = prop.spin(conditions) # Truth values F_truth = 166.41590262 Q_truth = 45.21732911 P_truth = 9470.2952633 # Over 9000! Cplast_truth = 0.00085898 error = Data() error.Thrust = np.max(np.abs(F-F_truth)) error.Power = np.max(np.abs(P-P_truth)) error.Torque = np.max(np.abs(Q-Q_truth)) error.Cp = np.max(np.abs(Cplast-Cplast_truth)) print 'Errors:' print error for k,v in error.items(): assert(np.abs(v)<0.001) return
def basic_prop(Na=24, Nr=101): # Design the Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2 prop.freestream_velocity = 135. * Units['mph'] prop.angular_velocity = 1300. * Units.rpm prop.tip_radius = 38. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_thrust = 1200. prop.origin = [[0., 0., 0.]] prop.number_azimuthal_stations = Na prop.rotation = 1 prop.symmetry = 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 = list(np.zeros(Nr).astype(int)) prop = propeller_design(prop, Nr) return prop
def ICE_CS(vehicle): # Replace the C172 engine and propeller with a constant speed propeller # Let's assume its an STC or 172RG # build network net = SUAVE.Components.Energy.Networks.Internal_Combustion_Propeller_Constant_Speed( ) net.tag = 'internal_combustion' net.number_of_engines = 1. net.nacelle_diameter = 42 * Units.inches net.engine_length = 0.01 * Units.inches net.areas = Data() net.rated_speed = 2700. * Units.rpm net.rated_power = 180. * Units.hp net.areas.wetted = 0.01 # Component 1 the engine net.engine = SUAVE.Components.Energy.Converters.Internal_Combustion_Engine( ) net.engine.sea_level_power = 180. * Units.horsepower net.engine.flat_rate_altitude = 0.0 net.engine.rated_speed = 2700. * Units.rpm net.engine.power_specific_fuel_consumption = 0.52 # prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2.0 prop.freestream_velocity = 119. * Units.knots prop.angular_velocity = 2650. * Units.rpm prop.tip_radius = 76. / 2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_power = .64 * 180. * Units.horsepower 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) net.propeller = prop # Replace the network vehicle.propulsors.internal_combustion = net return vehicle
def propeller(): ''' Parameters need to be added ''' prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 40.0 * Units['m/s'] # freestream prop_attributes.angular_velocity = 150. * Units['rpm'] prop_attributes.tip_radius = 4.25 * Units.meters prop_attributes.hub_radius = 0.05 * Units.meters prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 14.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 3500.0 * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes return prop
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Tecnam_P2006TElectric' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.max_takeoff = 1400 * Units.kilogram vehicle.mass_properties.takeoff = 1400 * Units.kilogram vehicle.mass_properties.operating_empty = 1000 * Units.kilogram vehicle.mass_properties.max_zero_fuel = 1400 * Units.kilogram vehicle.mass_properties.cargo = 80 * Units.kilogram # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 # basic parameters vehicle.reference_area = 64.4 * Units['meters**2'] vehicle.passengers = 4 vehicle.systems.control = "fully powered" vehicle.systems.accessories = "medium range" # ------------------------------------------------------------------ # Landing Gear # ------------------------------------------------------------------ # used for noise calculations #landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() #landing_gear.tag = "main_landing_gear" #landing_gear.main_tire_diameter = 0.423 * Units.m #landing_gear.nose_tire_diameter = 0.3625 * Units.m #landing_gear.main_strut_length = 0.4833 * Units.m #landing_gear.nose_strut_length = 0.3625 * Units.m #landing_gear.main_units = 2 #number of main landing gear units #landing_gear.nose_units = 1 #number of nose landing gear #landing_gear.main_wheels = 1 #number of wheels on the main landing gear #landing_gear.nose_wheels = 1 #number of wheels on the nose landing gear #vehicle.landing_gear = landing_gear # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' aux = time.time() fuselage.time = aux fuselage.number_coach_seats = vehicle.passengers fuselage.seats_abreast = 2 fuselage.seat_pitch = 0.995 * Units.meter fuselage.fineness.nose = 1.27 fuselage.fineness.tail = 1 #3.31 fuselage.lengths.nose = 1.16 * Units.meter fuselage.lengths.tail = 4.637 * Units.meter fuselage.lengths.cabin = 2.653 * Units.meter fuselage.lengths.total = 8.45 * Units.meter fuselage.lengths.fore_space = 0.0 * Units.meter fuselage.lengths.aft_space = 0.0 * Units.meter fuselage.width = 1.1 * Units.meter #1.22 fuselage.heights.maximum = 1.41 * Units.meter fuselage.effective_diameter = 2 * Units.meter fuselage.areas.side_projected = 7.46 * Units['meters**2'] fuselage.areas.wetted = 25.0 * Units['meters**2'] fuselage.areas.front_projected = 1.54 * Units['meters**2'] fuselage.differential_pressure = 10**5 * Units.pascal # Maximum differential pressure fuselage.heights.at_quarter_length = 1.077 * Units.meter fuselage.heights.at_three_quarters_length = 0.5 * Units.meter #0.621 * Units.meter fuselage.heights.at_wing_root_quarter_chord = 1.41 * Units.meter ## OpenVSP Design fuselage.OpenVSP_values = Data() # VSP uses degrees directly #MidFuselage1 Section fuselage.OpenVSP_values.midfus1 = Data() fuselage.OpenVSP_values.midfus1.z_pos = 0.03 #MidFuselage2 Section fuselage.OpenVSP_values.midfus2 = Data() fuselage.OpenVSP_values.midfus2.z_pos = 0.06 #MidFuselage3 Section fuselage.OpenVSP_values.midfus3 = Data() fuselage.OpenVSP_values.midfus3.z_pos = 0.04 #Tail Section fuselage.OpenVSP_values.tail = Data() fuselage.OpenVSP_values.tail.bottom = Data() fuselage.OpenVSP_values.tail.z_pos = 0.039 fuselage.OpenVSP_values.tail.bottom.angle = -20.0 fuselage.OpenVSP_values.tail.bottom.strength = 1 # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.thickness_to_chord = 0.15249979370200092 wing.taper = 0.9014171440917205 wing.spans.projected = 9.342124951930751 * Units.meter wing.chords.root = 2.0273876759854024 * Units.meter wing.chords.tip = wing.chords.root * wing.taper wing.chords.mean_aerodynamic = (wing.chords.root * (2.0 / 3.0) * ((1.0 + wing.taper + wing.taper**2.0) / (1.0 + wing.taper))) wing.areas.reference = (wing.chords.root + wing.chords.tip) * wing.spans.projected / 2 print wing.areas.reference basearea = wing.areas.reference wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = wing.areas.wetted wing.areas.affected = wing.areas.wetted wing.twists.root = 0. * Units.degrees wing.twists.tip = 0. * Units.degrees wing.dihedral = 1. * Units.degrees wing.origin = [2.986, 0, 1.077] # meters wing.sweeps.leading_edge = 1.9 * Units.deg wing.aspect_ratio = (wing.spans.projected * wing.spans.projected) / wing.areas.reference wing.span_efficiency = 0.95 wing.vertical = False wing.symmetric = True wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 ## Wing Segments # Root Segment #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 = 1. * Units.degrees #segment.sweeps.quarter_chord = 0. * Units.degrees #segment.thickness_to_chord = 0.15 #airfoil = SUAVE.Components.Wings.Airfoils.Airfoil() #airfoil.coordinate_file = '/Users/Bruno/Documents/Delft/Courses/2016-2017/Thesis/Code/Airfoils/naca642415.dat' #segment.append_airfoil(airfoil) #wing.Segments.append(segment) # Tip Segment #segment = SUAVE.Components.Wings.Segment() #segment.tag = 'tip' #segment.percent_span_location = 1.0 #segment.twist = 0. * Units.deg #segment.root_chord_percent = 1. #segment.dihedral_outboard = 1. * Units.degrees #segment.sweeps.quarter_chord = 0. * Units.degrees #segment.thickness_to_chord = 0.15 #airfoil = SUAVE.Components.Wings.Airfoils.Airfoil() #airfoil.coordinate_file = '/Users/Bruno/Documents/Delft/Courses/2016-2017/Thesis/Code/Airfoils/naca642415.dat' #segment.append_airfoil(airfoil) #wing.Segments.append(segment) # ------------------------------------------------------------------ # Flaps # ------------------------------------------------------------------ wing.flaps.chord = wing.chords.root * 0.15 wing.flaps.span_start = 0.3 * wing.spans.projected wing.flaps.span_end = 0.8 * wing.spans.projected wing.flaps.area = wing.flaps.chord * (wing.flaps.span_end - wing.flaps.span_start) wing.flaps.type = 'single_slotted' # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 4.193 wing.areas.reference = 0.145 * basearea wing.sweeps.quarter_chord = 0.0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.97 wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.chords.root wing.chords.mean_aerodynamic = (wing.chords.root * (2.0 / 3.0) * ((1.0 + wing.taper + wing.taper**2.0) / (1.0 + wing.taper))) wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = wing.areas.wetted wing.areas.affected = wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [7.789, 0.0, 0.3314] # meters wing.vertical = False wing.symmetric = True 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.areas.reference = 0.099 * basearea wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = wing.areas.wetted wing.areas.affected = wing.areas.wetted wing.aspect_ratio = 1.407 wing.sweeps.quarter_chord = 38.75 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 0.4142 wing.span_efficiency = 0.97 wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.chords.root = (2.0 * wing.areas.reference) / (wing.spans.projected * (1 + wing.taper)) wing.chords.tip = wing.chords.root * wing.taper wing.chords.mean_aerodynamic = (wing.chords.root * (2.0 / 3.0) * ((1.0 + wing.taper + wing.taper**2.0) / (1.0 + wing.taper))) wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [7.25, 0, 0.497] # meters wing.vertical = True wing.symmetric = False wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Propellers Powered By Batteries # ------------------------------------------------------------------ # build network net = SUAVE.Components.Energy.Networks.Lift_Forward_Propulsor() net.nacelle_diameter_lift = 0.08 * Units.meters net.nacelle_diameter_forward = 0.1732 * Units.meters net.engine_length_lift = 0.47244 * Units.meters net.engine_length_forward = 1.2 * Units.meters net.number_of_engines_lift = 10 print 'Prop Optimization' print 'Engines Lift Number' print net.number_of_engines_lift net.number_of_engines_forward = 2 net.thrust_angle_lift = 0.0 * Units.degrees net.thrust_angle_forward = 0.0 * Units.degrees net.voltage = 461. * Units['volt'] #461. net.areas_forward = Data() net.areas_forward.wetted = 1.1 * np.pi * net.nacelle_diameter_forward * net.engine_length_forward net.areas_lift = Data() net.areas_lift.wetted = 1.1 * np.pi * net.nacelle_diameter_forward * net.engine_length_lift net.number_of_engines = 1 net.nacelle_diameter = net.nacelle_diameter_forward net.areas = Data() net.areas.wetted = net.areas_lift.wetted net.engine_length = 1. # Component 1 - Tip ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc_forward = esc # Component 1 - High Lift ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc_lift = esc # Component 2 - Tip Propeller # Design the Propeller #prop_attributes = Data() #prop_attributes = propeller_design(prop_attributes) prop_forward = SUAVE.Components.Energy.Converters.Propeller() prop_forward.number_blades = 3.0 prop_forward.propulsive_efficiency = 0.85 prop_forward.freestream_velocity = 50.0 * Units['m/s'] # freestream m/s prop_forward.angular_velocity = 27500. * Units['rpm'] # For 20x10 prop prop_forward.tip_radius = 0.5 * Units.meter prop_forward.hub_radius = 0.085 * Units.meter prop_forward.design_Cl = 0.8 prop_forward.design_altitude = 14.0 * Units.km prop_forward.design_thrust = 0.0 * Units.newton prop_forward.design_power = 60000. * Units.watts prop_forward = propeller_design(prop_forward) net.propeller_forward = prop_forward # Component 2 - High Lift Propeller # Design the Propeller #prop_attributes = Data() prop_lift = SUAVE.Components.Energy.Converters.Propeller() prop_lift.number_blades = 5.0 prop_lift.propulsive_efficiency = 0.85 prop_lift.freestream_velocity = 1. * Units['m/s'] # freestream m/s prop_lift.angular_velocity = 2750 * Units['rpm'] # For 20x10 prop prop_lift.tip_radius = 0.26 * Units.meter #0.2880360 prop_lift.hub_radius = 0.07772400 * Units.meter prop_lift.design_Cl = 0.8 prop_lift.design_altitude = 0.0 * Units.meter prop_lift.design_thrust = 0.0 * Units.newton prop_lift.design_power = 10500. * Units.watts prop_lift = propeller_design(prop_lift) net.propeller_lift = prop_lift # Component 3 - Tip Motor motor = SUAVE.Components.Energy.Converters.Motor_Lo_Fid() #motor.resistance = 1. #motor.no_load_current = 7. * Units.ampere #motor.speed_constant = 11.9999 * Units['rpm/volt'] # RPM/volt converted to (rad/s)/volt #motor.propeller_radius = prop_forward.tip_radius #motor.propeller_Cp = prop_forward.Cp[0] #motor.gear_ratio = 12. # Gear ratio #motor.gearbox_efficiency = .98 # Gear box efficiency #motor.expected_current = 160. # Expected current #motor.mass_properties.mass = 9.0 * Units.kg #net.motor_forward = motor motor.speed_constant = 180. * Units['rpm/volt'] # RPM/volt is standard motor = size_from_kv(motor, motor.speed_constant) motor.gear_ratio = 1. # Gear ratio, no gearbox motor.gearbox_efficiency = .98 # Gear box efficiency, no gearbox motor.motor_efficiency = 0.825 net.motor_forward = motor # Component 3 - High Lift Motor motor = SUAVE.Components.Energy.Converters.Motor_Lo_Fid() #motor.resistance = 0.008 #motor.no_load_current = 4.5 * Units.ampere #motor.speed_constant = 5800. * Units['rpm/volt'] # RPM/volt converted to (rad/s)/volt #motor.propeller_radius = prop_lift.tip_radius #motor.propeller_Cp = prop_lift.Cp[0] #motor.gear_ratio = 12. # Gear ratio #motor.gearbox_efficiency = .98 # Gear box efficiency #motor.expected_current = 25. # Expected current #motor.mass_properties.mass = 6.0 * Units.kg #net.motor_lift = motor motor.speed_constant = 90. * Units['rpm/volt'] # RPM/volt is standard motor = size_from_kv(motor, motor.speed_constant) motor.gear_ratio = 1. # Gear ratio, no gearbox motor.gearbox_efficiency = .98 # Gear box efficiency, no gearbox motor.motor_efficiency = 0.825 net.motor_lift = motor # Component 4 - the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 50. * Units.watts payload.mass_properties.mass = 5.0 * Units.kg net.payload = payload # Component 5 - the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 50. * Units.watts net.avionics = avionics # Component 6 - the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.mass_properties.mass = 386.0 * Units.kg bat.specific_energy = 121.8 * Units.Wh / Units.kg #192.84 bat.specific_power = 0.312 * Units.kW / Units.kg #0.837 bat.resistance = 0.32 bat.max_voltage = 538. * Units['volt'] #10000. initialize_from_mass(bat, bat.mass_properties.mass) print bat.max_energy net.battery = bat # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ # add the energy network to the vehicle vehicle.append_component(net) #now add weights objects vehicle.landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() vehicle.control_systems = SUAVE.Components.Physical_Component() vehicle.electrical_systems = SUAVE.Components.Physical_Component() vehicle.avionics = SUAVE.Components.Energy.Peripherals.Avionics() vehicle.passenger_weights = SUAVE.Components.Physical_Component() #vehicle.furnishings = SUAVE.Components.Physical_Component() #vehicle.apu = SUAVE.Components.Physical_Component() #vehicle.hydraulics = SUAVE.Components.Physical_Component() vehicle.optionals = SUAVE.Components.Physical_Component() vehicle.wings[ 'vertical_stabilizer'].rudder = SUAVE.Components.Physical_Component() #print vehicle return vehicle
def define_vehicle(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Solar' vehicle.propulsors.propulsor = SUAVE.Components.Energy.Networks.Solar_Network() # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 200 * Units.kg vehicle.mass_properties.operating_empty = 200 * Units.kg vehicle.mass_properties.max_takeoff = 200 * Units.kg # basic parameters vehicle.reference_area = 80. # m^2 vehicle.envelope.ultimate_load = 2.0 vehicle.qm = 0.5*1.225*(25.**2.) #Max q vehicle.Ltb = 10. # Tail boom length # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Main Wing' wing.areas.reference = vehicle.reference_area # wing.spans.projected = 40. #m wing.aspect_ratio = (wing.spans.projected**2)/wing.areas.reference wing.sweep = 0. * Units.deg # wing.symmetric = True # wing.thickness_to_chord = 0.12 # wing.taper = 1. # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected # wing.areas.exposed = 0.8*wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6*wing.areas.wetted # part of high lift system wing.span_efficiency = 0.97 # wing.twists.root = 0.0*Units.degrees # wing.twists.tip = 0.0*Units.degrees # wing.highlift = False wing.vertical = False wing.eta = 1.0 wing.number_ribs = 26. # ? wing.number_end_ribs = 2. wing.transition_x_u = 0. wing.transition_x_l = 0. # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Horizontal Stabilizer' wing.areas.reference = vehicle.reference_area*.15 #m^2 wing.aspect_ratio = 20. # wing.spans.projected = np.sqrt(wing.aspect_ratio*wing.areas.reference) wing.sweep = 0 * Units.deg # wing.symmetric = True wing.thickness_to_chord = 0.12 # wing.taper = 1. # wing.twists.root = 0.0*Units.degrees # wing.twists.tip = 0.0*Units.degrees # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected # wing.areas.exposed = 0.8*wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6*wing.areas.wetted # part of high lift system wing.span_efficiency = 0.95 # wing.twists.root = 0. # wing.twists.tip = 0. # wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Vertical Stabilizer' wing.areas.reference = vehicle.reference_area*.1 #m^2 wing.aspect_ratio = 20. # wing.spans.projected = np.sqrt(wing.aspect_ratio*wing.areas.reference) wing.sweep = 0 * Units.deg # wing.symmetric = True wing.thickness_to_chord = 0.12 # wing.taper = 1. # wing.twists.root = 0.0*Units.degrees # wing.twists.tip = 0.0*Units.degrees # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected # wing.areas.exposed = 0.8*wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6*wing.areas.wetted # part of high lift system wing.span_efficiency = 0.97 # wing.twists.root = 0.0*Units.degrees # wing.twists.tip = 0.0*Units.degrees # wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) #------------------------------------------------------------------ # Propulsor #------------------------------------------------------------------ # build network net = Solar_Network() net.number_motors = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = vehicle.reference_area panel.efficiency = 0.2 panel.mass_properties.mass = panel.area*0.6 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 50.0 # freestream m/s prop_attributes.angular_velocity = 300.*(2.*np.pi/60.0) prop_attributes.tip_radius = 4.25 prop_attributes.hub_radius = 0.0508 prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 23.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 10000.0 prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.008 motor.no_load_current = 4.5 motor.speed_constant = 120.*(2.*np.pi/60.) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 20. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 160. # Expected current motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 100. #Watts payload.mass_properties.mass = 25.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery # I already assume 250 Wh/kg for batteries bat = SUAVE.Components.Energy.Storages.Battery() bat.mass_properties.mass = 50 * Units.kg bat.type = 'Li-Ion' bat.resistance = 0.0 #This needs updating net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 100.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Calculate the vehicle mass vehicle.mass_properties.breakdown = SUAVE.Methods.Weights.Correlations.Human_Powered.empty(vehicle) # ------------------------------------------------------------------ # Simple Aerodynamics Model # ------------------------------------------------------------------ aerodynamics = SUAVE.Attributes.Aerodynamics.Fidelity_Zero() aerodynamics.initialize(vehicle) vehicle.aerodynamics_model = aerodynamics # ------------------------------------------------------------------ # Not so Simple Propulsion Model # ------------------------------------------------------------------ vehicle.propulsion_model = net # ------------------------------------------------------------------ # Define Configurations # ------------------------------------------------------------------ # --- Takeoff Configuration --- config = vehicle.new_configuration("takeoff") # this configuration is derived from the baseline vehicle # --- Cruise Configuration --- config = vehicle.new_configuration("cruise") # this configuration is derived from vehicle.Configs.takeoff # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Cessna_172_SP' # ------------------------------------------------------------------ # 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.mass_properties.cargo = 0. # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 cruise_speed = 124. * Units.kts altitude = 8500. * 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 # basic parameters vehicle.reference_area = 174. * Units.feet**2 vehicle.passengers = 4 # ------------------------------------------------------------------ # 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 = 174. * Units.feet**2 wing.spans.projected = 36. * Units.feet + 1. * Units.inches wing.chords.root = 66. * Units.inches wing.chords.tip = 45. * Units.inches wing.chords.mean_aerodynamic = 58. * Units.inches wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2. / wing.areas.reference wing.twists.root = 3.0 * Units.degrees wing.twists.tip = 1.5 * Units.degrees wing.origin = [[80. * Units.inches, 0, 0]] wing.aerodynamic_center = [22. * Units.inches, 0, 0] wing.vertical = False wing.symmetric = True wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 # control surfaces ------------------------------------------- flap = SUAVE.Components.Wings.Control_Surfaces.Flap() flap.tag = 'flap' flap.span_fraction_start = 0.15 flap.span_fraction_end = 0.324 flap.deflection = 1.0 * Units.deg flap.chord_fraction = 0.19 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) SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_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 = 5800. * Units.inches**2 wing.spans.projected = 136. * Units.inches wing.chords.root = 55. * Units.inches wing.chords.tip = 30. * Units.inches wing.chords.mean_aerodynamic = 43. * Units.inches 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 = [[246. * Units.inches, 0, 0]] wing.aerodynamic_center = [20. * Units.inches, 0, 0] wing.vertical = False wing.symmetric = True wing.high_lift = False wing.dynamic_pressure_ratio = 0.9 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 = 3500. * Units.inches**2 wing.spans.projected = 73. * Units.inches wing.chords.root = 66. * Units.inches wing.chords.tip = 27. * Units.inches wing.chords.mean_aerodynamic = 48. * Units.inches 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 = [[237. * Units.inches, 0, 0]] wing.aerodynamic_center = [20. * Units.inches, 0, 0] wing.vertical = True wing.symmetric = False wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.number_coach_seats = 4. fuselage.tag = 'fuselage' fuselage.differential_pressure = 8 * Units.psi # Maximum differential pressure fuselage.width = 42. * Units.inches # Width of the fuselage fuselage.heights.maximum = 62. * Units.inches # Height of the fuselage fuselage.lengths.total = 326. * Units.inches # Length of the fuselage fuselage.lengths.empennage = 161. * Units.inches fuselage.lengths.cabin = 105. * Units.inches fuselage.lengths.structure = fuselage.lengths.total - fuselage.lengths.empennage fuselage.mass_properties.volume = .4 * fuselage.lengths.total * ( np.pi / 4.) * (fuselage.heights.maximum**2. ) #try this as approximation fuselage.mass_properties.internal_volume = .3 * fuselage.lengths.total * ( np.pi / 4.) * (fuselage.heights.maximum**2.) fuselage.areas.wetted = 30000. * Units.inches**2. fuselage.seats_abreast = 2. fuselage.fineness.nose = 1.6 fuselage.fineness.tail = 2. fuselage.lengths.nose = 60. * 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.front_projected = fuselage.width * fuselage.heights.maximum fuselage.effective_diameter = 50. * Units.inches # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Landing gear # ------------------------------------------------------------------ landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() main_gear = SUAVE.Components.Landing_Gear.Main_Landing_Gear() nose_gear = SUAVE.Components.Landing_Gear.Nose_Landing_Gear() main_gear.strut_length = 12. * Units.inches #guess based on picture nose_gear.strut_length = 6. * Units.inches landing_gear.main = main_gear landing_gear.nose = nose_gear #add to vehicle vehicle.landing_gear = landing_gear # ------------------------------------------------------------------ # Fuel # ------------------------------------------------------------------ # define fuel weight needed to size fuel system fuel = SUAVE.Attributes.Propellants.Aviation_Gasoline() fuel.mass_properties = SUAVE.Components.Mass_Properties() fuel.number_of_tanks = 1. fuel.origin = wing.origin fuel.internal_volume = fuel.mass_properties.mass / fuel.density #all of the fuel volume is internal fuel.mass_properties.center_of_gravity = wing.mass_properties.center_of_gravity fuel.mass_properties.mass = 319 * Units.lbs vehicle.fuel = fuel # ------------------------------------------------------------------ # Piston Propeller Network # ------------------------------------------------------------------ # build network net = SUAVE.Components.Energy.Networks.Internal_Combustion_Propeller() net.tag = 'internal_combustion' net.number_of_engines = 1. net.identical_propellers = True # the engine engine = SUAVE.Components.Energy.Converters.Internal_Combustion_Engine() engine.sea_level_power = 180. * Units.horsepower engine.flat_rate_altitude = 0.0 engine.rated_speed = 2700. * Units.rpm engine.power_specific_fuel_consumption = 0.52 net.engines.append(engine) # the prop prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2.0 prop.freestream_velocity = 119. * Units.knots prop.angular_velocity = 2650. * Units.rpm prop.tip_radius = 76. / 2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_power = .64 * 180. * Units.horsepower 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) net.propellers.append(prop) # add the network to the vehicle vehicle.append_component(net) #find uninstalled avionics weight Wuav = 2. * Units.lbs avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.mass_properties.uninstalled = Wuav vehicle.avionics = avionics # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ return vehicle
def main(): # This script could fail if either the design or analysis scripts fail, # in case of failure check both. The design and analysis powers will # differ because of karman-tsien compressibility corrections in the # analysis scripts # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 50.0 prop_attributes.angular_velocity = 2000. * (2. * np.pi / 60.0) prop_attributes.tip_radius = 1.5 prop_attributes.hub_radius = 0.05 prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 0.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 7000. prop_attributes = propeller_design(prop_attributes) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values( prop_attributes.design_altitude) V = prop_attributes.freestream_velocity conditions = Data() conditions.freestream = Data() conditions.propulsion = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions.propulsion.throttle = np.array([[1.0]]) conditions.frames.body.transform_to_inertial = np.array([np.eye(3)]) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.inputs.omega = np.array(prop_attributes.angular_velocity, ndmin=2) F, Q, P, Cplast = prop.spin(conditions) # Truth values F_truth = 166.41590262 Q_truth = 45.21732911 P_truth = 9470.2952633 # Over 9000! Cplast_truth = 0.00085898 error = Data() error.Thrust = np.max(np.abs(F - F_truth)) error.Power = np.max(np.abs(P - P_truth)) error.Torque = np.max(np.abs(Q - Q_truth)) error.Cp = np.max(np.abs(Cplast - Cplast_truth)) print('Errors:') print(error) for k, v in list(error.items()): assert (np.abs(v) < 1e-6) return
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'X57_Maxwell' # ------------------------------------------------------------------ # 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.mass_properties.cargo = 0. # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 # basic parameters vehicle.reference_area = 15.45 vehicle.passengers = 4 # ------------------------------------------------------------------ # 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.span_efficiency = 0.9 wing.areas.reference = 15.45 * Units['meters**2'] wing.spans.projected = 11. * Units.meter wing.chords.root = 1.67 * Units.meter wing.chords.tip = 1.14 * Units.meter wing.chords.mean_aerodynamic = 1.47 * Units.meter 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 = 1.5 * Units.degrees wing.origin = [2.032, 0., 0.] wing.aerodynamic_center = [0.558, 0., 0.] wing.vertical = False wing.symmetric = True wing.high_lift = True 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.sweeps.quarter_chord = 0.0 * Units.deg wing.thickness_to_chord = 0.12 wing.span_efficiency = 0.95 wing.areas.reference = 3.74 * Units['meters**2'] wing.spans.projected = 3.454 * Units.meter wing.sweeps.quarter_chord = 12.5 * Units.deg wing.chords.root = 1.397 * Units.meter wing.chords.tip = 0.762 * Units.meter wing.chords.mean_aerodynamic = 1.09 * Units.meter wing.taper = wing.chords.root/wing.chords.tip 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.248, 0., 0.784] wing.aerodynamic_center = [0.508, 0., 0.] wing.vertical = False 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.span_efficiency = 0.9 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.root/wing.chords.tip 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.01 ,0, 0.623] wing.aerodynamic_center = [0.508 ,0,0] wing.vertical = True wing.symmetric = False wing.t_tail = False 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 = 326. * 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 # add to vehicle vehicle.append_component(fuselage) #--------------------------------------------------------------------------------------------- # DEFINE PROPELLER #--------------------------------------------------------------------------------------------- # build network net = Battery_Propeller() net.number_of_engines = 2. net.nacelle_diameter = 42 * Units.inches net.engine_length = 0.01 * Units.inches net.areas = Data() net.areas.wetted = 0.01*(2*np.pi*0.01/2) # 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 # Design the Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_blades = 2.0 prop.freestream_velocity = 135.*Units['mph'] prop.angular_velocity = 1300. * Units.rpm # 2400 prop.tip_radius = 76./2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_altitude = 12000. * Units.feet prop.design_thrust = 800. prop.origin = [[2.,2.5,0.784]] # prop influence prop.symmetry = True prop = propeller_design(prop) net.propeller = prop # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion() bat.mass_properties.mass = 500. * Units.kg bat.specific_energy = 350. * Units.Wh/Units.kg bat.resistance = 0.006 bat.max_voltage = 500. initialize_from_mass(bat,bat.mass_properties.mass) net.battery = bat net.voltage = bat.max_voltage # Component 9 Miscellaneous Systems sys = SUAVE.Components.Systems.System() sys.mass_properties.mass = 5 # kg #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller motor # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() etam = 0.95 v = bat.max_voltage *3/4 omeg = prop.angular_velocity io = 4.0 start_kv = 1 end_kv = 25 # do optimization to find kv or just do a linspace then remove all negative values, take smallest one use 0.05 change # essentially you are sizing the motor for a particular rpm which is sized for a design tip mach # this reduces the bookkeeping errors possible_kv_vals = np.linspace(start_kv,end_kv,(end_kv-start_kv)*20 +1 , endpoint = True) * Units.rpm res_kv_vals = ((v-omeg/possible_kv_vals)*(1.-etam*v*possible_kv_vals/omeg))/io positive_res_vals = np.extract(res_kv_vals > 0 ,res_kv_vals) kv_idx = np.where(res_kv_vals == min(positive_res_vals))[0][0] kv = possible_kv_vals[kv_idx] res = min(positive_res_vals) motor.mass_properties.mass = 10. * Units.kg motor.origin = prop.origin motor.propeller_radius = prop.tip_radius motor.speed_constant = 0.35 motor.resistance = res motor.no_load_current = io motor.gear_ratio = 1. motor.gearbox_efficiency = 1. # Gear box efficiency net.motor = motor # 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
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Cessna_172_SP' # ------------------------------------------------------------------ # 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 = 2555. * Units.pounds # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 # basic parameters vehicle.reference_area = 174. * Units.feet**2 vehicle.passengers = 4 # ------------------------------------------------------------------ # 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 = 174. * Units.feet**2 wing.spans.projected = 36. * Units.feet + 1. * Units.inches wing.chords.root = 66. * Units.inches wing.chords.tip = 45. * Units.inches 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 = [[80. * Units.inches, 0, 36.75 * Units.inches]] wing.vertical = False wing.symmetric = True wing.high_lift = 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 = 3. * Units.deg segment.root_chord_percent = 1. segment.thickness_to_chord = 0.12 segment.dihedral_outboard = 2.5 * Units.degrees segment.sweeps.quarter_chord = 0 wing.append_segment(segment) segment = SUAVE.Components.Wings.Segment() segment.tag = 'Break' segment.percent_span_location = 0.531177829 segment.twist = 2. * Units.deg segment.root_chord_percent = 1.0 segment.thickness_to_chord = 0.12 segment.dihedral_outboard = 5 * Units.degrees segment.sweeps.quarter_chord = -3. * Units.degrees wing.append_segment(segment) segment = SUAVE.Components.Wings.Segment() segment.tag = 'Tip' segment.percent_span_location = 1. segment.twist = 1. * Units.degrees segment.root_chord_percent = 0.67 segment.thickness_to_chord = 0.12 segment.dihedral_outboard = 0. segment.sweeps.quarter_chord = 0. wing.append_segment(segment) # Fill out more segment properties automatically wing = segment_properties(wing) wing = SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_planform(wing) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Horizontal_Tail() wing.tag = 'horizontal_stabilizer' wing.sweeps.quarter_chord = 19.5 * Units.deg wing.thickness_to_chord = 0.12 wing.spans.projected = 135. * Units.inches wing.areas.reference = 5500 * Units.inches**2 wing.chords.root = 55. * Units.inches wing.chords.tip = 28. * Units.inches 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 = [[253. * Units.inches, 0, 0]] wing.vertical = False wing.symmetric = True wing.high_lift = False wing.dynamic_pressure_ratio = 0.9 wing = SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_planform(wing) vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Vertical_Tail() wing.tag = 'vertical_stabilizer' wing.sweeps.quarter_chord = 48. * Units.deg wing.thickness_to_chord = 0.12 wing.areas.reference = 3500. * Units.inches**2 wing.spans.projected = 56. * Units.inches wing.chords.root = 64. * Units.inches wing.chords.tip = 30. * Units.inches 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 = [[240. * Units.inches, 0, 0]] wing.vertical = True wing.symmetric = False wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 wing = SUAVE.Methods.Geometry.Two_Dimensional.Planform.wing_planform(wing) vehicle.append_component(wing) # ------------------------------------------------------------------ # Strut # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'strut' wing.sweeps.quarter_chord = 0. * Units.deg wing.thickness_to_chord = 0.4 wing.areas.reference = 660. * Units.inches**2 wing.spans.projected = 200. * Units.inches wing.chords.root = 6. * Units.inches wing.chords.tip = 6. * Units.inches wing.chords.mean_aerodynamic = 6. * Units.inches 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 = [[ 80. * Units.inches, 20. * Units.inches, -17. * Units.inches ]] wing.dihedral = 30.0 * Units.degrees wing.vertical = False wing.symmetric = True wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.number_coach_seats = 4. fuselage.tag = 'fuselage' fuselage.differential_pressure = 0. fuselage.width = 42. * Units.inches fuselage.heights.maximum = 62. * Units.inches fuselage.lengths.total = 326. * Units.inches fuselage.lengths.empennage = 161. * Units.inches fuselage.lengths.cabin = 105. * Units.inches fuselage.lengths.structure = fuselage.lengths.total - fuselage.lengths.empennage fuselage.mass_properties.volume = .4 * fuselage.lengths.total * ( np.pi / 4.) * (fuselage.heights.maximum**2. ) #try this as approximation fuselage.mass_properties.internal_volume = .3 * fuselage.lengths.total * ( np.pi / 4.) * (fuselage.heights.maximum**2.) fuselage.areas.wetted = 20.396 fuselage.seats_abreast = 2. fuselage.fineness.nose = 1.6 fuselage.fineness.tail = 2. fuselage.lengths.nose = 60. * 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.front_projected = fuselage.width * fuselage.heights.maximum 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 = 16.75 / 326. segment.height = 0. * Units.inches segment.width = 0. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_1' segment.percent_x_location = 0.070433529 segment.percent_z_location = 0.023187437 segment.height = 28.089241 * Units.inches segment.width = 40. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_2' segment.percent_x_location = 0.16766091 segment.percent_z_location = 0.014375532 segment.height = 38.872257 * Units.inches segment.width = 42. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_3' segment.percent_x_location = 0.243802224 segment.percent_z_location = 0.026573779 segment.height = 56.19732 * Units.inches segment.width = 42. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_4' segment.percent_x_location = 0.443495521 segment.percent_z_location = 0.015 segment.height = 46 * Units.inches segment.width = 42. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_5' segment.percent_x_location = 0.508342393 segment.percent_z_location = -0.000878305 segment.height = 34.067009 * Units.inches segment.width = 42. * Units.inches fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_6' segment.percent_x_location = 0.857801856 segment.percent_z_location = -0.022517885 segment.height = 15.538013 * Units.inches segment.width = 10 * Units.inches fuselage.Segments.append(segment) # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Piston Propeller Network # ------------------------------------------------------------------ # build network net = SUAVE.Components.Energy.Networks.Internal_Combustion_Propeller() net.tag = 'internal_combustion' net.number_of_engines = 1. net.identical_propellers = True # the engine engine = SUAVE.Components.Energy.Converters.Internal_Combustion_Engine() engine.sea_level_power = 180. * Units.horsepower engine.flat_rate_altitude = 0.0 engine.rated_speed = 2700. * Units.rpm engine.power_specific_fuel_consumption = 0.52 net.engines.append(engine) # the prop prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2.0 prop.origin = [[0.0, 0.0, 16.75 * Units.inches]] prop.freestream_velocity = 119. * Units.knots prop.angular_velocity = 2650. * Units.rpm prop.tip_radius = 76. / 2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_power = .64 * 180. * Units.horsepower prop.variable_pitch = False prop.airfoil_geometry = ['./Airfoils/NACA_4412.txt'] prop.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' ]] 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) net.propellers.append(prop) # add the network to the vehicle vehicle.append_component(net) # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ return vehicle
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 define_vehicle(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Solar' vehicle.propulsors.propulsor = SUAVE.Components.Energy.Networks.Solar_Network( ) # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 200 * Units.kg vehicle.mass_properties.operating_empty = 200 * Units.kg vehicle.mass_properties.max_takeoff = 200 * Units.kg # basic parameters vehicle.reference_area = 80. # m^2 vehicle.envelope.ultimate_load = 2.0 vehicle.qm = 0.5 * 1.225 * (25.**2.) #Max q vehicle.Ltb = 10. # Tail boom length # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Main Wing' wing.areas.reference = vehicle.reference_area # wing.spans.projected = 40. #m wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.sweep = 0. * Units.deg # wing.symmetric = True # wing.thickness_to_chord = 0.12 # wing.taper = 1. # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected # wing.areas.exposed = 0.8 * wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6 * wing.areas.wetted # part of high lift system wing.span_efficiency = 0.97 # wing.twists.root = 0.0 * Units.degrees # wing.twists.tip = 0.0 * Units.degrees # wing.highlift = False wing.vertical = False wing.eta = 1.0 wing.number_ribs = 26. # ? wing.number_end_ribs = 2. wing.transition_x_u = 0. wing.transition_x_l = 0. # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Horizontal Stabilizer' wing.areas.reference = vehicle.reference_area * .15 #m^2 wing.aspect_ratio = 20. # wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.sweep = 0 * Units.deg # wing.symmetric = True wing.thickness_to_chord = 0.12 # wing.taper = 1. # wing.twists.root = 0.0 * Units.degrees # wing.twists.tip = 0.0 * Units.degrees # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected # wing.areas.exposed = 0.8 * wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6 * wing.areas.wetted # part of high lift system wing.span_efficiency = 0.95 # wing.twists.root = 0. # wing.twists.tip = 0. # wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'Vertical Stabilizer' wing.areas.reference = vehicle.reference_area * .1 #m^2 wing.aspect_ratio = 20. # wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.sweep = 0 * Units.deg # wing.symmetric = True wing.thickness_to_chord = 0.12 # wing.taper = 1. # wing.twists.root = 0.0 * Units.degrees # wing.twists.tip = 0.0 * Units.degrees # # size the wing planform SUAVE.Geometry.Two_Dimensional.Planform.wing_planform(wing) wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected # wing.areas.exposed = 0.8 * wing.areas.wetted # might not be needed as input wing.areas.affected = 0.6 * wing.areas.wetted # part of high lift system wing.span_efficiency = 0.97 # wing.twists.root = 0.0 * Units.degrees # wing.twists.tip = 0.0 * Units.degrees # wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) #------------------------------------------------------------------ # Propulsor #------------------------------------------------------------------ # build network net = Solar_Network() net.number_motors = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = vehicle.reference_area panel.efficiency = 0.2 panel.mass_properties.mass = panel.area * 0.6 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 50.0 # freestream m/s prop_attributes.angular_velocity = 300. * (2. * np.pi / 60.0) prop_attributes.tip_radius = 4.25 prop_attributes.hub_radius = 0.0508 prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 23.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 10000.0 prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.008 motor.no_load_current = 4.5 motor.speed_constant = 120. * (2. * np.pi / 60. ) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 20. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 160. # Expected current motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 100. #Watts payload.mass_properties.mass = 25.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery # I already assume 250 Wh/kg for batteries bat = SUAVE.Components.Energy.Storages.Battery() bat.mass_properties.mass = 50 * Units.kg bat.type = 'Li-Ion' bat.resistance = 0.0 #This needs updating net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 100.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Calculate the vehicle mass vehicle.mass_properties.breakdown = SUAVE.Methods.Weights.Correlations.Human_Powered.empty( vehicle) # ------------------------------------------------------------------ # Simple Aerodynamics Model # ------------------------------------------------------------------ aerodynamics = SUAVE.Attributes.Aerodynamics.Fidelity_Zero() aerodynamics.initialize(vehicle) vehicle.aerodynamics_model = aerodynamics # ------------------------------------------------------------------ # Not so Simple Propulsion Model # ------------------------------------------------------------------ vehicle.propulsion_model = net # ------------------------------------------------------------------ # Define Configurations # ------------------------------------------------------------------ # --- Takeoff Configuration --- config = vehicle.new_configuration("takeoff") # this configuration is derived from the baseline vehicle # --- Cruise Configuration --- config = vehicle.new_configuration("cruise") # this configuration is derived from vehicle.Configs.takeoff # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ 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
def main(): # ------------------------------------------------------------------ # Propulsor # ------------------------------------------------------------------ # build network net = Solar_Network() net.number_motors = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = 100 * Units.m panel.efficiency = 0.18 panel.mass_properties.mass = panel.area*.600 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller #Propeller design specs design_altitude = 0.0 * Units.km Velocity = 10.0 # freestream m/s RPM = 5887 Blades = 2.0 Radius = .4064 Hub_Radius = 0.05 Design_Cl = 0.7 Thrust = 0.0 #Specify either thrust or power to design for Power = 7500. #Specify either thrust or power to design for # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = Blades prop_attributes.freestream_velocity = Velocity prop_attributes.angular_velocity = RPM*(2.*np.pi/60.0) prop_attributes.tip_radius = Radius prop_attributes.hub_radius = Hub_Radius prop_attributes.design_Cl = Design_Cl prop_attributes.design_altitude = design_altitude prop_attributes.design_thrust = Thrust prop_attributes.design_power = Power prop_attributes = propeller_design(prop_attributes) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.01 motor.no_load_current = 8.0 motor.speed_constant = 140.*(2.*np.pi/60.) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 1. motor.gearbox_efficiency = 1. motor.expected_current = 260. motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 0. #Watts payload.mass_properties.mass = 0. * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Battery() bat.mass_properties.mass = 50. #kg bat.type = 'Li-Ion' bat.resistance = 0.0 net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 50.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Setup the conditions to run the network conditions = Data() conditions.propulsion = Data() conditions.freestream = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.frames.planet = Data() numerics = Data() # Calculate atmospheric properties atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() p, T, rho, a, mu = atmosphere.compute_values(design_altitude) conditions.propulsion.throttle = np.array([[1.0],[1.0]]) conditions.freestream.velocity = np.array([[1.0],[1.0]]) conditions.freestream.density = np.array([rho,rho]) conditions.freestream.viscosity = np.array([mu, mu]) conditions.freestream.speed_of_sound = np.array([a, a]) conditions.freestream.altitude = np.array([[design_altitude], [design_altitude]]) conditions.propulsion.battery_energy = bat.max_energy()*np.ones_like(conditions.freestream.altitude) conditions.frames.body.inertial_rotations = np.zeros([2,3]) conditions.frames.inertial.time = np.array([[0.0],[1.0]]) numerics.integrate_time = np.array([[0, 0],[0, 1]]) conditions.frames.planet.start_time = time.strptime("Sat, Jun 21 06:00:00 2014", "%a, %b %d %H:%M:%S %Y",) conditions.frames.planet.latitude = np.array([[0.0],[0.0]]) conditions.frames.planet.longitude = np.array([[0.0],[0.0]]) conditions.freestream.temperature = np.array([T, T]) # Run the network and print the results F, mdot, P = net(conditions,numerics) # Truth results truth_F = [[538.00449442], [538.00449442]] truth_P = [[14272.1902522],[14272.1902522]] truth_i = [[ 249.31622624],[ 249.31622624]] truth_rpm = [[ 6668.4094191],[ 6668.4094191]] truth_bat = [[45000000.] , [44987534.18868808]] error = Data() error.Thrust = np.max(np.abs(F-truth_F)) error.Propeller_Power = np.max(np.abs(P-truth_P)) error.RPM = np.max(np.abs(conditions.propulsion.rpm-truth_rpm)) error.Current = np.max(np.abs(conditions.propulsion.current-truth_i)) error.Battery = np.max(np.abs(bat.CurrentEnergy-truth_bat)) print error for k,v in error.items(): assert(np.abs(v)<0.001) return
def main(): # This script could fail if either the design or analysis scripts fail, # in case of failure check both. The design and analysis powers will # differ because of karman-tsien compressibility corrections in the # analysis scripts net = Battery_Propeller() net.number_of_engines = 2 # Design Gearbox gearbox = SUAVE.Components.Energy.Converters.Gearbox() gearbox.gearwheel_radius1 = 1 gearbox.gearwheel_radius2 = 1 gearbox.efficiency = 0.95 gearbox.inputs.torque = 885.550158704757 gearbox.inputs.speed = 207.16160479940007 gearbox.inputs.power = 183451.9920076409 gearbox.compute() # Design the Propeller with airfoil geometry defined bad_prop = SUAVE.Components.Energy.Converters.Propeller() bad_prop.tag = "Prop_W_Aifoil" bad_prop.number_of_blades = 2 bad_prop.number_of_engines = 1 bad_prop.freestream_velocity = 1 bad_prop.tip_radius = 0.3 bad_prop.hub_radius = 0.21336 bad_prop.design_tip_mach = 0.1 bad_prop.angular_velocity = gearbox.inputs.speed bad_prop.design_Cl = 0.7 bad_prop.design_altitude = 1. * Units.km bad_prop.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt'] bad_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' ]] bad_prop.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] bad_prop.design_thrust = 100000 bad_prop = propeller_design(bad_prop) prop_a = SUAVE.Components.Energy.Converters.Propeller() prop_a.tag = "Prop_W_Aifoil" prop_a.number_of_blades = 3 prop_a.number_of_engines = 1 prop_a.freestream_velocity = 49.1744 prop_a.tip_radius = 1.0668 prop_a.hub_radius = 0.21336 prop_a.design_tip_mach = 0.65 prop_a.angular_velocity = gearbox.inputs.speed # 207.16160479940007 prop_a.design_Cl = 0.7 prop_a.design_altitude = 1. * Units.km prop_a.airfoil_geometry = [ '../Vehicles/Airfoils/NACA_4412.txt', '../Vehicles/Airfoils/Clark_y.txt' ] prop_a.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' ], [ '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_50000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_100000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_200000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_500000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_1000000.txt' ] ] prop_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ] prop_a.design_thrust = 3054.4809132125697 prop_a = propeller_design(prop_a) # plot propeller plot_propeller(prop_a) # Design the Propeller with airfoil geometry defined prop = SUAVE.Components.Energy.Converters.Propeller() prop.tag = "Prop_No_Aifoil" prop.number_of_blades = 3 prop.number_of_engines = 1 prop.freestream_velocity = 49.1744 prop.tip_radius = 1.0668 prop.hub_radius = 0.21336 prop.design_tip_mach = 0.65 prop.angular_velocity = gearbox.inputs.speed prop.design_Cl = 0.7 prop.design_altitude = 1. * Units.km prop.origin = [[16. * 0.3048, 0., 2.02 * 0.3048]] prop.design_power = gearbox.outputs.power prop = propeller_design(prop) # Design a Rotor with airfoil geometry defined rot_a = SUAVE.Components.Energy.Converters.Rotor() rot_a.tag = "Rot_W_Aifoil" rot_a.tip_radius = 2.8 * Units.feet rot_a.hub_radius = 0.35 * Units.feet rot_a.number_of_blades = 2 rot_a.design_tip_mach = 0.65 rot_a.number_of_engines = 12 rot_a.disc_area = np.pi * (rot_a.tip_radius**2) rot_a.induced_hover_velocity = 12.756071638899549 rot_a.freestream_velocity = 500. * Units['ft/min'] rot_a.angular_velocity = 258.9520059992501 rot_a.design_Cl = 0.7 rot_a.design_altitude = 20 * Units.feet rot_a.design_thrust = 2271.2220451593753 rot_a.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt'] rot_a.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' ]] rot_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] rot_a = propeller_design(rot_a) # Design a Rotor without airfoil geometry defined rot = SUAVE.Components.Energy.Converters.Rotor() rot.tag = "Rot_No_Aifoil" rot.tip_radius = 2.8 * Units.feet rot.hub_radius = 0.35 * Units.feet rot.number_of_blades = 2 rot.design_tip_mach = 0.65 rot.number_of_engines = 12 rot.disc_area = np.pi * (rot.tip_radius**2) rot.induced_hover_velocity = 12.756071638899549 rot.freestream_velocity = 500. * Units['ft/min'] rot.angular_velocity = 258.9520059992501 rot.design_Cl = 0.7 rot.design_altitude = 20 * Units.feet rot.design_thrust = 2271.2220451593753 rot = propeller_design(rot) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(rot.design_altitude) V = prop.freestream_velocity Vr = rot.freestream_velocity conditions = Data() conditions.freestream = Data() conditions.propulsion = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions.propulsion.throttle = np.array([[1.0]]) conditions.frames.body.transform_to_inertial = np.array([np.eye(3)]) conditions_r = copy.deepcopy(conditions) conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions_r.frames.inertial.velocity_vector = np.array([[0, Vr, 0]]) # Create and attach this propeller prop_a.inputs.omega = np.array(prop.angular_velocity, ndmin=2) prop.inputs.omega = np.array(prop.angular_velocity, ndmin=2) rot_a.inputs.omega = copy.copy(prop.inputs.omega) rot.inputs.omega = copy.copy(prop.inputs.omega) # propeller with airfoil results F_a, Q_a, P_a, Cplast_a, output_a, etap_a = prop_a.spin(conditions) plot_results(output_a, prop_a, 'blue', '-', 's') # propeller without airfoil results conditions.propulsion.pitch_command = np.array([[1.0]]) * Units.degree F, Q, P, Cplast, output, etap = prop.spin(conditions) plot_results(output, prop, 'red', '-', 'o') # rotor with airfoil results Fr_a, Qr_a, Pr_a, Cplastr_a, outputr_a, etapr = rot_a.spin(conditions_r) plot_results(outputr_a, rot_a, 'green', '-', '^') # rotor with out airfoil results conditions_r.propulsion.pitch_command = np.array([[1.0]]) * Units.degree Fr, Qr, Pr, Cplastr, outputr, etapr = rot.spin(conditions_r) plot_results(outputr, rot, 'black', '-', 'P') # Truth values for propeller with airfoil geometry defined F_a_truth = 3390.61957425 Q_a_truth = 1001.363593 P_a_truth = 207444.08891448 Cplast_a_truth = 0.10692172 # Truth values for propeller without airfoil geometry defined F_truth = 2705.62228566 Q_truth = 815.76685175 P_truth = 168995.57015083 Cplast_truth = 0.08710442 # Truth values for rotor with airfoil geometry defined Fr_a_truth = 1447.00285504 Qr_a_truth = 191.05249889 Pr_a_truth = 39578.74227177 Cplastr_a_truth = 0.06225539 # Truth values for rotor without airfoil geometry defined Fr_truth = 1290.26055703 Qr_truth = 179.49371868 Pr_truth = 37184.2068134 Cplastr_truth = 0.0584889 # Store errors error = Data() error.Thrust_a = np.max(np.abs(F_a - F_a_truth)) error.Torque_a = np.max(np.abs(Q_a - Q_a_truth)) error.Power_a = np.max(np.abs(P_a - P_a_truth)) error.Cp_a = np.max(np.abs(Cplast_a - Cplast_a_truth)) error.Thrust = np.max(np.abs(F - F_truth)) error.Torque = np.max(np.abs(Q - Q_truth)) error.Power = np.max(np.abs(P - P_truth)) error.Cp = np.max(np.abs(Cplast - Cplast_truth)) error.Thrustr_a = np.max(np.abs(Fr_a - Fr_a_truth)) error.Torquer_a = np.max(np.abs(Qr_a - Qr_a_truth)) error.Powerr_a = np.max(np.abs(Pr_a - Pr_a_truth)) error.Cpr_a = np.max(np.abs(Cplastr_a - Cplastr_a_truth)) error.Thrustr = np.max(np.abs(Fr - Fr_truth)) error.Torquer = np.max(np.abs(Qr - Qr_truth)) error.Powerr = np.max(np.abs(Pr - Pr_truth)) error.Cpr = np.max(np.abs(Cplastr - Cplastr_truth)) print('Errors:') print(error) for k, v in list(error.items()): assert (np.abs(v) < 1e-6) return
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Solar' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 200. * Units.kg vehicle.mass_properties.operating_empty = 200. * Units.kg vehicle.mass_properties.max_takeoff = 200. * Units.kg # basic parameters vehicle.reference_area = 80. vehicle.envelope.ultimate_load = 2.0 vehicle.envelope.limit_load = 1.5 vehicle.envelope.maximum_dynamic_pressure = 0.5*1.225*(40.**2.) #Max q # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = vehicle.reference_area wing.spans.projected = 40.0 * Units.meter wing.aspect_ratio = (wing.spans.projected**2)/wing.areas.reference wing.sweeps.quarter_chord = 0.0 * Units.deg wing.symmetric = True wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.vertical = False wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected wing.chords.root = wing.areas.reference/wing.spans.projected wing.chords.tip = wing.areas.reference/wing.spans.projected wing.span_efficiency = 0.98 wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.highlift = False wing.vertical = False wing.number_ribs = 26. wing.number_end_ribs = 2. wing.transition_x_upper = 0.6 wing.transition_x_lower = 1.0 wing.origin = [3.0,0.0,0.0] # meters wing.aerodynamic_center = [3.0,0.0,0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 20. wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.95 wing.areas.reference = vehicle.reference_area * .15 wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.spans.projected = np.sqrt(wing.aspect_ratio*wing.areas.reference) wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.vertical = False wing.symmetric = True wing.dynamic_pressure_ratio = 0.9 wing.number_ribs = 5.0 wing.chords.root = wing.areas.reference/wing.spans.projected wing.chords.tip = wing.areas.reference/wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected wing.origin = [10.,0.0,0.0] # meters wing.aerodynamic_center = [0.5,0.0,0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' wing.aspect_ratio = 20. wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.97 wing.areas.reference = vehicle.reference_area * 0.1 wing.spans.projected = np.sqrt(wing.aspect_ratio*wing.areas.reference) wing.chords.root = wing.areas.reference/wing.spans.projected wing.chords.tip = wing.areas.reference/wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference/wing.spans.projected wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [10.,0.0,0.0] # meters wing.aerodynamic_center = [0.5,0.0,0.0] # meters wing.symmetric = True wing.vertical = True wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) #------------------------------------------------------------------ # Propulsor #------------------------------------------------------------------ # build network net = Solar() net.number_of_engines = 1. net.nacelle_diameter = 0.2 * Units.meters net.engine_length = 0.01 * Units.meters net.areas = Data() net.areas.wetted = 0.01*(2*np.pi*0.01/2.) # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = vehicle.reference_area * 0.9 panel.efficiency = 0.25 panel.mass_properties.mass = panel.area*(0.60 * Units.kg) net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 40.0 * Units['m/s']# freestream prop_attributes.angular_velocity = 150. * Units['rpm'] prop_attributes.tip_radius = 4.25 * Units.meters prop_attributes.hub_radius = 0.05 * Units.meters prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 14.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 3500.0 * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.008 motor.no_load_current = 4.5 * Units.ampere motor.speed_constant = 120. * Units['rpm'] # RPM/volt converted to (rad/s)/volt motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 12. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 160. # Expected current motor.mass_properties.mass = 2.0 * Units.kg net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 50. * Units.watts payload.mass_properties.mass = 5.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 50. * Units.watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion() bat.mass_properties.mass = 55.0 * Units.kg bat.specific_energy = 450. * Units.Wh/Units.kg bat.resistance = 0.05 initialize_from_mass(bat,bat.mass_properties.mass) net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 40.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # add the solar network to the vehicle vehicle.append_component(net) return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'tail_sitter' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 0.82 * Units.kg vehicle.mass_properties.operating_empty = 0.82 * Units.kg vehicle.mass_properties.max_takeoff = 0.82 * Units.kg # basic parameters vehicle.reference_area = 0.1668 # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.areas.reference = vehicle.reference_area wing.spans.projected = 1.03 * Units.m wing.aspect_ratio = (wing.spans.projected**2)/wing.areas.reference wing.sweeps.quarter_chord = 5.0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.dynamic_pressure_ratio = 1.0 wing.chords.mean_aerodynamic = 0.162 * Units.m wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.high_lift = False wing.vertical = False wing.symmetric = True # add to vehicle vehicle.append_component(wing) #------------------------------------------------------------------ # Propulsor #------------------------------------------------------------------ # build network net = SUAVE.Components.Energy.Networks.Battery_Propeller() net.number_of_propeller_engines = 4. net.voltage = 12.3 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 # Design the Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2.0 prop.freestream_velocity = 15.0 # freestream m/s prop.angular_velocity = 7500. * Units['rpm'] prop.tip_radius = 4. * Units.inch prop.hub_radius = 0.125 * Units.inch prop.design_Cl = 0.7 prop.design_altitude = 0.1 * Units.km prop.design_power = 200. * Units.watts prop = propeller_design(prop) origins = [[0., 0.15, -0.05], [0., -0.15, -0.05], [0., .35, 0.05], [0., 0.35, 0.05]] for ii in range(4): rotor = deepcopy(prop) rotor.tag = 'propeller' rotor.origin = [origins[ii]] net.propellers.append(rotor) # Component 3 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.speed_constant = 1500. * Units['rpm'] # RPM/volt converted to (rad/s)/volt motor = size_from_kv(motor) motor.gear_ratio = 1. # Gear ratio motor.gearbox_efficiency = 1. # Gear box efficiency motor.expected_current = 10. # Expected current motor.propeller_radius = prop.tip_radius for ii in range(4): rotor_motor = deepcopy(motor) rotor_motor.tag = 'motor' rotor_motor.origin = [origins[ii]] net.propeller_motors.append(rotor_motor) # Component 4 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 0. #Watts payload.mass_properties.mass = 0.0 * Units.kg net.payload = payload # Component 5 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 2. #Watts net.avionics = avionics # Component 6 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion() bat.mass_properties.mass = 0.17 * Units.kg bat.specific_energy = 175.*Units.Wh/Units.kg bat.resistance = 0.003 bat.max_voltage = 11.1 initialize_from_mass(bat) net.battery = bat # add the solar network to the vehicle vehicle.append_component(net) return vehicle
def main(): # This script could fail if either the design or analysis scripts fail, # in case of failure check both. The design and analysis powers will # differ because of karman-tsien compressibility corrections in the # analysis scripts net = Battery_Propeller() net.number_of_propeller_engines = 2 # Design Gearbox gearbox = SUAVE.Components.Energy.Converters.Gearbox() gearbox.gearwheel_radius1 = 1 gearbox.gearwheel_radius2 = 1 gearbox.efficiency = 0.95 gearbox.inputs.torque = 885.550158704757 gearbox.inputs.speed = 207.16160479940007 gearbox.inputs.power = 183451.9920076409 gearbox.compute() # Design the Propeller with airfoil geometry defined bad_prop = SUAVE.Components.Energy.Converters.Propeller() bad_prop.tag = "Prop_W_Aifoil" bad_prop.number_of_blades = 2 bad_prop.number_of_engines = 1 bad_prop.freestream_velocity = 1 bad_prop.tip_radius = 0.3 bad_prop.hub_radius = 0.21336 bad_prop.design_tip_mach = 0.1 bad_prop.angular_velocity = gearbox.inputs.speed bad_prop.design_Cl = 0.7 bad_prop.design_altitude = 1. * Units.km bad_prop.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt'] bad_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' ]] bad_prop.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] bad_prop.design_thrust = 100000 bad_prop = propeller_design(bad_prop) prop_a = SUAVE.Components.Energy.Converters.Propeller() prop_a.tag = "Prop_W_Aifoil" prop_a.number_of_blades = 3 prop_a.number_of_engines = 1 prop_a.freestream_velocity = 49.1744 prop_a.tip_radius = 1.0668 prop_a.hub_radius = 0.21336 prop_a.design_tip_mach = 0.65 prop_a.angular_velocity = gearbox.inputs.speed # 207.16160479940007 prop_a.design_Cl = 0.7 prop_a.design_altitude = 1. * Units.km prop_a.airfoil_geometry = [ '../Vehicles/Airfoils/NACA_4412.txt', '../Vehicles/Airfoils/Clark_y.txt' ] prop_a.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' ], [ '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_50000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_100000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_200000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_500000.txt', '../Vehicles/Airfoils/Polars/Clark_y_polar_Re_1000000.txt' ] ] prop_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 ] prop_a.design_thrust = 3054.4809132125697 prop_a = propeller_design(prop_a) # plot propeller plot_propeller(prop_a) # Design the Propeller with airfoil geometry defined prop = SUAVE.Components.Energy.Converters.Propeller() prop.tag = "Prop_No_Aifoil" prop.number_of_blades = 3 prop.number_of_engines = 1 prop.freestream_velocity = 49.1744 prop.tip_radius = 1.0668 prop.hub_radius = 0.21336 prop.design_tip_mach = 0.65 prop.angular_velocity = gearbox.inputs.speed prop.design_Cl = 0.7 prop.design_altitude = 1. * Units.km prop.origin = [[16. * 0.3048, 0., 2.02 * 0.3048]] prop.design_power = gearbox.outputs.power prop = propeller_design(prop) # Design a Rotor with airfoil geometry defined rot_a = SUAVE.Components.Energy.Converters.Rotor() rot_a.tag = "Rot_W_Aifoil" rot_a.tip_radius = 2.8 * Units.feet rot_a.hub_radius = 0.35 * Units.feet rot_a.number_of_blades = 2 rot_a.design_tip_mach = 0.65 rot_a.number_of_engines = 12 rot_a.disc_area = np.pi * (rot_a.tip_radius**2) rot_a.freestream_velocity = 500. * Units['ft/min'] rot_a.angular_velocity = 258.9520059992501 rot_a.design_Cl = 0.7 rot_a.design_altitude = 20 * Units.feet rot_a.design_thrust = 2271.2220451593753 rot_a.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt'] rot_a.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' ]] rot_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] rot_a = propeller_design(rot_a) # Design a Rotor without airfoil geometry defined rot = SUAVE.Components.Energy.Converters.Rotor() rot.tag = "Rot_No_Aifoil" rot.tip_radius = 2.8 * Units.feet rot.hub_radius = 0.35 * Units.feet rot.number_of_blades = 2 rot.design_tip_mach = 0.65 rot.number_of_engines = 12 rot.disc_area = np.pi * (rot.tip_radius**2) rot.freestream_velocity = 500. * Units['ft/min'] rot.angular_velocity = 258.9520059992501 rot.design_Cl = 0.7 rot.design_altitude = 20 * Units.feet rot.design_thrust = 2271.2220451593753 rot = propeller_design(rot) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(rot.design_altitude) V = prop.freestream_velocity Vr = rot.freestream_velocity conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics() conditions._size = 1 conditions.freestream = Data() conditions.propulsion = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions.propulsion.throttle = np.array([[1.0]]) conditions.frames.body.transform_to_inertial = np.array([np.eye(3)]) conditions_r = copy.deepcopy(conditions) conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions_r.frames.inertial.velocity_vector = np.array([[0, Vr, 0]]) # Create and attach this propeller prop_a.inputs.omega = np.array(prop.angular_velocity, ndmin=2) prop.inputs.omega = np.array(prop.angular_velocity, ndmin=2) rot_a.inputs.omega = copy.copy(prop.inputs.omega) rot.inputs.omega = copy.copy(prop.inputs.omega) # propeller with airfoil results prop_a.inputs.pitch_command = 0.0 * Units.degree F_a, Q_a, P_a, Cplast_a, output_a, etap_a = prop_a.spin(conditions) plot_results(output_a, prop_a, 'blue', '-', 's') # propeller without airfoil results prop.inputs.pitch_command = 0.0 * Units.degree F, Q, P, Cplast, output, etap = prop.spin(conditions) plot_results(output, prop, 'red', '-', 'o') # rotor with airfoil results rot_a.inputs.pitch_command = 0.0 * Units.degree Fr_a, Qr_a, Pr_a, Cplastr_a, outputr_a, etapr = rot_a.spin(conditions_r) plot_results(outputr_a, rot_a, 'green', '-', '^') # rotor with out airfoil results rot.inputs.pitch_command = 0.0 * Units.degree Fr, Qr, Pr, Cplastr, outputr, etapr = rot.spin(conditions_r) plot_results(outputr, rot, 'black', '-', 'P') # Truth values for propeller with airfoil geometry defined F_a_truth = 3346.252387977257 Q_a_truth = 982.79237764 P_a_truth = 203596.8461368 Cplast_a_truth = 0.10493876 # Truth values for propeller without airfoil geometry defined F_truth = 2629.0134410677906 Q_truth = 787.38493275 P_truth = 163115.92626346 Cplast_truth = 0.08407391 # Truth values for rotor with airfoil geometry defined Fr_a_truth = 1500.9917429652628 Qr_a_truth = 141.39427382 Pr_a_truth = 29291.46467336 Cplastr_a_truth = 0.04607401 # Truth values for rotor without airfoil geometry defined Fr_truth = 1250.1858330726345 Qr_truth = 121.95427719 Pr_truth = 25264.24377481 Cplastr_truth = 0.0397394 # Store errors error = Data() error.Thrust_a = np.max(np.abs(np.linalg.norm(F_a) - F_a_truth)) error.Torque_a = np.max(np.abs(Q_a - Q_a_truth)) error.Power_a = np.max(np.abs(P_a - P_a_truth)) error.Cp_a = np.max(np.abs(Cplast_a - Cplast_a_truth)) error.Thrust = np.max(np.abs(np.linalg.norm(F) - F_truth)) error.Torque = np.max(np.abs(Q - Q_truth)) error.Power = np.max(np.abs(P - P_truth)) error.Cp = np.max(np.abs(Cplast - Cplast_truth)) error.Thrustr_a = np.max(np.abs(np.linalg.norm(Fr_a) - Fr_a_truth)) error.Torquer_a = np.max(np.abs(Qr_a - Qr_a_truth)) error.Powerr_a = np.max(np.abs(Pr_a - Pr_a_truth)) error.Cpr_a = np.max(np.abs(Cplastr_a - Cplastr_a_truth)) error.Thrustr = np.max(np.abs(np.linalg.norm(Fr) - Fr_truth)) error.Torquer = np.max(np.abs(Qr - Qr_truth)) error.Powerr = np.max(np.abs(Pr - Pr_truth)) error.Cpr = np.max(np.abs(Cplastr - Cplastr_truth)) print('Errors:') print(error) for k, v in list(error.items()): assert (np.abs(v) < 1e-6) return
def main(): # ------------------------------------------------------------------ # Propulsor # ------------------------------------------------------------------ # build network net = Solar() net.number_of_engines = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = 100 * Units.m panel.efficiency = 0.18 panel.mass_properties.mass = panel.area*.600 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Propeller design specs design_altitude = 0.0 * Units.km Velocity = 10.0 # freestream m/s RPM = 5887 Blades = 2.0 Radius = .4064 Hub_Radius = 0.05 Design_Cl = 0.7 Thrust = 0.0 #Specify either thrust or power to design for Power = 7500. #Specify either thrust or power to design for # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = Blades prop_attributes.freestream_velocity = Velocity prop_attributes.angular_velocity = RPM*(2.*np.pi/60.0) prop_attributes.tip_radius = Radius prop_attributes.hub_radius = Hub_Radius prop_attributes.design_Cl = Design_Cl prop_attributes.design_altitude = design_altitude prop_attributes.design_thrust = Thrust prop_attributes.design_power = Power prop_attributes = propeller_design(prop_attributes) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.01 motor.no_load_current = 8.0 motor.speed_constant = 140.*(2.*np.pi/60.) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius #motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 1. motor.gearbox_efficiency = 1. motor.expected_current = 260. motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 0. #Watts payload.mass_properties.mass = 0. * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion() batterymass = 50. #kg bat.type = 'Li-Ion' bat.resistance = 0.0 bat.energy_density = 250. initialize_from_mass(bat,batterymass) bat.current_energy = bat.max_energy net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 50.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Setup the conditions to run the network state = Data() state.conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics() state.numerics = SUAVE.Analyses.Mission.Segments.Conditions.Numerics() conditions = state.conditions numerics = state.numerics # Calculate atmospheric properties atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(prop_attributes.design_altitude) rho = atmosphere_conditions.density[0,:] a = atmosphere_conditions.speed_of_sound[0,:] mu = atmosphere_conditions.dynamic_viscosity[0,:] T = atmosphere_conditions.temperature[0,:] conditions.propulsion.throttle = np.array([[1.0],[1.0]]) conditions.freestream.velocity = np.array([[1.0],[1.0]]) conditions.freestream.density = np.array([rho,rho]) conditions.freestream.dynamic_viscosity = np.array([mu, mu]) conditions.freestream.speed_of_sound = np.array([a, a]) conditions.freestream.altitude = np.array([[design_altitude], [design_altitude]]) conditions.propulsion.battery_energy = bat.max_energy*np.ones_like(conditions.freestream.altitude) conditions.frames.body.inertial_rotations = np.zeros([2,3]) conditions.frames.inertial.time = np.array([[0.0],[1.0]]) numerics.time.integrate = np.array([[0, 0],[0, 1]]) numerics.time.differentiate = np.array([[0, 0],[0, 1]]) conditions.frames.planet.start_time = time.strptime("Sat, Jun 21 06:00:00 2014", "%a, %b %d %H:%M:%S %Y",) conditions.frames.planet.latitude = np.array([[0.0],[0.0]]) conditions.frames.planet.longitude = np.array([[0.0],[0.0]]) conditions.freestream.temperature = np.array([T, T]) conditions.frames.body.transform_to_inertial = np.array([[[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]], [[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]]]) conditions.propulsion.propeller_power_coefficient = np.array([[1.], [1.]]) * prop.prop_attributes.Cp # Run the network and print the results results = net(state) F = results.thrust_force_vector # Truth results truth_F = [[ 545.35952329, 545.35952329]] truth_i = [[ 249.31622624], [ 249.31622624]] truth_rpm = [[ 6668.4094191], [ 6668.4094191]] truth_bat = [[ 36000000. ], [ 35987534.18868808]] error = Data() error.Thrust = np.max(np.abs(F[:,0]-truth_F)) error.RPM = np.max(np.abs(conditions.propulsion.rpm-truth_rpm)) error.Current = np.max(np.abs(conditions.propulsion.current-truth_i)) error.Battery = np.max(np.abs(bat.current_energy-truth_bat)) print(error) for k,v in list(error.items()): assert(np.abs(v)<1e-6) return
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 = segment_properties(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 = 2.0 prop.freestream_velocity = 135. * Units['mph'] prop.angular_velocity = 1300. * Units.rpm prop.tip_radius = 76. / 2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_altitude = 12000. * Units.feet prop.design_thrust = 1200. 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) 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 = 500. 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.784]] motor.nominal_voltage = bat.max_voltage * 3 / 4 motor.propeller_radius = prop.tip_radius motor.no_load_current = 4.0 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.784]] 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
def configs_setup(vehicle): #--------------------------------------------------------------------------- # Initialize Configurations #--------------------------------------------------------------------------- configs = SUAVE.Components.Configs.Config.Container() base_config = SUAVE.Components.Configs.Config(vehicle) base_config.tag = 'base' configs.append(base_config) #--------------------------------------------------------------------------- # Electric Helicopter Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_helicopter' config.propulsors.network.number_of_engines = 1 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 3800. * Units.mm prop_attributes.hub_radius = 500. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 1600. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0., 0., 0.] config.propulsors.network.propeller = prop configs.append(config) #--------------------------------------------------------------------------- # Electric Stopped Rotor Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_stopped_rotor' config.propulsors.network.number_of_engines = 8 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 800. * Units.mm #608 prop_attributes.hub_radius = 150. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 200. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0., 0., 0.] config.propulsors.network.propeller = prop thrust_prop_attributes = cp.deepcopy(prop_attributes) thrust_prop_attributes.number_blades = 2.0 thrust_prop = SUAVE.Components.Energy.Converters.Propeller() thrust_prop.prop_attributes = thrust_prop_attributes config.propulsors.network.thrust_propeller = thrust_prop configs.append(config) #--------------------------------------------------------------------------- # Electric Tiltrotor Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_tiltrotor' config.propulsors.network.number_of_engines = 8 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 800. * Units.mm #608 prop_attributes.hub_radius = 150. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 200. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0., 0., 0.] config.propulsors.network.propeller = prop configs.append(config) return configs
def main(): # ------------------------------------------------------------------ # Propulsor # ------------------------------------------------------------------ # build network net = Solar_Network() net.number_motors = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = 100 * Units.m panel.efficiency = 0.18 panel.mass_properties.mass = panel.area * .600 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller #Propeller design specs design_altitude = 0.0 * Units.km Velocity = 10.0 # freestream m/s RPM = 5887 Blades = 2.0 Radius = .4064 Hub_Radius = 0.05 Design_Cl = 0.7 Thrust = 0.0 #Specify either thrust or power to design for Power = 7500. #Specify either thrust or power to design for # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = Blades prop_attributes.freestream_velocity = Velocity prop_attributes.angular_velocity = RPM * (2. * np.pi / 60.0) prop_attributes.tip_radius = Radius prop_attributes.hub_radius = Hub_Radius prop_attributes.design_Cl = Design_Cl prop_attributes.design_altitude = design_altitude prop_attributes.design_thrust = Thrust prop_attributes.design_power = Power prop_attributes = propeller_design(prop_attributes) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.01 motor.no_load_current = 8.0 motor.speed_constant = 140. * (2. * np.pi / 60. ) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 1. motor.gearbox_efficiency = 1. motor.expected_current = 260. motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 0. #Watts payload.mass_properties.mass = 0. * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Battery() bat.mass_properties.mass = 50. #kg bat.type = 'Li-Ion' bat.resistance = 0.0 net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 50.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Setup the conditions to run the network conditions = Data() conditions.propulsion = Data() conditions.freestream = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.frames.planet = Data() numerics = Data() # Calculate atmospheric properties atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() p, T, rho, a, mu = atmosphere.compute_values(design_altitude) conditions.propulsion.throttle = np.array([[1.0], [1.0]]) conditions.freestream.velocity = np.array([[1.0], [1.0]]) conditions.freestream.density = np.array([rho, rho]) conditions.freestream.viscosity = np.array([mu, mu]) conditions.freestream.speed_of_sound = np.array([a, a]) conditions.freestream.altitude = np.array([[design_altitude], [design_altitude]]) conditions.propulsion.battery_energy = bat.max_energy() * np.ones_like( conditions.freestream.altitude) conditions.frames.body.inertial_rotations = np.zeros([2, 3]) conditions.frames.inertial.time = np.array([[0.0], [1.0]]) numerics.integrate_time = np.array([[0, 0], [0, 1]]) conditions.frames.planet.start_time = time.strptime( "Sat, Jun 21 06:00:00 2014", "%a, %b %d %H:%M:%S %Y", ) conditions.frames.planet.latitude = np.array([[0.0], [0.0]]) conditions.frames.planet.longitude = np.array([[0.0], [0.0]]) conditions.freestream.temperature = np.array([T, T]) # Run the network and print the results F, mdot, P = net(conditions, numerics) # Truth results truth_F = [[538.00449442], [538.00449442]] truth_P = [[14272.1902522], [14272.1902522]] truth_i = [[249.31622624], [249.31622624]] truth_rpm = [[6668.4094191], [6668.4094191]] truth_bat = [[45000000.], [44987534.18868808]] error = Data() error.Thrust = np.max(np.abs(F - truth_F)) error.Propeller_Power = np.max(np.abs(P - truth_P)) error.RPM = np.max(np.abs(conditions.propulsion.rpm - truth_rpm)) error.Current = np.max(np.abs(conditions.propulsion.current - truth_i)) error.Battery = np.max(np.abs(bat.CurrentEnergy - truth_bat)) print error for k, v in error.items(): assert (np.abs(v) < 0.001) return
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.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.span_efficiency = 0.9 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) # 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.span_efficiency = 0.9 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 = [14.0*0.3048 , 0.0 , 0.205 ] wing.aerodynamic_center = [15.0*0.3048 , 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.span_efficiency = 0.9 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 = [14.0*0.3048 , 4.0*0.3048 , 0.205 ] wing.aerodynamic_center = 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.span_efficiency = 0.9 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 = [14.0*0.3048 , -4.0*0.3048 , 0.205 ] wing.aerodynamic_center = 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.origin = [[0. , 0., 0.]] 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 = 16.0 * Units.feet 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.Fuselages.Segment() segment.tag = 'segment_1' segment.origin = [0., 0. ,0.] segment.percent_x_location = 0. segment.percent_z_location = 0.0 segment.height = 0.1 * Units.feet segment.width = 0.1 * Units.feet segment.length = 0. segment.effective_diameter = 0.1 * Units.feet fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_2' segment.origin = [4.*0.3048 , 0. ,0.1*0.3048 ] segment.percent_x_location = 0.25 segment.percent_z_location = 0.05 segment.height = 3.75 * Units.feet segment.width = 5.65 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.65 * Units.feet fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_3' segment.origin = [8.*0.3048 , 0. ,0.34*0.3048 ] segment.percent_x_location = 0.5 segment.percent_z_location = 0.071 segment.height = 4.65 * Units.feet segment.width = 5.55 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.55 * Units.feet fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_4' segment.origin = [12.*0.3048 , 0. ,0.77*0.3048 ] segment.percent_x_location = 0.75 segment.percent_z_location = 0.089 segment.height = 4.73 * Units.feet segment.width = 4.26 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 4.26 * Units.feet fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_5' segment.origin = [16.*0.3048 , 0. ,2.02*0.3048 ] segment.percent_x_location = 1.0 segment.percent_z_location = 0.158 segment.height = 0.67 * Units.feet segment.width = 0.33 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 0.33 * Units.feet fuselage.Segments.append(segment) # add to vehicle vehicle.append_component(fuselage) #------------------------------------------------------------------- # BOOMS #------------------------------------------------------------------- boom = SUAVE.Components.Fuselages.Fuselage() boom.tag = 'Boom_1R' boom.configuration = 'Boom' boom.origin = [[0.718,7.5*0.3048 , -0.15 ]] boom.seats_abreast = 0. boom.seat_pitch = 0.0 boom.fineness.nose = 0.950 boom.fineness.tail = 1.029 boom.lengths.nose = 0.5 * Units.feet boom.lengths.tail = 0.5 * Units.feet boom.lengths.cabin = 9.0 * Units.feet boom.lengths.total = 10 * Units.feet boom.width = 0.5 * Units.feet boom.heights.maximum = 0.5 * Units.feet boom.heights.at_quarter_length = 0.5 * Units.feet boom.heights.at_three_quarters_length = 0.5 * Units.feet boom.heights.at_wing_root_quarter_chord = 0.5 * Units.feet boom.areas.wetted = 18 * Units.feet**2 boom.areas.front_projected = 0.26 * Units.feet**2 boom.effective_diameter = 0.5 * Units.feet boom.differential_pressure = 0. boom.y_pitch_count = 2 boom.y_pitch = (72/12)*0.3048 boom.symmetric = True boom.boom_pitch = 6 * Units.feet boom.index = 1 # add to vehicle vehicle.append_component(boom) # create pattern of booms on one side original_boom_origin = boom.origin if boom.y_pitch_count > 1 : for n in range(boom.y_pitch_count): if n == 0: continue else: index = n+1 boom = deepcopy(vehicle.fuselages.boom_1r) boom.origin[0][1] = n*boom.boom_pitch + original_boom_origin[0][1] boom.tag = 'Boom_' + str(index) + 'R' boom.index = n vehicle.append_component(boom) if boom.symmetric : for n in range(boom.y_pitch_count): index = n+1 boom = deepcopy(vehicle.fuselages.boom_1r) boom.origin[0][1] = -n*boom.boom_pitch - original_boom_origin[0][1] boom.tag = 'Boom_' + str(index) + 'L' boom.index = n vehicle.append_component(boom) #------------------------------------------------------------------ # PROPULSOR #------------------------------------------------------------------ net = Lift_Cruise() net.number_of_engines_lift = 12 net.number_of_engines_forward = 1 net.thrust_angle_lift = 90. * Units.degrees net.thrust_angle_forward = 0. 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 #------------------------------------------------------------------ esc_lift = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc_lift.efficiency = 0.95 net.esc_lift = esc_lift esc_thrust = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc_thrust.efficiency = 0.95 net.esc_forward = esc_thrust #------------------------------------------------------------------ # 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() bat.specific_energy = 300. * Units.Wh/Units.kg bat.resistance = 0.005 bat.max_voltage = net.voltage bat.mass_properties.mass = 300. * Units.kg initialize_from_mass(bat, bat.mass_properties.mass) 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 # Thrust Propeller propeller = SUAVE.Components.Energy.Converters.Propeller() propeller.number_blades = 3 propeller.number_of_engines = net.number_of_engines_forward propeller.freestream_velocity = V_inf propeller.tip_radius = 1.0668 propeller.hub_radius = 0.21336 propeller.design_tip_mach = 0.65 propeller.angular_velocity = propeller.design_tip_mach *speed_of_sound /propeller.tip_radius propeller.design_Cl = 0.7 propeller.design_altitude = 1. * Units.km propeller.design_thrust = (Drag*2.5)/net.number_of_engines_forward propeller = propeller_design(propeller) propeller.origin = [[16.*0.3048 , 0. ,2.02*0.3048 ]] net.propeller = propeller # Lift Rotors rotor = SUAVE.Components.Energy.Converters.Rotor() rotor.tip_radius = 2.8 * Units.feet rotor.hub_radius = 0.35 * Units.feet rotor.number_blades = 2 rotor.design_tip_mach = 0.65 rotor.number_of_engines = net.number_of_engines_lift rotor.disc_area = np.pi*(rotor.tip_radius**2) rotor.induced_hover_velocity = np.sqrt(Hover_Load/(2*rho*rotor.disc_area*net.number_of_engines_lift)) rotor.freestream_velocity = 500. * Units['ft/min'] rotor.angular_velocity = rotor.design_tip_mach* speed_of_sound /rotor.tip_radius rotor.design_Cl = 0.7 rotor.design_altitude = 20 * Units.feet rotor.design_thrust = (Hover_Load * 2.5 )/net.number_of_engines_lift rotor.x_pitch_count = 2 rotor.y_pitch_count = vehicle.fuselages['boom_1r'].y_pitch_count rotor.y_pitch = vehicle.fuselages['boom_1r'].y_pitch rotor = propeller_design(rotor) rotor.origin = vehicle.fuselages['boom_1r'].origin rotor.symmetric = True # populating propellers on one side of wing if rotor.y_pitch_count > 1 : for n in range(rotor.y_pitch_count): if n == 0: continue propeller_origin = [rotor.origin[0][0] , rotor.origin[0][1] + n*rotor.y_pitch ,rotor.origin[0][2]] rotor.origin.append(propeller_origin) # populating propellers on one side of the vehicle if rotor.x_pitch_count > 1 : relative_prop_origins = np.linspace(0,vehicle.fuselages['boom_1r'].lengths.total,rotor.x_pitch_count) for n in range(len(rotor.origin)): for m in range(len(relative_prop_origins)-1): propeller_origin = [rotor.origin[n][0] + relative_prop_origins[m+1] , rotor.origin[n][1] ,rotor.origin[n][2] ] rotor.origin.append(propeller_origin) # propulating propellers on the other side of thevehicle if rotor.symmetric : for n in range(len(rotor.origin)): propeller_origin = [rotor.origin[n][0] , -rotor.origin[n][1] ,rotor.origin[n][2] ] rotor.origin.append(propeller_origin) # re-compute number of lift rotors if changed net.number_of_engines_lift = len(rotor.origin) # append propellers to vehicle net.rotor = rotor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller (Thrust) motor motor_forward = SUAVE.Components.Energy.Converters.Motor() motor_forward.efficiency = 0.95 motor_forward.nominal_voltage = bat.max_voltage *3/4 motor_forward.mass_properties.mass = 2.0 * Units.kg motor_forward.origin = propeller.origin motor_forward.propeller_radius = propeller.tip_radius motor_forward.gear_ratio = 1. motor_forward.gearbox_efficiency = 1. # Gear box efficiency motor_forward.no_load_current = 2.0 motor_forward = compute_optimal_motor_parameters(motor_forward,propeller) net.motor_forward = motor_forward # Rotor (Lift) Motor motor_lift = SUAVE.Components.Energy.Converters.Motor() motor_lift.efficiency = 0.95 motor_lift.nominal_voltage = bat.max_voltage motor_lift.mass_properties.mass = 3. * Units.kg motor_lift.origin = rotor.origin motor_lift.propeller_radius = rotor.tip_radius motor_lift.gear_ratio = 1.0 motor_lift.gearbox_efficiency = 1.0 motor_lift.no_load_current = 4.0 motor_lift = compute_optimal_motor_parameters(motor_lift,rotor) net.motor_lift = motor_lift # 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 return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Tiltwing' vehicle.configuration = 'eVTOL' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 2250. * Units.lb vehicle.mass_properties.operating_empty = 2250. * Units.lb vehicle.mass_properties.max_takeoff = 2250. * Units.lb vehicle.mass_properties.center_of_gravity = [[ 2.0144, 0. , 0.]] vehicle.passengers = 1 vehicle.reference_area = 10.58275476 vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3. # ------------------------------------------------------ # WINGS # ------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'canard_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [[0.1, 0.0 , 0.0]] wing.aerodynamic_center = [0.3, 0.0 , 0.0] wing.winglet_fraction = 0.0 wing.symmetric = True # add to vehicle vehicle.append_component(wing) wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [[ 5.138, 0.0 , 1.323 ]] # for images 1.54 wing.aerodynamic_center = [ 5.3, 0.0 , 1.323 ] wing.winglet_fraction = 0.0 wing.symmetric = True # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------ # FUSELAGE # ------------------------------------------------------ # FUSELAGE PROPERTIES fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.seats_abreast = 0. fuselage.seat_pitch = 1. fuselage.fineness.nose = 1.5 fuselage.fineness.tail = 4.0 fuselage.lengths.nose = 1.7 fuselage.lengths.tail = 2.7 fuselage.lengths.cabin = 1.7 fuselage.lengths.total = 6.1 fuselage.width = 1.15 fuselage.heights.maximum = 1.7 fuselage.heights.at_quarter_length = 1.2 fuselage.heights.at_wing_root_quarter_chord = 1.7 fuselage.heights.at_three_quarters_length = 0.75 fuselage.areas.wetted = 12.97989862 fuselage.areas.front_projected = 1.365211404 fuselage.effective_diameter = 1.318423736 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. segment.height = 0.09 segment.width = 0.23473 segment.length = 0. segment.effective_diameter = 0. fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_1' segment.percent_x_location = 0.97675/6.1 segment.percent_z_location = 0.21977/6.1 segment.height = 0.9027 segment.width = 1.01709 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_2' segment.percent_x_location = 1.93556/6.1 segment.percent_z_location = 0.39371/6.1 segment.height = 1.30558 segment.width = 1.38871 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_3' segment.percent_x_location = 3.44137/6.1 segment.percent_z_location = 0.57143/6.1 segment.height = 1.52588 segment.width = 1.47074 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_4' segment.percent_x_location = 4.61031/6.1 segment.percent_z_location = 0.81577/6.1 segment.height = 1.14788 segment.width = 1.11463 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 = 1.19622/6.1 segment.height = 0.31818 segment.width = 0.23443 fuselage.Segments.append(segment) # add to vehicle vehicle.append_component(fuselage) #------------------------------------------------------------------ # network #------------------------------------------------------------------ net = SUAVE.Components.Energy.Networks.Battery_Propeller() net.number_of_propeller_engines = 8 net.thrust_angle = 0.0 * Units.degrees # conversion to radians, net.nacelle_diameter = 0.2921 # https://www.magicall.biz/products/integrated-motor-controller-magidrive/ net.engine_length = 0.95 net.areas = Data() net.areas.wetted = np.pi*net.nacelle_diameter*net.engine_length + 0.5*np.pi*net.nacelle_diameter**2 net.voltage = 400. net.identical_propellers = True #------------------------------------------------------------------ # Design Electronic Speed Controller #------------------------------------------------------------------ esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 net.esc = esc # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 10. #Watts payload.mass_properties.mass = 0.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 20. #Watts net.avionics = avionics #------------------------------------------------------------------ # Design Battery #------------------------------------------------------------------ bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion_LiNiMnCoO2_18650() bat.mass_properties.mass = 200. * 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 # Component 9 Miscellaneous Systems sys = SUAVE.Components.Systems.System() sys.mass_properties.mass = 5 # kg #------------------------------------------------------------------ # Nacelles #------------------------------------------------------------------ nacelle = SUAVE.Components.Nacelles.Nacelle() nacelle.diameter = 0.2921 nacelle.length = 0.95 nacelle_origins = [[-0.2, 1.347, 0.0], [-0.2, 3.2969999999999997, 0.0], [-0.2, -1.347, 0.0], [-0.2, -3.2969999999999997, 0.0], [4.938, 1.347, 1.54], [4.938, 3.2969999999999997, 1.54], [4.938, -1.347, 1.54], [4.938, -3.2969999999999997, 1.54]] nacelle.areas.wetted = np.pi*nacelle.diameter*nacelle.length + 0.5*np.pi*nacelle.diameter**2 for idx in range(8): nacelle = deepcopy(nacelle) nacelle.tag = 'nacelle_' + str(idx) nacelle.origin = [nacelle_origins[idx]] vehicle.append_component(nacelle) #------------------------------------------------------------------ # Design Rotors #------------------------------------------------------------------ # atmosphere conditions speed_of_sound = 340 # Create propeller geometry prop = SUAVE.Components.Energy.Converters.Propeller() # This is truly a prop because the default of the mission is pointing forward prop.tip_radius = 0.8875 prop.hub_radius = 0.15 prop.disc_area = np.pi*(prop.tip_radius**2) prop.design_tip_mach = 0.5 prop.number_of_blades = 3 prop.freestream_velocity = 10 prop.angular_velocity = prop.design_tip_mach*speed_of_sound/prop.tip_radius prop.design_Cl = 0.7 prop.design_altitude = 500 * Units.feet Hover_Load = vehicle.mass_properties.takeoff*9.81 prop.design_thrust = Hover_Load/(net.number_of_propeller_engines-1) # contingency for one-engine-inoperative condition 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) prop.rotation = 1 # Front Rotors Locations origins = [[-0.2, 1.347, 0.0], [-0.2, 3.2969999999999997, 0.0], [-0.2, -1.347, 0.0], [-0.2, -3.2969999999999997, 0.0],\ [4.938, 1.347, 1.54], [4.938, 3.2969999999999997, 1.54], [4.938, -1.347, 1.54], [4.938, -3.2969999999999997, 1.54]] for ii in range(8): rotor = deepcopy(prop) rotor.tag = 'propeller' rotor.origin = [origins[ii]] net.propellers.append(rotor) # Motor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller (Thrust) motor motor = SUAVE.Components.Energy.Converters.Motor() motor.efficiency = 0.9 motor.nominal_voltage = bat.max_voltage *3/4 motor.propeller_radius = prop.tip_radius motor.no_load_current = 2.0 motor = size_optimal_motor(motor,prop) motor.mass_properties.mass = nasa_motor(motor.design_torque) net.motor = motor for ii in range(8): rotor_motor = deepcopy(motor) rotor_motor.tag = 'motor' rotor_motor.origin = [origins[ii]] net.propeller_motors.append(rotor_motor) # 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 # append motor origin spanwise locations onto wing data structure motor_origins_front = np.array(origins[:4]) motor_origins_rear = np.array(origins[5:]) vehicle.wings['canard_wing'].motor_spanwise_locations = motor_origins_front[:,1]/ vehicle.wings['canard_wing'].spans.projected vehicle.wings['canard_wing'].motor_spanwise_locations = motor_origins_front[:,1]/ vehicle.wings['canard_wing'].spans.projected vehicle.wings['main_wing'].motor_spanwise_locations = motor_origins_rear[:,1]/ vehicle.wings['main_wing'].spans.projected vehicle.append_component(net) vehicle.weight_breakdown = empty(vehicle) compute_component_centers_of_gravity(vehicle) vehicle.center_of_gravity() return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Solar' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 200. * Units.kg vehicle.mass_properties.operating_empty = 200. * Units.kg vehicle.mass_properties.max_takeoff = 200. * Units.kg # basic parameters vehicle.reference_area = 80. vehicle.envelope.ultimate_load = 2.0 vehicle.envelope.limit_load = 1.5 vehicle.envelope.maximum_dynamic_pressure = 0.5 * 1.225 * (40.**2.) #Max q # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = vehicle.reference_area wing.spans.projected = 40.0 * Units.meter wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.sweeps.quarter_chord = 0.0 * Units.deg wing.symmetric = True wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.vertical = False wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.span_efficiency = 0.98 wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.highlift = False wing.vertical = False wing.number_ribs = 26. wing.number_end_ribs = 2. wing.transition_x_upper = 0.6 wing.transition_x_lower = 1.0 wing.origin = [3.0, 0.0, 0.0] # meters wing.aerodynamic_center = [3.0, 0.0, 0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 20. wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.95 wing.areas.reference = vehicle.reference_area * .15 wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.vertical = False wing.symmetric = True wing.dynamic_pressure_ratio = 0.9 wing.number_ribs = 5.0 wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.origin = [10., 0.0, 0.0] # meters wing.aerodynamic_center = [0.5, 0.0, 0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' wing.aspect_ratio = 20. wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.97 wing.areas.reference = vehicle.reference_area * 0.1 wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [10., 0.0, 0.0] # meters wing.aerodynamic_center = [0.5, 0.0, 0.0] # meters wing.symmetric = True wing.vertical = True wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) #------------------------------------------------------------------ # Propulsor #------------------------------------------------------------------ # build network net = Solar() net.number_of_engines = 1. net.nacelle_diameter = 0.2 * Units.meters net.engine_length = 0.01 * Units.meters net.areas = Data() net.areas.wetted = 0.01 * (2 * np.pi * 0.01 / 2.) # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = vehicle.reference_area * 0.9 panel.efficiency = 0.25 panel.mass_properties.mass = panel.area * (0.60 * Units.kg) net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 2.0 prop_attributes.freestream_velocity = 40.0 * Units['m/s'] # freestream prop_attributes.angular_velocity = 150. * Units['rpm'] prop_attributes.tip_radius = 4.25 * Units.meters prop_attributes.hub_radius = 0.05 * Units.meters prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 14.0 * Units.km prop_attributes.design_thrust = 0.0 prop_attributes.design_power = 3500.0 * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.008 motor.no_load_current = 4.5 * Units.ampere motor.speed_constant = 120. * Units[ 'rpm'] # RPM/volt converted to (rad/s)/volt motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 12. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 160. # Expected current motor.mass_properties.mass = 2.0 * Units.kg net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 50. * Units.watts payload.mass_properties.mass = 5.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 50. * Units.watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.mass_properties.mass = 55.0 * Units.kg bat.specific_energy = 450. * Units.Wh / Units.kg bat.resistance = 0.05 initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 40.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # add the solar network to the vehicle vehicle.append_component(net) return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'X57_Maxwell' # ------------------------------------------------------------------ # 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.mass_properties.cargo = 0. # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 # basic parameters vehicle.reference_area = 15.45 vehicle.passengers = 4 # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.sweeps.quarter_chord = 0.0 * Units.deg wing.sweeps.leading_edge = 0.0 * Units.deg wing.thickness_to_chord = 0.12 wing.areas.reference = 15.45 * Units['meters**2'] wing.spans.projected = 11. * Units.meter wing.chords.root = 1.67 * Units.meter wing.chords.tip = 1.14 * Units.meter wing.chords.mean_aerodynamic = 1.47 * Units.meter 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 = 1.5 * Units.degrees wing.origin = [[2.032, 0., 0.784]] wing.aerodynamic_center = [0.558, 0., 0.784] wing.vertical = False wing.symmetric = True wing.high_lift = True 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.sweeps.quarter_chord = 0.0 * Units.deg wing.thickness_to_chord = 0.12 wing.areas.reference = 3.74 * Units['meters**2'] wing.spans.projected = 3.454 * Units.meter wing.sweeps.quarter_chord = 12.5 * Units.deg wing.chords.root = 1.397 * Units.meter wing.chords.tip = 0.762 * Units.meter wing.chords.mean_aerodynamic = 1.09 * Units.meter wing.taper = wing.chords.root / wing.chords.tip 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.248, 0., 0]] wing.aerodynamic_center = [0.508, 0., 0.] wing.vertical = False 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.root / wing.chords.tip 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.01, 0, 0.623]] wing.aerodynamic_center = [0.508, 0, 0] wing.vertical = True wing.symmetric = False wing.t_tail = False 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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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.Fuselages.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) #--------------------------------------------------------------------------------------------- # DEFINE PROPELLER #--------------------------------------------------------------------------------------------- # build network net = Battery_Propeller() net.number_of_engines = 2. net.nacelle_diameter = 42 * Units.inches net.engine_length = 0.01 * Units.inches net.areas = Data() net.areas.wetted = 0.01 * (2 * np.pi * 0.01 / 2) # 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 # Design the Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_of_blades = 2.0 prop.freestream_velocity = 135. * Units['mph'] prop.angular_velocity = 1300. * Units.rpm prop.tip_radius = 76. / 2. * Units.inches prop.hub_radius = 8. * Units.inches prop.design_Cl = 0.8 prop.design_altitude = 12000. * Units.feet prop.design_altitude = 12000. * Units.feet prop.design_thrust = 1200. prop.origin = [[2., 2.5, 0.784], [2., -2.5, 0.784]] prop.rotation = [-1, 1] prop.symmetry = 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) net.propeller = prop # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.mass_properties.mass = 500. * Units.kg bat.specific_energy = 350. * Units.Wh / Units.kg bat.resistance = 0.006 bat.max_voltage = 500. initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat net.voltage = bat.max_voltage # Component 9 Miscellaneous Systems sys = SUAVE.Components.Systems.System() sys.mass_properties.mass = 5 # kg #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller motor # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() etam = 0.95 v = bat.max_voltage * 3 / 4 omeg = prop.angular_velocity io = 4.0 start_kv = 1 end_kv = 25 # do optimization to find kv or just do a linspace then remove all negative values, take smallest one use 0.05 change # essentially you are sizing the motor for a particular rpm which is sized for a design tip mach # this reduces the bookkeeping errors possible_kv_vals = np.linspace( start_kv, end_kv, (end_kv - start_kv) * 20 + 1, endpoint=True) * Units.rpm res_kv_vals = ((v - omeg / possible_kv_vals) * (1. - etam * v * possible_kv_vals / omeg)) / io positive_res_vals = np.extract(res_kv_vals > 0, res_kv_vals) kv_idx = np.where(res_kv_vals == min(positive_res_vals))[0][0] kv = possible_kv_vals[kv_idx] res = min(positive_res_vals) motor.mass_properties.mass = 10. * Units.kg motor.origin = prop.origin motor.propeller_radius = prop.tip_radius motor.speed_constant = 0.35 motor.resistance = res motor.no_load_current = io motor.gear_ratio = 1. motor.gearbox_efficiency = 1. # Gear box efficiency net.motor = motor # 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
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Vahana' vehicle.configuration = 'eVTOL' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 2250. * Units.lb vehicle.mass_properties.operating_empty = 2250. * Units.lb vehicle.mass_properties.max_takeoff = 2250. * Units.lb vehicle.mass_properties.center_of_gravity = [2.0144, 0., 0.] vehicle.reference_area = 10.58275476 vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3. # ------------------------------------------------------ # WINGS # ------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'canard_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.span_efficiency = 0.9 wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [0.0, 0.0, 0.0] wing.aerodynamic_center = [0., 0., 0.] wing.winglet_fraction = 0.0 wing.symmetric = True # Segment segment = SUAVE.Components.Wings.Segment() segment.tag = 'Section_1' segment.origin = [0., 0., 0.] segment.percent_span_location = 0. segment.twist = 0. segment.root_chord_percent = 1. segment.dihedral_outboard = 0. segment.sweeps.quarter_chord = 0. segment.thickness_to_chord = 0.18 wing.Segments.append(segment) # Segment segment = SUAVE.Components.Wings.Segment() segment.tag = 'Section_2' segment.origin = [0., 0., 0.] segment.percent_span_location = 1. segment.twist = 0. segment.root_chord_percent = 1. segment.dihedral_outboard = 0. segment.sweeps.quarter_chord = 0. segment.thickness_to_chord = 0.18 wing.Segments.append(segment) # add to vehicle vehicle.append_component(wing) wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.span_efficiency = 0.9 wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [5.138, 0.0, 1.24] wing.aerodynamic_center = [0., 0., 0.] wing.winglet_fraction = 0.0 wing.symmetric = True # Segment segment = SUAVE.Components.Wings.Segment() segment.tag = 'Section_1' segment.origin = [0., 0., 0.] segment.percent_span_location = 0. segment.twist = 0. segment.root_chord_percent = 1. segment.dihedral_outboard = 0. segment.sweeps.quarter_chord = 0. segment.thickness_to_chord = 0.18 wing.Segments.append(segment) # Segment segment = SUAVE.Components.Wings.Segment() segment.tag = 'Section_2' segment.origin = [0., 0., 0.] segment.percent_span_location = 1. segment.twist = 0. segment.root_chord_percent = 1. segment.dihedral_outboard = 0. segment.sweeps.quarter_chord = 0. segment.thickness_to_chord = 0.18 wing.Segments.append(segment) # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------ # FUSELAGE # ------------------------------------------------------ # FUSELAGE PROPERTIES fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.origin = [0., 0., 0.] fuselage.seats_abreast = 0. fuselage.seat_pitch = 1. fuselage.fineness.nose = 1.5 fuselage.fineness.tail = 4.0 fuselage.lengths.nose = 1.7 fuselage.lengths.tail = 2.7 fuselage.lengths.cabin = 1.7 fuselage.lengths.total = 6.1 fuselage.width = 1.15 fuselage.heights.maximum = 1.7 fuselage.heights.at_quarter_length = 1.2 fuselage.heights.at_wing_root_quarter_chord = 1.7 fuselage.heights.at_three_quarters_length = 0.75 fuselage.areas.wetted = 12.97989862 fuselage.areas.front_projected = 1.365211404 fuselage.effective_diameter = 1.318423736 fuselage.differential_pressure = 0. # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_1' segment.origin = [0., 0., 0.] segment.percent_x_location = 0. segment.percent_z_location = 0. segment.height = 0. segment.width = 0. segment.length = 0. segment.effective_diameter = 0. fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_2' segment.origin = [0., 0., 0.] segment.percent_x_location = 0.275 segment.percent_z_location = -0.009 segment.height = 0.309 * 2 segment.width = 0.28 * 2 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_3' segment.origin = [0., 0., 0.] segment.percent_x_location = 0.768 segment.percent_z_location = 0.046 segment.height = 0.525 * 2 segment.width = 0.445 * 2 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_4' segment.origin = [0., 0., 0.] segment.percent_x_location = 0.25 * 6.2 segment.percent_z_location = 0.209 segment.height = 0.7 * 2 segment.width = 0.55 * 2 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_5' segment.origin = [0., 0., 0.] segment.percent_x_location = 0.5 * 6.2 segment.percent_z_location = 0.407 segment.height = 0.850 * 2 segment.width = 0.61 * 2 segment.effective_diameter = 0. fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_6' segment.origin = [0., 0., 0.] segment.percent_x_location = 0.75 segment.percent_z_location = 0.771 segment.height = 0.63 * 2 segment.width = 0.442 * 2 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_7' segment.origin = [0., 0., 0.] segment.percent_x_location = 1. * 6.2 segment.percent_z_location = 1.192 segment.height = 0.165 * 2 segment.width = 0.125 * 2 fuselage.Segments.append(segment) # add to vehicle vehicle.append_component(fuselage) #------------------------------------------------------------------ # PROPULSOR #------------------------------------------------------------------ net = Vectored_Thrust() net.number_of_engines = 8 net.thrust_angle = 90.0 * Units.degrees # conversion to radians, net.nacelle_diameter = 0.2921 # https://www.magicall.biz/products/integrated-motor-controller-magidrive/ net.engine_length = 0.106 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 #------------------------------------------------------------------ esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 net.esc = 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( ) bat.specific_energy = 300. * Units.Wh / Units.kg bat.resistance = 0.005 bat.max_voltage = net.voltage bat.mass_properties.mass = 350. * Units.kg initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat #------------------------------------------------------------------ # Design Rotors #------------------------------------------------------------------ # atmosphere conditions speed_of_sound = 340 rho = 1.22 fligth_CL = 0.75 AR = vehicle.wings.main_wing.aspect_ratio Cd0 = 0.06 Cdi = fligth_CL**2 / (np.pi * AR * 0.98) Cd = Cd0 + Cdi # Create propeller geometry rot = SUAVE.Components.Energy.Converters.Rotor() rot.y_pitch = 1.850 rot.tip_radius = 0.8875 rot.hub_radius = 0.1 rot.disc_area = np.pi * (rot.tip_radius**2) rot.design_tip_mach = 0.5 rot.number_blades = 3 rot.freestream_velocity = 85. * Units['ft/min'] # 110 mph rot.angular_velocity = rot.design_tip_mach * speed_of_sound / rot.tip_radius rot.design_Cl = 0.7 rot.design_altitude = 500 * Units.feet Lift = vehicle.mass_properties.takeoff * 9.81 rot.design_thrust = (Lift * 1.5) / net.number_of_engines rot.induced_hover_velocity = np.sqrt( Lift / (2 * rho * rot.disc_area * net.number_of_engines)) rot = propeller_design(rot) # Front Rotors Locations rot_front = Data() rot_front.origin = [[0.0, 1.347, 0.0]] rot_front.symmetric = True rot_front.x_pitch_count = 1 rot_front.y_pitch_count = 2 rot_front.y_pitch = 1.85 # populating rotors on one side of wing if rot_front.y_pitch_count > 1: for n in range(rot_front.y_pitch_count): if n == 0: continue for i in range(len(rot_front.origin)): propeller_origin = [ rot_front.origin[i][0], rot_front.origin[i][1] + n * rot_front.y_pitch, rot_front.origin[i][2] ] rot_front.origin.append(propeller_origin) # populating rotors on the other side of the vehicle if rot_front.symmetric: for n in range(len(rot_front.origin)): propeller_origin = [ rot_front.origin[n][0], -rot_front.origin[n][1], rot_front.origin[n][2] ] rot_front.origin.append(propeller_origin) # Rear Rotors Locations rot_rear = Data() rot_rear.origin = [[0.0, 1.347, 1.24]] rot_rear.symmetric = True rot_rear.x_pitch_count = 1 rot_rear.y_pitch_count = 2 rot_rear.y_pitch = 1.85 # populating rotors on one side of wing if rot_rear.y_pitch_count > 1: for n in range(rot_rear.y_pitch_count): if n == 0: continue for i in range(len(rot_rear.origin)): propeller_origin = [ rot_rear.origin[i][0], rot_rear.origin[i][1] + n * rot_rear.y_pitch, rot_rear.origin[i][2] ] rot_rear.origin.append(propeller_origin) # populating rotors on the other side of the vehicle if rot_rear.symmetric: for n in range(len(rot_rear.origin)): propeller_origin = [ rot_rear.origin[n][0], -rot_rear.origin[n][1], rot_rear.origin[n][2] ] rot_rear.origin.append(propeller_origin) # Assign all rotors (front and rear) to network rot.origin = rot_front.origin + rot_rear.origin # append rotors to vehicle net.rotor = rot # Motor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller (Thrust) motor motor = SUAVE.Components.Energy.Converters.Motor() motor.mass_properties.mass = 9. * Units.kg motor.origin = rot_front.origin + rot_rear.origin motor.efficiency = 0.935 motor.gear_ratio = 1. motor.gearbox_efficiency = 1. # Gear box efficiency motor.nominal_voltage = bat.max_voltage * 3 / 4 motor.propeller_radius = rot.tip_radius motor.no_load_current = 2.0 motor = compute_optimal_motor_parameters(motor, rot) net.motor = motor 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 # append motor origin spanwise locations onto wing data structure motor_origins_front = np.array(rot_front.origin) vehicle.wings['canard_wing'].motor_spanwise_locations = np.multiply( 0.19, motor_origins_front[:, 1]) motor_origins_rear = np.array(rot_rear.origin) vehicle.wings['main_wing'].motor_spanwise_locations = np.multiply( 0.19, motor_origins_rear[:, 1]) return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'multicopter' vehicle.configuration = 'eVTOL' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 2080. * Units.lb vehicle.mass_properties.operating_empty = 1666. * Units.lb vehicle.mass_properties.max_takeoff = 2080. * Units.lb vehicle.mass_properties.center_of_gravity = [[2.6, 0., 0.]] # This needs updating vehicle.passengers = 5 vehicle.reference_area = 73 * Units.feet**2 vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3. wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 1. wing.spans.projected = 0.1 wing.chords.root = 0.1 wing.chords.tip = 0.1 wing.origin = [[2.6, 0., 0.]] wing.symbolic = True 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 = 16.0 * Units.feet 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_1' segment.origin = [0., 0., 0.] segment.percent_x_location = 0. segment.percent_z_location = 0.0 segment.height = 0.1 * Units.feet segment.width = 0.1 * Units.feet segment.length = 0. segment.effective_diameter = 0.1 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_2' segment.origin = [4. * 0.3048, 0., 0.1 * 0.3048] segment.percent_x_location = 0.25 segment.percent_z_location = 0.05 segment.height = 3.75 * Units.feet segment.width = 5.65 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.65 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_3' segment.origin = [8. * 0.3048, 0., 0.34 * 0.3048] segment.percent_x_location = 0.5 segment.percent_z_location = 0.071 segment.height = 4.65 * Units.feet segment.width = 5.55 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.55 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_4' segment.origin = [12. * 0.3048, 0., 0.77 * 0.3048] segment.percent_x_location = 0.75 segment.percent_z_location = 0.089 segment.height = 4.73 * Units.feet segment.width = 4.26 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 4.26 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Lofted_Body_Segment.Segment() segment.tag = 'segment_5' segment.origin = [16. * 0.3048, 0., 2.02 * 0.3048] segment.percent_x_location = 1.0 segment.percent_z_location = 0.158 segment.height = 0.67 * Units.feet segment.width = 0.33 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 0.33 * Units.feet fuselage.append_segment(segment) # add to vehicle vehicle.append_component(fuselage) # ----------------------------------------------------------------- # Design the Nacelle # ----------------------------------------------------------------- nacelle = SUAVE.Components.Nacelles.Nacelle() nacelle.diameter = 0.6 * Units.feet # need to check nacelle.length = 0.5 * Units.feet nacelle.tag = 'nacelle_1' nacelle.areas.wetted = np.pi * nacelle.diameter * nacelle.length + 0.5 * np.pi * nacelle.diameter**2 nacelle.origin = [[0., 2., 1.4]] vehicle.append_component(nacelle) nacelle_2 = deepcopy(nacelle) nacelle_2.tag = 'nacelle_2' nacelle_2.origin = [[0.0, -2., 1.4]] vehicle.append_component(nacelle_2) nacelle_3 = deepcopy(nacelle) nacelle_3.tag = 'nacelle_3' nacelle_3.origin = [[2.5, 4., 1.4]] vehicle.append_component(nacelle_3) nacelle_4 = deepcopy(nacelle) nacelle_4.tag = 'nacelle_4' nacelle_4.origin = [[2.5, -4., 1.4]] vehicle.append_component(nacelle_4) nacelle_5 = deepcopy(nacelle) nacelle_5.tag = 'nacelle_5' nacelle_5.origin = [[5.0, 2., 1.4]] vehicle.append_component(nacelle_5) nacelle_6 = deepcopy(nacelle) nacelle_6.tag = 'nacelle_6' nacelle_6.origin = [[5.0, -2., 1.4]] vehicle.append_component(nacelle_6) #------------------------------------------------------------------ # Network #------------------------------------------------------------------ net = SUAVE.Components.Energy.Networks.Battery_Propeller() net.number_of_lift_rotor_engines = 6 net.nacelle_diameter = 0.6 * Units.feet # need to check 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. net.identical_lift_rotors = True #------------------------------------------------------------------ # Design Electronic Speed Controller #------------------------------------------------------------------ esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 net.esc = 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 = 300. * Units.kg bat.max_voltage = net.voltage initialize_from_mass(bat) net.battery = bat #------------------------------------------------------------------ # Design Rotors #------------------------------------------------------------------ # atmosphere and flight conditions for propeller/lift_rotor design g = 9.81 # gravitational acceleration speed_of_sound = 340 # speed of sound Hover_Load = vehicle.mass_properties.takeoff * g # hover load design_tip_mach = 0.7 # design tip mach number lift_rotor = SUAVE.Components.Energy.Converters.Lift_Rotor() lift_rotor.tip_radius = 3.95 * Units.feet lift_rotor.hub_radius = 0.6 * Units.feet lift_rotor.disc_area = np.pi * (lift_rotor.tip_radius**2) lift_rotor.number_of_blades = 3 lift_rotor.freestream_velocity = 10.0 lift_rotor.angular_velocity = (design_tip_mach * speed_of_sound) / lift_rotor.tip_radius lift_rotor.design_Cl = 0.7 lift_rotor.design_altitude = 1000 * Units.feet lift_rotor.design_thrust = Hover_Load / ( net.number_of_lift_rotor_engines - 1 ) # contingency for one-engine-inoperative condition 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 origins = [[0., 2., 1.4], [0.0, -2., 1.4], [2.5, 4., 1.4], [2.5, -4., 1.4], [5.0, 2., 1.4], [5.0, -2., 1.4]] for ii in range(6): lift_rotor = deepcopy(lift_rotor) lift_rotor.tag = 'lift_rotor' lift_rotor.origin = [origins[ii]] net.lift_rotors.append(lift_rotor) #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Motor lift_motor = SUAVE.Components.Energy.Converters.Motor() lift_motor.efficiency = 0.95 lift_motor.nominal_voltage = bat.max_voltage * 0.5 lift_motor.mass_properties.mass = 3. * Units.kg lift_motor.origin = lift_rotor.origin lift_motor.propeller_radius = lift_rotor.tip_radius lift_motor.no_load_current = 2.0 lift_motor = size_optimal_motor(lift_motor, lift_rotor) net.lift_motor = lift_motor # Define motor sizing parameters max_power = lift_rotor.design_power * 1.2 max_torque = lift_rotor.design_torque * 1.2 # test high temperature superconducting motor weight function mass = hts_motor(max_power) # test NDARC motor weight function mass = nasa_motor(max_torque) # test air cooled motor weight function mass = air_cooled_motor(max_power) lift_motor.mass_properties.mass = mass # Appending motors with different origins for ii in range(6): lift_rotor_motor = deepcopy(lift_motor) lift_rotor_motor.tag = 'motor' net.lift_rotor_motors.append(lift_rotor_motor) vehicle.append_component(net) vehicle.weight_breakdown = empty(vehicle) compute_component_centers_of_gravity(vehicle) vehicle.center_of_gravity() return vehicle
def main(): # ------------------------------------------------------------------ # Propulsor # ------------------------------------------------------------------ # build network net = Solar() net.number_of_engines = 1. net.nacelle_dia = 0.2 # Component 1 the Sun? sun = SUAVE.Components.Energy.Processes.Solar_Radiation() net.solar_flux = sun # Component 2 the solar panels panel = SUAVE.Components.Energy.Converters.Solar_Panel() panel.area = 100 * Units.m panel.efficiency = 0.18 panel.mass_properties.mass = panel.area * .600 net.solar_panel = panel # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 5 the Propeller # Propeller design specs design_altitude = 0.0 * Units.km Velocity = 10.0 # freestream m/s RPM = 5887 Blades = 2.0 Radius = .4064 Hub_Radius = 0.05 Design_Cl = 0.7 Thrust = 0.0 #Specify either thrust or power to design for Power = 7500. #Specify either thrust or power to design for # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = Blades prop_attributes.freestream_velocity = Velocity prop_attributes.angular_velocity = RPM * (2. * np.pi / 60.0) prop_attributes.tip_radius = Radius prop_attributes.hub_radius = Hub_Radius prop_attributes.design_Cl = Design_Cl prop_attributes.design_altitude = design_altitude prop_attributes.design_thrust = Thrust prop_attributes.design_power = Power prop_attributes = propeller_design(prop_attributes) # Create and attach this propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes net.propeller = prop # Component 4 the Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.01 motor.no_load_current = 8.0 motor.speed_constant = 140. * (2. * np.pi / 60. ) # RPM/volt converted to rad/s motor.propeller_radius = prop.prop_attributes.tip_radius motor.propeller_Cp = prop.prop_attributes.Cp motor.gear_ratio = 1. motor.gearbox_efficiency = 1. motor.expected_current = 260. motor.mass_properties.mass = 2.0 net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 0. #Watts payload.mass_properties.mass = 0. * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 0. #Watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) batterymass = 50. #kg bat.type = 'Li-Ion' bat.resistance = 0.0 bat.energy_density = 250. initialize_from_mass(bat, batterymass) bat.current_energy = bat.max_energy net.battery = bat #Component 9 the system logic controller and MPPT logic = SUAVE.Components.Energy.Distributors.Solar_Logic() logic.system_voltage = 50.0 logic.MPPT_efficiency = 0.95 net.solar_logic = logic # Setup the conditions to run the network state = Data() state.conditions = SUAVE.Analyses.Mission.Segments.Conditions.Aerodynamics( ) state.numerics = SUAVE.Analyses.Mission.Segments.Conditions.Numerics() conditions = state.conditions numerics = state.numerics # Calculate atmospheric properties atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values( prop_attributes.design_altitude) rho = atmosphere_conditions.density[0, :] a = atmosphere_conditions.speed_of_sound[0, :] mu = atmosphere_conditions.dynamic_viscosity[0, :] T = atmosphere_conditions.temperature[0, :] conditions.propulsion.throttle = np.array([[1.0], [1.0]]) conditions.freestream.velocity = np.array([[1.0], [1.0]]) conditions.freestream.density = np.array([rho, rho]) conditions.freestream.dynamic_viscosity = np.array([mu, mu]) conditions.freestream.speed_of_sound = np.array([a, a]) conditions.freestream.altitude = np.array([[design_altitude], [design_altitude]]) conditions.propulsion.battery_energy = bat.max_energy * np.ones_like( conditions.freestream.altitude) conditions.frames.body.inertial_rotations = np.zeros([2, 3]) conditions.frames.inertial.time = np.array([[0.0], [1.0]]) numerics.time.integrate = np.array([[0, 0], [0, 1]]) numerics.time.differentiate = np.array([[0, 0], [0, 1]]) conditions.frames.planet.start_time = time.strptime( "Sat, Jun 21 06:00:00 2014", "%a, %b %d %H:%M:%S %Y", ) conditions.frames.planet.latitude = np.array([[0.0], [0.0]]) conditions.frames.planet.longitude = np.array([[0.0], [0.0]]) conditions.freestream.temperature = np.array([T, T]) # Run the network and print the results results = net(state) F = results.thrust_force_vector # Truth results truth_F = [[522.40448791], [522.40448791]] truth_i = [[314.90485916], [314.90485916]] truth_rpm = [[6581.17653732], [6581.17653732]] truth_bat = [[36000000.], [35984254.75704217]] error = Data() error.Thrust = np.max(np.abs(F[:, 0] - truth_F)) error.RPM = np.max(np.abs(conditions.propulsion.rpm - truth_rpm)) error.Current = np.max(np.abs(conditions.propulsion.current - truth_i)) error.Battery = np.max(np.abs(bat.current_energy - truth_bat)) print error for k, v in error.items(): assert (np.abs(v) < 0.001) return
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Pteryxyz_Electric' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 450. * Units.kg vehicle.mass_properties.operating_empty = 450. * Units.kg vehicle.mass_properties.max_takeoff = 450. * Units.kg # basic parameters vehicle.reference_area = 6.2 vehicle.envelope.ultimate_load = 2.0 vehicle.envelope.limit_load = 1.5 max_q = 56. #m/s vehicle.envelope.maximum_dynamic_pressure = 0.5 * 1.225 * (max_q**2. ) #Max q # ------------------------------------------------------------------ # Landing Gear # ------------------------------------------------------------------ # used for noise calculations landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() landing_gear.tag = "main_landing_gear" landing_gear.main_tire_diameter = 0.423 * Units.m landing_gear.nose_tire_diameter = 0.3625 * Units.m landing_gear.main_strut_length = 0.4833 * Units.m landing_gear.nose_strut_length = 0.3625 * Units.m landing_gear.main_units = 2 # number of main landing gear units landing_gear.nose_units = 1 # number of nose landing gear landing_gear.main_wheels = 1 # number of wheels on the main landing gear landing_gear.nose_wheels = 1 # number of wheels on the nose landing gear vehicle.landing_gear = landing_gear # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = vehicle.reference_area wing.spans.projected = 7.04 * Units.meter wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.sweeps.quarter_chord = 0.0 * Units.deg wing.symmetric = True wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.vertical = False wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.span_efficiency = 0.98 wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.highlift = False wing.vertical = False wing.number_ribs = 26. wing.number_end_ribs = 2. wing.transition_x_upper = 0.6 wing.transition_x_lower = 1.0 wing.origin = [1.6, 0.0, 0.0] # meters wing.aerodynamic_center = [1.9, 0.0, 0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.spans.projected = 2.45 * Units.meter wing.areas.reference = 1.20 wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.95 wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.vertical = False wing.symmetric = True wing.dynamic_pressure_ratio = 0.9 wing.number_ribs = 5.0 wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.origin = [4.2, 0.0, 0.0] # meters wing.aerodynamic_center = [0.5, 0.0, 0.0] # meters # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' wing.spans.projected = 4.60 * Units.meter wing.areas.reference = 0.5 wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.sweeps.quarter_chord = 0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.97 wing.areas.reference = vehicle.reference_area * 0.1 wing.spans.projected = np.sqrt(wing.aspect_ratio * wing.areas.reference) wing.chords.root = wing.areas.reference / wing.spans.projected wing.chords.tip = wing.areas.reference / wing.spans.projected wing.chords.mean_aerodynamic = wing.areas.reference / wing.spans.projected wing.areas.wetted = 2.0 * wing.areas.reference wing.areas.exposed = 0.8 * wing.areas.wetted wing.areas.affected = 0.6 * wing.areas.wetted wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [3.7, 0.0, 0.0] # meters wing.aerodynamic_center = [0.5, 0.0, 0.0] # meters wing.symmetric = True wing.vertical = True wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 wing.number_ribs = 5. # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' # fuselage.aerodynamic_center= [2.986,0,1.077] fuselage.number_coach_seats = vehicle.passengers fuselage.seats_abreast = 2 fuselage.seat_pitch = 0.995 * Units.meter fuselage.fineness.nose = 1.27 fuselage.fineness.tail = 1 # 3.31 fuselage.lengths.nose = 1.16 * Units.meter fuselage.lengths.tail = 4.637 * Units.meter fuselage.lengths.cabin = 2.653 * Units.meter fuselage.lengths.total = 8.45 * Units.meter fuselage.lengths.fore_space = 0.0 * Units.meter fuselage.lengths.aft_space = 0.0 * Units.meter fuselage.width = 1.22 * Units.meter fuselage.heights.maximum = 1.41 * Units.meter fuselage.effective_diameter = 2 * Units.meter fuselage.areas.side_projected = 7.46 * Units['meters**2'] fuselage.areas.wetted = 25.0 * Units['meters**2'] fuselage.areas.front_projected = 1.54 * Units['meters**2'] fuselage.differential_pressure = 0.0 * Units.pascal # Maximum differential pressure fuselage.heights.at_quarter_length = 1.077 * Units.meter fuselage.heights.at_three_quarters_length = 0.5 * Units.meter # 0.621 * Units.meter fuselage.heights.at_wing_root_quarter_chord = 1.41 * Units.meter # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Propellers Powered By Batteries # ------------------------------------------------------------------ # build network net = Battery_Propeller() net.number_of_engines = 1 net.nacelle_diameter = 0.58 * Units.meters net.engine_length = 1.74 * Units.meters net.thrust_angle = 0.0 * Units.degrees net.voltage = 709.0 * Units.V net.areas = Data() net.areas.wetted = 1.1 * np.pi * net.nacelle_diameter * net.engine_length max_power = 175 * Units.kW # Component 3 the ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc = esc # Component 4 - Propeller # Design the Propeller # Component 5 the Propeller front # Design the Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_blades = 2.0 prop.freestream_velocity = 56.0 * Units['m/s'] # freestream prop.angular_velocity = 10000. * Units['rpm'] prop.tip_radius = 1.40 * Units.meters prop.hub_radius = 0.05 * Units.meters prop.design_Cl = 0.7 prop.design_altitude = 5.0 * Units.km prop.design_thrust = None prop.design_power = 150000.0 * Units.watts prop = propeller_design(prop) net.propeller = prop # Component 4 the Motor front motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.01 motor.no_load_current = 125. * Units.ampere motor.speed_constant = 4.5 * Units[ 'rpm/volt'] # RPM/volt converted to (rad/s)/volt motor.propeller_radius = prop.tip_radius motor.propeller_Cp = prop.power_coefficient motor.gear_ratio = 1. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 212. # Expected current motor.mass_properties.mass = 50.0 * Units.kg net.motor = motor # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 50. * Units.watts payload.mass_properties.mass = 5.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 50. * Units.watts net.avionics = avionics # Component 8 the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.cell_energy = 9.36 #[Wh] bat.cell_capacity = 2600 #[mAh] bat.max_const_discharge = 35 #[A] bat.v_max = 4.2 #[V] bat.v_nom = 3.7 #[V] bat.v_min = 2.5 #[V] bat.cell_mass = 44.3 #[g] bat.cell_current = 2.5 #[A] bat.voltage = 709 #[V] bat.power = 150 #[kW] bat.boost_power = 175 #[kW] bat.no_of_packs = 2 bat.current = bat.voltage * bat.power bat.boost_current = bat.voltage * bat.boost_power bat.current_per_pack = bat.current / bat.no_of_packs bat.parallel_cells_per_pack = 4 bat.additional_cell = 1 bat.series_cells = bat.voltage / bat.v_max bat.parallel_cells = bat.parallel_cells_per_pack * bat.additional_cell bat.cells_per_pack = bat.series_cells * bat.parallel_cells bat.cell_mass_ratio = 1.2 bat.mass_properties.mass = bat.cell_mass_ratio * bat.cells_per_pack * bat.cell_mass / 1000 * Units.kg bat.pack_energy = bat.cells_per_pack * bat.cell_energy / 1000 bat.total_energy = bat.pack_energy * bat.no_of_packs bat.specific_energy = 450. * Units.Wh / Units.kg bat.resistance = 0.05 initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ # add the energy network to the vehicle vehicle.append_component(net) # print vehicle return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Tecnam_P2006TElectric' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.max_takeoff = 1400 * Units.kilogram vehicle.mass_properties.takeoff = 1400 * Units.kilogram vehicle.mass_properties.operating_empty = 1000 * Units.kilogram vehicle.mass_properties.max_zero_fuel = 1400 * Units.kilogram vehicle.mass_properties.cargo = 80 * Units.kilogram # envelope properties vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3.8 # basic parameters vehicle.reference_area = 64.4 * Units['meters**2'] vehicle.passengers = 4 vehicle.systems.control = "fully powered" vehicle.systems.accessories = "medium range" # ------------------------------------------------------------------ # Landing Gear # ------------------------------------------------------------------ # used for noise calculations landing_gear = SUAVE.Components.Landing_Gear.Landing_Gear() landing_gear.tag = "main_landing_gear" landing_gear.main_tire_diameter = 0.423 * Units.m landing_gear.nose_tire_diameter = 0.3625 * Units.m landing_gear.main_strut_length = 0.4833 * Units.m landing_gear.nose_strut_length = 0.3625 * Units.m landing_gear.main_units = 2 #number of main landing gear units landing_gear.nose_units = 1 #number of nose landing gear landing_gear.main_wheels = 1 #number of wheels on the main landing gear landing_gear.nose_wheels = 1 #number of wheels on the nose landing gear vehicle.landing_gear = landing_gear # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.number_coach_seats = vehicle.passengers fuselage.seats_abreast = 2 fuselage.seat_pitch = 0.995 * Units.meter fuselage.fineness.nose = 1.27 fuselage.fineness.tail = 1 #3.31 fuselage.lengths.nose = 1.16 * Units.meter fuselage.lengths.tail = 4.637 * Units.meter fuselage.lengths.cabin = 2.653 * Units.meter fuselage.lengths.total = 8.45 * Units.meter fuselage.lengths.fore_space = 0.0 * Units.meter fuselage.lengths.aft_space = 0.0 * Units.meter fuselage.width = 1.22 * Units.meter fuselage.heights.maximum = 1.41 * Units.meter fuselage.effective_diameter = 2 * Units.meter fuselage.areas.side_projected = 7.46 * Units['meters**2'] fuselage.areas.wetted = 25.0 * Units['meters**2'] fuselage.areas.front_projected = 1.54 * Units['meters**2'] fuselage.differential_pressure = 0.0 * Units.pascal # Maximum differential pressure fuselage.heights.at_quarter_length = 1.077 * Units.meter fuselage.heights.at_three_quarters_length = 0.5 * Units.meter #0.621 * Units.meter fuselage.heights.at_wing_root_quarter_chord = 1.41 * Units.meter # add to vehicle vehicle.append_component(fuselage) # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.thickness_to_chord = 0.2 wing.taper = 0.9 wing.spans.projected = 13.8 * Units.meter wing.chords.root = 5.2 * Units.meter wing.chords.tip = wing.chords.root * wing.taper wing.chords.mean_aerodynamic = 0.6 * Units.meter wing.areas.reference = (wing.chords.root + wing.chords.tip) * wing.spans.projected / 2 wing.twists.root = 0. * Units.degrees wing.twists.tip = 0. * Units.degrees wing.dihedral = 1. * Units.degrees wing.origin = [2.986, 0, 1.077] # meters wing.sweeps.leading_edge = 1.9 * Units.deg wing.aspect_ratio = (wing.spans.projected * wing.spans.projected) / wing.areas.reference wing.span_efficiency = 0.99 * ( 1 - 0.0407 * (fuselage.width / wing.spans.projected) - 1.792 * ((fuselage.width / wing.spans.projected)**2)) wing.vertical = False wing.symmetric = True wing.high_lift = True wing.dynamic_pressure_ratio = 1.0 ## Wing Segments # Root Segment #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 = 1. * Units.degrees #segment.sweeps.quarter_chord = 0. * Units.degrees #segment.thickness_to_chord = 0.15 #airfoil = SUAVE.Components.Wings.Airfoils.Airfoil() #airfoil.coordinate_file = '/Users/Bruno/Documents/Delft/Courses/2016-2017/Thesis/Code/Airfoils/naca642415.dat' #segment.append_airfoil(airfoil) #wing.Segments.append(segment) # Tip Segment #segment = SUAVE.Components.Wings.Segment() #segment.tag = 'tip' #segment.percent_span_location = 1.0 #segment.twist = 0. * Units.deg #segment.root_chord_percent = 1. #segment.dihedral_outboard = 1. * Units.degrees #segment.sweeps.quarter_chord = 0. * Units.degrees #segment.thickness_to_chord = 0.15 #airfoil = SUAVE.Components.Wings.Airfoils.Airfoil() #airfoil.coordinate_file = '/Users/Bruno/Documents/Delft/Courses/2016-2017/Thesis/Code/Airfoils/naca642415.dat' #segment.append_airfoil(airfoil) #wing.Segments.append(segment) # ------------------------------------------------------------------ # Flaps # ------------------------------------------------------------------ wing.flaps.chord = 0.20 wing.flaps.span_start = 0.1053 wing.flaps.span_end = 0.6842 wing.flaps.type = 'single_slotted' # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.aspect_ratio = 4.193 wing.sweeps.quarter_chord = 0.0 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = 0.733 wing.spans.projected = 3.3 * Units.meter wing.chords.root = 0.787 * Units.meter wing.chords.tip = 0.787 * Units.meter wing.chords.mean_aerodynamic = (wing.chords.root * (2.0 / 3.0) * ((1.0 + wing.taper + wing.taper**2.0) / (1.0 + wing.taper))) * Units.meter wing.areas.reference = 2.5971 * Units['meters**2'] wing.areas.exposed = 4.0 * Units['meters**2'] wing.areas.wetted = 4.0 * Units['meters**2'] wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [7.789, 0.0, 0.3314] # meters wing.vertical = False wing.symmetric = True 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.aspect_ratio = 1.407 wing.sweeps.quarter_chord = 38.75 * Units.deg wing.thickness_to_chord = 0.12 wing.taper = 1.0 wing.span_efficiency = -0.107 wing.spans.projected = 1.574 * Units.meter wing.chords.root = 1.2 * Units.meter wing.chords.tip = 0.497 * Units.meter wing.chords.mean_aerodynamic = (wing.chords.root * (2.0 / 3.0) * ((1.0 + wing.taper + wing.taper**2.0) / (1.0 + wing.taper))) * Units.meter wing.areas.reference = 1.761 * Units['meters**2'] wing.twists.root = 0.0 * Units.degrees wing.twists.tip = 0.0 * Units.degrees wing.origin = [7.25, 0, 0.497] # meters wing.vertical = True wing.symmetric = False wing.t_tail = False wing.dynamic_pressure_ratio = 1.0 # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------------------ # Propellers Powered By Batteries # ------------------------------------------------------------------ # build network net = SUAVE.Components.Energy.Networks.Lift_Forward_Propulsor_Network() net.nacelle_diameter_lift = 0.08 * Units.meters net.nacelle_diameter_forward = 0.1732 * Units.meters net.engine_length_lift = 0.47244 * Units.meters net.engine_length_forward = 1.2 * Units.meters net.number_of_engines_lift = 12 net.number_of_engines_forward = 2 net.thrust_angle_lift = 0.0 * Units.degrees net.thrust_angle_forward = 0.0 * Units.degrees net.voltage = 461. net.areas_forward = Data() net.areas_forward.wetted = 1.1 * np.pi * net.nacelle_diameter_forward * net.engine_length_forward net.areas_lift = Data() net.areas_lift.wetted = 1.1 * np.pi * net.nacelle_diameter_forward * net.engine_length_lift # Component 1 - Tip ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc_forward = esc # Component 1 - High Lift ESC esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 # Gundlach for brushless motors net.esc_lift = esc # Component 2 - Tip Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 3.0 prop_attributes.freestream_velocity = 50.0 * Units['m/s'] # freestream m/s prop_attributes.angular_velocity = 27500. * Units['rpm'] # For 20x10 prop prop_attributes.tip_radius = 0.762 * Units.meter prop_attributes.hub_radius = 0.085 * Units.meter prop_attributes.design_Cl = 0.8 prop_attributes.design_altitude = 14.0 * Units.km prop_attributes.design_thrust = 0.0 * Units.newton prop_attributes.design_power = 250000. * Units.watts prop_attributes = propeller_design(prop_attributes) prop_forward = SUAVE.Components.Energy.Converters.Propeller() prop_forward.prop_attributes = prop_attributes net.propeller_forward = prop_forward # Component 2 - High Lift Propeller # Design the Propeller prop_attributes = Data() prop_attributes.number_blades = 5.0 prop_attributes.freestream_velocity = 1. * Units['m/s'] # freestream m/s prop_attributes.angular_velocity = 2750 * Units['rpm'] # For 20x10 prop prop_attributes.tip_radius = 0.2880360 * Units.meter prop_attributes.hub_radius = 0.07772400 * Units.meter prop_attributes.design_Cl = 0.8 prop_attributes.design_altitude = 0.0 * Units.meter prop_attributes.design_thrust = 0.0 * Units.newton prop_attributes.design_power = 10000. * Units.watts prop_attributes = propeller_design(prop_attributes) prop_lift = SUAVE.Components.Energy.Converters.Propeller() prop_lift.prop_attributes = prop_attributes net.propeller_lift = prop_lift # Component 3 - Tip Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 1. motor.no_load_current = 7. * Units.ampere motor.speed_constant = 11.9999 * Units[ 'rpm/volt'] # RPM/volt converted to (rad/s)/volt motor.propeller_radius = prop_forward.prop_attributes.tip_radius motor.propeller_Cp = prop_forward.prop_attributes.Cp[0] motor.gear_ratio = 12. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 160. # Expected current motor.mass_properties.mass = 9.0 * Units.kg net.motor_forward = motor # Component 3 - High Lift Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.resistance = 0.008 motor.no_load_current = 4.5 * Units.ampere motor.speed_constant = 5800. * Units[ 'rpm/volt'] # RPM/volt converted to (rad/s)/volt motor.propeller_radius = prop_lift.prop_attributes.tip_radius motor.propeller_Cp = prop_lift.prop_attributes.Cp[0] motor.gear_ratio = 12. # Gear ratio motor.gearbox_efficiency = .98 # Gear box efficiency motor.expected_current = 25. # Expected current motor.mass_properties.mass = 6.0 * Units.kg net.motor_lift = motor # Component 4 - the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 50. * Units.watts payload.mass_properties.mass = 5.0 * Units.kg net.payload = payload # Component 5 - the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 50. * Units.watts net.avionics = avionics # Component 6 - the Battery bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.mass_properties.mass = 358.33 * Units.kg bat.specific_energy = 192.84 * Units.Wh / Units.kg bat.specific_power = 0.837 * Units.kW / Units.kg bat.resistance = 0.0153 bat.max_voltage = 10000. initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat # ------------------------------------------------------------------ # Vehicle Definition Complete # ------------------------------------------------------------------ # add the energy network to the vehicle vehicle.append_component(net) #print vehicle return vehicle
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'Tiltwing' vehicle.configuration = 'eVTOL' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 2250. * Units.lb vehicle.mass_properties.operating_empty = 2250. * Units.lb vehicle.mass_properties.max_takeoff = 2250. * Units.lb vehicle.mass_properties.center_of_gravity = [[2.0144, 0., 0.]] vehicle.passengers = 1 vehicle.reference_area = 10.58275476 vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3. # ------------------------------------------------------ # WINGS # ------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'canard_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [[0.1, 0.0, 0.0]] wing.aerodynamic_center = [0., 0., 0.] wing.winglet_fraction = 0.0 wing.symmetric = True # add to vehicle vehicle.append_component(wing) wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 11.37706641 wing.sweeps.quarter_chord = 0.0 wing.thickness_to_chord = 0.18 wing.taper = 1. wing.spans.projected = 6.65 wing.chords.root = 0.95 wing.total_length = 0.95 wing.chords.tip = 0.95 wing.chords.mean_aerodynamic = 0.95 wing.dihedral = 0.0 wing.areas.reference = 6.31 wing.areas.wetted = 12.635 wing.areas.exposed = 12.635 wing.twists.root = 0. wing.twists.tip = 0. wing.origin = [[5.138, 0.0, 1.323]] # for images 1.54 wing.aerodynamic_center = [0., 0., 0.] wing.winglet_fraction = 0.0 wing.symmetric = True # add to vehicle vehicle.append_component(wing) # ------------------------------------------------------ # FUSELAGE # ------------------------------------------------------ # FUSELAGE PROPERTIES fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.seats_abreast = 0. fuselage.seat_pitch = 1. fuselage.fineness.nose = 1.5 fuselage.fineness.tail = 4.0 fuselage.lengths.nose = 1.7 fuselage.lengths.tail = 2.7 fuselage.lengths.cabin = 1.7 fuselage.lengths.total = 6.1 fuselage.width = 1.15 fuselage.heights.maximum = 1.7 fuselage.heights.at_quarter_length = 1.2 fuselage.heights.at_wing_root_quarter_chord = 1.7 fuselage.heights.at_three_quarters_length = 0.75 fuselage.areas.wetted = 12.97989862 fuselage.areas.front_projected = 1.365211404 fuselage.effective_diameter = 1.318423736 fuselage.differential_pressure = 0. # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_0' segment.percent_x_location = 0. segment.percent_z_location = 0. segment.height = 0.09 segment.width = 0.23473 segment.length = 0. segment.effective_diameter = 0. fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_1' segment.percent_x_location = 0.97675 / 6.1 segment.percent_z_location = 0.21977 / 6.1 segment.height = 0.9027 segment.width = 1.01709 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_2' segment.percent_x_location = 1.93556 / 6.1 segment.percent_z_location = 0.39371 / 6.1 segment.height = 1.30558 segment.width = 1.38871 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_3' segment.percent_x_location = 3.44137 / 6.1 segment.percent_z_location = 0.57143 / 6.1 segment.height = 1.52588 segment.width = 1.47074 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_4' segment.percent_x_location = 4.61031 / 6.1 segment.percent_z_location = 0.81577 / 6.1 segment.height = 1.14788 segment.width = 1.11463 fuselage.Segments.append(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_5' segment.percent_x_location = 1. segment.percent_z_location = 1.19622 / 6.1 segment.height = 0.31818 segment.width = 0.23443 fuselage.Segments.append(segment) # add to vehicle vehicle.append_component(fuselage) #------------------------------------------------------------------ # PROPULSOR #------------------------------------------------------------------ net = Vectored_Thrust() net.number_of_engines = 8 net.thrust_angle = 0.0 * Units.degrees # conversion to radians, net.nacelle_diameter = 0.2921 # https://www.magicall.biz/products/integrated-motor-controller-magidrive/ net.engine_length = 0.95 net.areas = Data() net.areas.wetted = np.pi * net.nacelle_diameter * net.engine_length + 0.5 * np.pi * net.nacelle_diameter**2 net.voltage = 400. #------------------------------------------------------------------ # Design Electronic Speed Controller #------------------------------------------------------------------ esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 net.esc = esc # Component 6 the Payload payload = SUAVE.Components.Energy.Peripherals.Payload() payload.power_draw = 10. #Watts payload.mass_properties.mass = 0.0 * Units.kg net.payload = payload # Component 7 the Avionics avionics = SUAVE.Components.Energy.Peripherals.Avionics() avionics.power_draw = 20. #Watts net.avionics = avionics #------------------------------------------------------------------ # Design Battery #------------------------------------------------------------------ bat = SUAVE.Components.Energy.Storages.Batteries.Constant_Mass.Lithium_Ion( ) bat.mass_properties.mass = 200. * Units.kg bat.specific_energy = 200. * Units.Wh / Units.kg bat.resistance = 0.006 bat.max_voltage = 400. initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat net.voltage = bat.max_voltage # Component 9 Miscellaneous Systems sys = SUAVE.Components.Systems.System() sys.mass_properties.mass = 5 # kg #------------------------------------------------------------------ # Design Rotors #------------------------------------------------------------------ # atmosphere conditions speed_of_sound = 340 rho = 1.22 fligth_CL = 0.75 AR = vehicle.wings.main_wing.aspect_ratio Cd0 = 0.06 Cdi = fligth_CL**2 / (np.pi * AR * 0.98) Cd = Cd0 + Cdi # Create propeller geometry rot = SUAVE.Components.Energy.Converters.Rotor() rot.y_pitch = 1.850 rot.tip_radius = 0.8875 rot.hub_radius = 0.15 rot.disc_area = np.pi * (rot.tip_radius**2) rot.design_tip_mach = 0.5 rot.number_of_blades = 3 rot.freestream_velocity = 10 rot.angular_velocity = rot.design_tip_mach * speed_of_sound / rot.tip_radius rot.design_Cl = 0.7 rot.design_altitude = 500 * Units.feet Lift = vehicle.mass_properties.takeoff * 9.81 rot.design_thrust = (Lift * 1.5) / net.number_of_engines rot.induced_hover_velocity = np.sqrt( Lift / (2 * rho * rot.disc_area * net.number_of_engines)) rot.airfoil_geometry = ['../Vehicles/Airfoils/NACA_4412.txt'] rot.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' ]] rot.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] rot = propeller_design(rot) rot.rotation = [1, 1, 1, 1, 1, 1, 1, 1] # Front Rotors Locations rot_front = Data() rot_front.origin = [[-0.2, 1.347, 0.]] rot_front.symmetric = True rot_front.x_pitch_count = 1 rot_front.y_pitch_count = 2 rot_front.y_pitch = 1.95 # populating rotors on one side of wing if rot_front.y_pitch_count > 1: for n in range(rot_front.y_pitch_count): if n == 0: continue for i in range(len(rot_front.origin)): propeller_origin = [ rot_front.origin[i][0], rot_front.origin[i][1] + n * rot_front.y_pitch, rot_front.origin[i][2] ] rot_front.origin.append(propeller_origin) # populating rotors on the other side of the vehicle if rot_front.symmetric: for n in range(len(rot_front.origin)): propeller_origin = [ rot_front.origin[n][0], -rot_front.origin[n][1], rot_front.origin[n][2] ] rot_front.origin.append(propeller_origin) # Rear Rotors Locations rot_rear = Data() rot_rear.origin = [[5.138 - 0.2, 1.347, 1.54]] rot_rear.symmetric = True rot_rear.x_pitch_count = 1 rot_rear.y_pitch_count = 2 rot_rear.y_pitch = 1.95 # populating rotors on one side of wing if rot_rear.y_pitch_count > 1: for n in range(rot_rear.y_pitch_count): if n == 0: continue for i in range(len(rot_rear.origin)): propeller_origin = [ rot_rear.origin[i][0], rot_rear.origin[i][1] + n * rot_rear.y_pitch, rot_rear.origin[i][2] ] rot_rear.origin.append(propeller_origin) # populating rotors on the other side of the vehicle if rot_rear.symmetric: for n in range(len(rot_rear.origin)): propeller_origin = [ rot_rear.origin[n][0], -rot_rear.origin[n][1], rot_rear.origin[n][2] ] rot_rear.origin.append(propeller_origin) # Assign all rotors (front and rear) to network rot.origin = rot_front.origin + rot_rear.origin # append rotors to vehicle net.rotor = rot # Motor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller (Thrust) motor motor = SUAVE.Components.Energy.Converters.Motor() motor.origin = rot_front.origin + rot_rear.origin motor.efficiency = 0.935 motor.gear_ratio = 1. motor.gearbox_efficiency = 1. # Gear box efficiency motor.nominal_voltage = bat.max_voltage * 3 / 4 motor.propeller_radius = rot.tip_radius motor.no_load_current = 2.0 motor = size_optimal_motor(motor, rot) motor.mass_properties.mass = nasa_motor(motor.design_torque) net.motor = motor 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 # append motor origin spanwise locations onto wing data structure motor_origins_front = np.array(rot_front.origin) motor_origins_rear = np.array(rot_rear.origin) vehicle.wings[ 'canard_wing'].motor_spanwise_locations = motor_origins_front[:, 1] / vehicle.wings[ 'canard_wing'].spans.projected vehicle.wings[ 'canard_wing'].motor_spanwise_locations = motor_origins_front[:, 1] / vehicle.wings[ 'canard_wing'].spans.projected vehicle.wings[ 'main_wing'].motor_spanwise_locations = motor_origins_rear[:, 1] / vehicle.wings[ 'main_wing'].spans.projected net.origin = rot.origin vehicle.weight_breakdown = empty(vehicle) compute_component_centers_of_gravity(vehicle) vehicle.center_of_gravity() return vehicle
def main(): # This script could fail if either the design or analysis scripts fail, # in case of failure check both. The design and analysis powers will # differ because of karman-tsien compressibility corrections in the # analysis scripts net = Battery_Propeller() net.number_of_engines = 2 # Design Gearbox gearbox = SUAVE.Components.Energy.Converters.Gearbox() gearbox.gearwheel_radius1 = 1 gearbox.gearwheel_radius2 = 1 gearbox.efficiency = 0.95 gearbox.inputs.torque = 800 # N-m gearbox.inputs.speed = 209.43951023931953 gearbox.inputs.power = 7000 gearbox.compute() # Design the Propeller with airfoil geometry defined prop_a = SUAVE.Components.Energy.Converters.Propeller() prop_a.number_blades = 2.0 prop_a.freestream_velocity = 50.0 prop_a.angular_velocity = gearbox.inputs.speed # 209.43951023931953 prop_a.tip_radius = 1.5 prop_a.hub_radius = 0.05 prop_a.design_Cl = 0.7 prop_a.design_altitude = 0.0 * Units.km prop_a.airfoil_geometry = ['NACA_4412_geo.txt'] prop_a.airfoil_polars = ['NACA_4412_polar.txt'] prop_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] prop_a.design_power = gearbox.outputs.power # 7000 prop_a = propeller_design(prop_a) # Design the Propeller with airfoil geometry defined prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_blades = 2.0 prop.freestream_velocity = 50.0 prop.angular_velocity = gearbox.inputs.speed # 209.43951023931953 prop.tip_radius = 1.5 prop.hub_radius = 0.05 prop.design_Cl = 0.7 prop.design_altitude = 0.0 * Units.km prop.design_power = gearbox.outputs.power # 7000 prop = propeller_design(prop) # Design a Rotor with airfoil geometry defined rot_a = SUAVE.Components.Energy.Converters.Rotor() rot_a.number_blades = 2.0 rot_a.freestream_velocity = 1 * Units.ft / Units.second rot_a.angular_velocity = 2000. * (2. * np.pi / 60.0) rot_a.tip_radius = 1.5 rot_a.hub_radius = 0.05 rot_a.design_Cl = 0.7 rot_a.design_altitude = 0.0 * Units.km rot_a.design_thrust = 1000.0 rot_a.airfoil_geometry = ['NACA_4412_geo.txt'] rot_a.airfoil_polars = ['NACA_4412_polar.txt'] rot_a.airfoil_polar_stations = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] rot_a.induced_hover_velocity = 13.5 #roughly equivalent to a Chinook at SL rot_a = propeller_design(rot_a) # Design a Rotor without airfoil geometry defined rot = SUAVE.Components.Energy.Converters.Rotor() rot.number_blades = 2.0 rot.freestream_velocity = 1 * Units.ft / Units.second rot.angular_velocity = 2000. * (2. * np.pi / 60.0) rot.tip_radius = 1.5 rot.hub_radius = 0.05 rot.design_Cl = 0.7 rot.design_altitude = 0.0 * Units.km rot.design_thrust = 1000.0 rot.induced_hover_velocity = 13.5 #roughly equivalent to a Chinook at SL rot = propeller_design(rot) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(prop.design_altitude) V = prop.freestream_velocity Vr = rot.freestream_velocity conditions = Data() conditions.freestream = Data() conditions.propulsion = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions.propulsion.throttle = np.array([[1.0]]) conditions.frames.body.transform_to_inertial = np.array([np.eye(3)]) conditions_r = copy.deepcopy(conditions) conditions.frames.inertial.velocity_vector = np.array([[V, 0, 0]]) conditions_r.frames.inertial.velocity_vector = np.array([[0, Vr, 0]]) # Create and attach this propeller prop_a.inputs.omega = np.array(prop.angular_velocity, ndmin=2) prop.inputs.omega = np.array(prop.angular_velocity, ndmin=2) rot_a.inputs.omega = copy.copy(prop.inputs.omega) rot.inputs.omega = copy.copy(prop.inputs.omega) # propeller with airfoil results F_a, Q_a, P_a, Cplast_a, output_a, etap_a = prop_a.spin(conditions) # propeller without airfoil results conditions.propulsion.pitch_command = np.array([[1.0]]) * Units.degree F, Q, P, Cplast, output, etap = prop.spin_variable_pitch(conditions) # rotor with airfoil results Fr_a, Qr_a, Pr_a, Cplastr_a, outputr_a, etapr = rot_a.spin(conditions_r) # rotor with out airfoil results conditions_r.propulsion.pitch_command = np.array([[1.0]]) * Units.degree Fr, Qr, Pr, Cplastr, outputr, etapr = rot.spin_variable_pitch(conditions_r) # Truth values for propeller with airfoil geometry defined F_a_truth = 97.95830293 Q_a_truth = 28.28338146 P_a_truth = 5923.6575610 Cplast_a_truth = 0.00053729 # Truth values for propeller without airfoil geometry defined F_truth = 179.27020984 Q_truth = 48.06170453 P_truth = 10066.0198578 Cplast_truth = 0.00091302 # Truth values for rotor with airfoil geometry defined Fr_a_truth = 893.16859917 Qr_a_truth = 77.57705597 Pr_a_truth = 16247.70060823 Cplastr_a_truth = 0.00147371 # Truth values for rotor without airfoil geometry defined Fr_truth = 900.63698565 Qr_truth = 78.01972629 Pr_truth = 16340.41326374 Cplastr_truth = 0.00148212 # Store errors error = Data() error.Thrust_a = np.max(np.abs(F_a - F_a_truth)) error.Torque_a = np.max(np.abs(Q_a - Q_a_truth)) error.Power_a = np.max(np.abs(P_a - P_a_truth)) error.Cp_a = np.max(np.abs(Cplast_a - Cplast_a_truth)) error.Thrust = np.max(np.abs(F - F_truth)) error.Torque = np.max(np.abs(Q - Q_truth)) error.Power = np.max(np.abs(P - P_truth)) error.Cp = np.max(np.abs(Cplast - Cplast_truth)) error.Thrustr_a = np.max(np.abs(Fr_a - Fr_a_truth)) error.Torquer_a = np.max(np.abs(Qr_a - Qr_a_truth)) error.Powerr_a = np.max(np.abs(Pr_a - Pr_a_truth)) error.Cpr_a = np.max(np.abs(Cplastr_a - Cplastr_a_truth)) error.Thrustr = np.max(np.abs(Fr - Fr_truth)) error.Torquer = np.max(np.abs(Qr - Qr_truth)) error.Powerr = np.max(np.abs(Pr - Pr_truth)) error.Cpr = np.max(np.abs(Cplastr - Cplastr_truth)) print('Errors:') print(error) for k, v in list(error.items()): assert (np.abs(v) < 1e-6) return
def vehicle_setup(): # ------------------------------------------------------------------ # Initialize the Vehicle # ------------------------------------------------------------------ vehicle = SUAVE.Vehicle() vehicle.tag = 'multicopter' vehicle.configuration = 'eVTOL' # ------------------------------------------------------------------ # Vehicle-level Properties # ------------------------------------------------------------------ # mass properties vehicle.mass_properties.takeoff = 2080. * Units.lb vehicle.mass_properties.operating_empty = 1666. * Units.lb vehicle.mass_properties.max_takeoff = 2080. * Units.lb vehicle.mass_properties.center_of_gravity = [2.6, 0., 0.] # This needs updating vehicle.passengers = 5 vehicle.reference_area = 73 * Units.feet**2 vehicle.envelope.ultimate_load = 5.7 vehicle.envelope.limit_load = 3. wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.aspect_ratio = 1 wing.spans.projected = 0.01 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 = 16.0 * Units.feet 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.Fuselages.Segment() segment.tag = 'segment_1' segment.origin = [0., 0., 0.] segment.percent_x_location = 0. segment.percent_z_location = 0.0 segment.height = 0.1 * Units.feet segment.width = 0.1 * Units.feet segment.length = 0. segment.effective_diameter = 0.1 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_2' segment.origin = [4. * 0.3048, 0., 0.1 * 0.3048] segment.percent_x_location = 0.25 segment.percent_z_location = 0.05 segment.height = 3.75 * Units.feet segment.width = 5.65 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.65 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_3' segment.origin = [8. * 0.3048, 0., 0.34 * 0.3048] segment.percent_x_location = 0.5 segment.percent_z_location = 0.071 segment.height = 4.65 * Units.feet segment.width = 5.55 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 5.55 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_4' segment.origin = [12. * 0.3048, 0., 0.77 * 0.3048] segment.percent_x_location = 0.75 segment.percent_z_location = 0.089 segment.height = 4.73 * Units.feet segment.width = 4.26 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 4.26 * Units.feet fuselage.append_segment(segment) # Segment segment = SUAVE.Components.Fuselages.Segment() segment.tag = 'segment_5' segment.origin = [16. * 0.3048, 0., 2.02 * 0.3048] segment.percent_x_location = 1.0 segment.percent_z_location = 0.158 segment.height = 0.67 * Units.feet segment.width = 0.33 * Units.feet segment.length = 3.2 * Units.feet segment.effective_diameter = 0.33 * Units.feet fuselage.append_segment(segment) # add to vehicle vehicle.append_component(fuselage) #------------------------------------------------------------------ # PROPULSOR #------------------------------------------------------------------ net = Vectored_Thrust() net.number_of_engines = 6 net.thrust_angle = 90. * Units.degrees net.nacelle_diameter = 0.6 * Units.feet # need to check 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 #------------------------------------------------------------------ esc = SUAVE.Components.Energy.Distributors.Electronic_Speed_Controller() esc.efficiency = 0.95 net.esc = 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( ) bat.specific_energy = 350. * Units.Wh / Units.kg bat.resistance = 0.005 bat.max_voltage = net.voltage bat.mass_properties.mass = 300. * Units.kg initialize_from_mass(bat, bat.mass_properties.mass) net.battery = bat #------------------------------------------------------------------ # Design Rotors #------------------------------------------------------------------ # atmosphere and flight conditions for propeller/rotor design g = 9.81 # gravitational acceleration speed_of_sound = 340 # speed of sound rho = 1.22 # reference density Hover_Load = vehicle.mass_properties.takeoff * g # hover load design_tip_mach = 0.7 # design tip mach number rotor = SUAVE.Components.Energy.Converters.Rotor() rotor.tip_radius = 3.95 * Units.feet rotor.hub_radius = 0.6 * Units.feet rotor.disc_area = np.pi * (rotor.tip_radius**2) rotor.number_blades = 3 rotor.freestream_velocity = 500. * Units['ft/min'] rotor.angular_velocity = (design_tip_mach * speed_of_sound) / rotor.tip_radius rotor.design_Cl = 0.8 rotor.design_altitude = 1000 * Units.feet rotor.design_thrust = (Hover_Load / net.number_of_engines) * 2. rotor = propeller_design(rotor) rotor.induced_hover_velocity = np.sqrt( Hover_Load / (2 * rho * rotor.disc_area * net.number_of_engines)) # propulating propellers on the other side of the vehicle rotor.origin = [] for fuselage in vehicle.fuselages: if fuselage.tag == 'fuselage': continue else: rotor.origin.append(fuselage.origin[0]) # append propellers to vehicle net.rotor = rotor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Motor motor = SUAVE.Components.Energy.Converters.Motor() motor.efficiency = 0.95 motor.nominal_voltage = bat.max_voltage motor.mass_properties.mass = 3. * Units.kg motor.origin = rotor.origin motor.propeller_radius = rotor.tip_radius motor.gear_ratio = 1.0 motor.gearbox_efficiency = 1.0 motor.no_load_current = 4.0 motor = size_optimal_motor(motor, rotor) net.motor = motor # Define motor sizing parameters max_power = rotor.design_power * 1.2 max_torque = rotor.design_torque * 1.2 # test high temperature superconducting motor weight function mass = hts_motor(max_power) # test NDARC motor weight function mass = nasa_motor(max_torque) # test air cooled motor weight function mass = air_cooled_motor(max_power) motor.mass_properties.mass = mass net.motor = motor vehicle.append_component(net) vehicle.weight_breakdown = empty(vehicle, None) return vehicle
def main(): '''This script checks the functions in in Motor.py used to compute motor torques and output voltage and currents''' # Propeller prop = SUAVE.Components.Energy.Converters.Propeller() prop.number_blades = 2.0 prop.freestream_velocity = 50.0 prop.angular_velocity = 209.43951023931953 prop.tip_radius = 1.5 prop.hub_radius = 0.05 prop.design_Cl = 0.7 prop.design_altitude = 0.0 * Units.km prop.design_thrust = 2271.2220451593753 prop = propeller_design(prop) # Motor #------------------------------------------------------------------ # Design Motors #------------------------------------------------------------------ # Propeller (Thrust) motor motor = SUAVE.Components.Energy.Converters.Motor() motor.mass_properties.mass = 9. * Units.kg motor.efficiency = 0.935 motor.gear_ratio = 1. motor.gearbox_efficiency = 1. # Gear box efficiency motor.no_load_current = 2.0 motor.propeller_radius = prop.tip_radius motor.nominal_voltage = 400 motor = size_optimal_motor(motor, prop) # Propeller (Thrust) motor motor_low_fid = SUAVE.Components.Energy.Converters.Motor_Lo_Fid() motor_low_fid.motor_efficiency = 0.98 motor_low_fid.rated_power = 1000 motor_low_fid.rated_voltage = 200 motor_low_fid.mass_properties.mass = 9. * Units.kg size_from_mass(motor_low_fid) # Find the operating conditions atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() atmosphere_conditions = atmosphere.compute_values(prop.design_altitude) V = prop.freestream_velocity conditions = Data() conditions.freestream = Data() conditions.propulsion = Data() conditions.frames = Data() conditions.frames.body = Data() conditions.frames.inertial = Data() conditions.freestream.update(atmosphere_conditions) conditions.freestream.dynamic_viscosity = atmosphere_conditions.dynamic_viscosity conditions.freestream.velocity = np.array([[V, 0, 0]]) conditions.propulsion.throttle = np.array([[1.0]]) conditions.frames.body.transform_to_inertial = np.array([np.eye(3)]) conditions.propulsion.propeller_power_coefficient = np.array([[0.02]]) #------------------------------------ # Motor Omega Function #------------------------------------ # create copy of motor to test functions motor_1 = motor # Define function specific inputs voltage_1 = 400 motor_1.inputs.voltage = np.array([[voltage_1]]) # Run Motor Omega Function omega_1 = motor_1.omega(conditions) torque_1 = motor_1.outputs.torque[0][0] #------------------------------------ # Motor Current Function #------------------------------------ # create copy of motor to test functions motor_2 = motor # Define function specific inputs motor_2.inputs.voltage = np.array([[voltage_1]]) motor_2.outputs.omega = np.array([[prop.angular_velocity]]) # Run Motor Current Function i, etam = motor_2.current(conditions) current_2 = i[0][0] #------------------------------------ # Motor Torque Function #------------------------------------ # create copy of motor to test functions motor_3 = motor # Define function specific inputs motor_3.inputs.voltage = np.array([[voltage_1]]) motor_3.inputs.omega = np.array([[prop.angular_velocity]]) # Run Motor Torque Function motor_3.torque(conditions) torque_3 = motor_3.outputs.torque[0][0] #------------------------------------ # Motor Voltage-Current Function #------------------------------------ # create copy of motor to test functions motor_4 = motor # Define function specific inputs motor_4.inputs.torque = np.array([[torque_1]]) # Run Motor Voltage-Current Function motor_4.voltage_current(conditions) voltage_4 = motor_4.outputs.voltage[0][0] current_4 = motor_4.outputs.current[0][0] #------------------------------------ # Low Fidelity Motor #------------------------------------ motor_low_fid.inputs.voltage = np.array([[voltage_1]]) p, i = motor_low_fid.power_lo(conditions) power_out = p[0][0] current = i[0][0] # Truth values omega_1_truth = 209.32373481 torque_1_truth = 1051.64631117327 current_2_truth = 332.1671891793585 torque_3_truth = 630.0492434009769 voltage_4_truth = 400.22093117369883 current_4_truth = 553.0983628781883 power_out_truth = 1960.0 error = Data() error.omega_test = np.max(np.abs(omega_1_truth - omega_1[0])) error.torque_test_1 = np.max(np.abs(torque_1_truth - torque_1)) error.current_test_1 = np.max(np.abs(current_2_truth - current_2)) error.torque_test_2 = np.max(np.abs(torque_3_truth - torque_3)) error.voltage_test = np.max(np.abs(voltage_4_truth - voltage_4)) error.current_test_2 = np.max(np.abs(current_4_truth - current_4)) error.power_out_test = np.max(np.abs(power_out_truth - power_out)) print('Errors:') print(error) for k, v in list(error.items()): assert (np.abs(v) < 1e-6) return
def configs_setup(vehicle): #--------------------------------------------------------------------------- # Initialize Configurations #--------------------------------------------------------------------------- configs = SUAVE.Components.Configs.Config.Container() base_config = SUAVE.Components.Configs.Config(vehicle) base_config.tag = 'base' configs.append(base_config) #--------------------------------------------------------------------------- # Electric Helicopter Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_helicopter' config.propulsors.network.number_of_engines = 1 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 3800. * Units.mm prop_attributes.hub_radius = 500. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 1600. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0.,0.,0.] config.propulsors.network.propeller = prop configs.append(config) #--------------------------------------------------------------------------- # Electric Stopped Rotor Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_stopped_rotor' config.propulsors.network.number_of_engines = 8 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 800. * Units.mm #608 prop_attributes.hub_radius = 150. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 200. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0.,0.,0.] config.propulsors.network.propeller = prop thrust_prop_attributes = cp.deepcopy(prop_attributes) thrust_prop_attributes.number_blades = 2.0 thrust_prop = SUAVE.Components.Energy.Converters.Propeller() thrust_prop.prop_attributes = thrust_prop_attributes config.propulsors.network.thrust_propeller = thrust_prop configs.append(config) #--------------------------------------------------------------------------- # Electric Tiltrotor Configuration #--------------------------------------------------------------------------- config = SUAVE.Components.Configs.Config(base_config) config.tag = 'electric_tiltrotor' config.propulsors.network.number_of_engines = 8 prop_attributes = Data() prop_attributes.number_blades = 4.0 prop_attributes.freestream_velocity = 150. * Units['meter/second'] prop_attributes.angular_velocity = 3500. * Units['rpm'] prop_attributes.tip_radius = 800. * Units.mm #608 prop_attributes.hub_radius = 150. * Units.mm prop_attributes.design_Cl = 0.7 prop_attributes.design_altitude = 1. * Units.km prop_attributes.design_thrust = 200. * 9.81 * Units.newtons prop_attributes.design_power = 0. * Units.watts prop_attributes = propeller_design(prop_attributes) prop = SUAVE.Components.Energy.Converters.Propeller() prop.prop_attributes = prop_attributes prop.origin = [0.,0.,0.] config.propulsors.network.propeller = prop configs.append(config) return configs