def __call__(self, conditions): """ process vehicle to setup geometry, condititon and configuration Inputs: conditions - DataDict() of aerodynamic conditions results - DataDict() of Outputs: Assumptions: """ # unpack configuration = self.configuration geometry = self.geometry stability_model = self.stability_model q = conditions.freestream.dynamic_pressure Sref = geometry.reference_area mach = conditions.freestream.mach_number velocity = conditions.freestream.velocity density = conditions.freestream.density Span = geometry.wings['main_wing'].spans.projected mac = geometry.wings['main_wing'].chords.mean_aerodynamic aero = conditions.aerodynamics # set up data structures static_stability = Data() dynamic_stability = Data() # Calculate CL_alpha if not conditions.has_key('lift_curve_slope'): conditions.lift_curve_slope = datcom(geometry.wings['main_wing'], mach) # Calculate change in downwash with respect to change in angle of attack for surf in geometry.wings: sref = surf.areas.reference span = (surf.aspect_ratio * sref)**0.5 surf.CL_alpha = datcom(surf, mach) surf.ep_alpha = Supporting_Functions.ep_alpha( surf.CL_alpha, sref, span) # Static Stability Methods static_stability.cm_alpha = taw_cmalpha(geometry, mach, conditions, configuration) static_stability.cn_beta = taw_cnbeta(geometry, conditions, configuration) # Dynamic Stability if np.count_nonzero( configuration.mass_properties.moments_of_inertia.tensor) > 0: # Dynamic Stability Approximation Methods - valid for non-zero I tensor # Derivative of yawing moment with respect to the rate of yaw cDw = aero.drag_breakdown.parasite[ 'main_wing'].parasite_drag_coefficient # Might not be the correct value l_v = geometry.wings['vertical_stabilizer'].origin[ 0] + geometry.wings['vertical_stabilizer'].aerodynamic_center[ 0] - geometry.wings['main_wing'].origin[ 0] - geometry.wings['main_wing'].aerodynamic_center[0] dynamic_stability.cn_r = Supporting_Functions.cn_r( cDw, geometry.wings['vertical_stabilizer'].areas.reference, Sref, l_v, span, geometry.wings['vertical_stabilizer'].dynamic_pressure_ratio, geometry.wings['vertical_stabilizer'].CL_alpha) # Derivative of rolling moment with respect to roll rate dynamic_stability.cl_p = 0 # Need to see if there is a low fidelity way to calculate cl_p # Derivative of roll rate with respect to sideslip (dihedral effect) dynamic_stability.cl_beta = 0 # Need to see if there is a low fidelity way to calculate cl_beta # Derivative of pitching moment with respect to pitch rate l_t = geometry.wings['horizontal_stabilizer'].origin[ 0] + geometry.wings['horizontal_stabilizer'].aerodynamic_center[ 0] - geometry.wings['main_wing'].origin[ 0] - geometry.wings['main_wing'].aerodynamic_center[ 0] #Need to check this is the length of the horizontal tail moment arm dynamic_stability.cm_q = Supporting_Functions.cm_q( conditions.lift_curve_slope, l_t, mac) # Need to check Cm_i versus Cm_alpha # Derivative of pitching rate with respect to d(alpha)/d(t) dynamic_stability.cm_alpha_dot = Supporting_Functions.cm_alphadot( static_stability.cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha, l_t, mac) # Need to check Cm_i versus Cm_alpha # Derivative of Z-axis force with respect to angle of attack dynamic_stability.cz_alpha = Supporting_Functions.cz_alpha( aero.drag_coefficient, conditions.lift_curve_slope) stability_model.dutch_roll = Approximations.dutch_roll( velocity, static_stability.cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], dynamic_stability.cn_r) if dynamic_stability.cl_p != 0: stability_model.roll_tau = Approximations.roll( configuration.mass_properties.momen[2][2], Sref, density, velocity, Span, dynamic_stability.cl_p) dynamic_stability.cy_phi = Supporting_Functions.cy_phi( aero.lift_coefficient) dynamic_stability.cl_r = Supporting_Functions.cl_r( aero.lift_coefficient) # Will need to be changed stability_model.spiral_tau = Approximations.spiral( conditions.weights.total_mass, velocity, density, Sref, dynamic_stability.cl_p, static_stability.cn_beta, dynamic_stability.cy_phi, dynamic_stability.cl_beta, dynamic_stability.cn_r, dynamic_stability.cl_r) stability_model.short_period = Approximations.short_period( velocity, density, Sref, mac, dynamic_stability.cm_q, dynamic_stability.cz_alpha, conditions.weights.total_mass, static_stability.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1][1], dynamic_stability.cm_alpha_dot) stability_model.phugoid = Approximations.phugoid( conditions.freestream.gravity, conditions.freestream.velocity, aero.drag_coefficient, aero.lift_coefficient) # Dynamic Stability Full Linearized Methods if aero.has_key( 'cy_beta' ) and dynamic_stability.cl_p != 0 and dynamic_stability.cl_beta != 0: theta = conditions.frames.wind.body_rotations[:, 1] dynamic_stability.cy_beta = aero.cy_beta dynamic_stability.cl_psi = Supporting_Functions.cy_psi( aero.lift_coefficient, theta) dynamic_stability.cL_u = 0 dynamic_stability.cz_u = Supporting_Functions.cz_u( aero.lift_coefficient, velocity, dynamic_stability.cL_u) dynamic_stability.cz_alpha_dot = Supporting_Functions.cz_alphadot( static_stability.cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha) dynamic_stability.cz_q = Supporting_Functions.cz_q( static_stability.cm_alpha) dynamic_stability.cx_u = Supporting_Functions.cx_u( aero.drag_coefficient) dynamic_stability.cx_alpha = Supporting_Functions.cx_alpha( aero.lift_coefficient, conditions.lift_curve_slope) lateral_directional = Full_Linearized_Equations.lateral_directional( velocity, static_stability.cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2] [2], dynamic_stability.cn_r, configuration.mass_properties.Moments_Of_Inertia.tensor[0] [0], dynamic_stability.cl_p, configuration.mass_properties.moments_of_inertia.tensor[0] [2], dynamic_stability.cl_r, dynamic_stability.cl_beta, dynamic_stability.cn_p, dynamic_stability.cy_phi, dynamic_stability.cy_psi, dynamic_stability.cy_beta, conditions.weights.total_mass) longitudinal = Full_Linearized_Equations.longitudinal( velocity, density, Sref, mac, dynamic_stability.cm_q, dynamic_stability.cz_alpha, conditions.weights.total_mass, static_stability.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1] [1], dynamic_stability.cm_alpha_dot, dynamic_stability.cz_u, dynamic_stability.cz_alpha_dot, dynamic_stability.cz_q, -aero.lift_coefficient, theta, dynamic_stability.cx_u, dynamic_stability.cx_alpha) stability_model.dutch_roll.natural_frequency = lateral_directional.dutch_natural_frequency stability_model.dutch_roll.damping_ratio = lateral_directional.dutch_damping_ratio stability_model.spiral_tau = lateral_directional.spiral_tau stability_model.roll_tau = lateral_directional.roll_tau stability_model.short_period.natural_frequency = longitudinal.short_natural_frequency stability_model.short_period.damping_ratio = longitudinal.short_damping_ratio stability_model.phugoid.natural_frequency = longitudinal.phugoid_natural_frequency stability_model.phugoid.damping_ratio = longitudinal.phugoid_damping_ratio # pack results results = Data() results.static = static_stability results.dynamic = dynamic_stability return results
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.sweep = 42.0 * Units.deg # Leading edge wing.chords.root = 42.9 * Units.feet #54.5 wing.chords.tip = 14.7 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.origin = np.array([58.6, 0., 3.6]) * Units.feet reference = SUAVE.Core.Container() vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' vertical = SUAVE.Components.Wings.Wing() vertical.spans.exposed = 32.4 * Units.feet vertical.chords.root = 38.7 * Units.feet # vertical.chords.fuselage_intersect vertical.chords.tip = 13.4 * Units.feet vertical.sweep = 50.0 * Units.deg # Leading Edge vertical.x_root_LE1 = 180.0 * Units.feet vertical.symmetric = False vertical.exposed_root_chord_offset = 13.3 * Units.feet ref_vertical = extend_to_ref_area(vertical) wing.areas.reference = ref_vertical.areas.reference wing.spans.projected = ref_vertical.spans.projected wing.chords.root = ref_vertical.chords.root dx_LE_vert = ref_vertical.root_LE_change wing.chords.tip = vertical.chords.tip wing.aspect_ratio = ref_vertical.aspect_ratio wing.sweep = vertical.sweep wing.taper = wing.chords.tip / wing.chords.root wing.origin = np.array([vertical.x_root_LE1 + dx_LE_vert, 0., 0.]) wing.effective_aspect_ratio = 2.2 wing.symmetric = False wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) Mach = np.array([0.198]) wing.CL_alpha = datcom(wing, Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.areas.side_projected = 4696.16 * Units.feet**2 fuselage.lengths.total = 229.7 * Units.feet fuselage.heights.maximum = 26.9 * Units.feet fuselage.width = 20.9 * Units.feet fuselage.heights.at_quarter_length = 26.0 * Units.feet fuselage.heights.at_three_quarters_length = 19.7 * Units.feet fuselage.heights.at_wing_root_quarter_chord = 23.8 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([112.2, 0, 6.8 ]) * Units.feet #segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment = SUAVE.Analyses.Mission.Segments.Segment() segment.freestream = Data() segment.freestream.mach_number = Mach segment.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() altitude = 0.0 * Units.feet conditions = segment.atmosphere.compute_values(altitude / Units.km) segment.a = conditions.speed_of_sound segment.freestream.density = conditions.density segment.freestream.dynamic_viscosity = conditions.dynamic_viscosity segment.freestream.velocity = segment.freestream.mach_number * segment.a #Method Test cn_b = taw_cnbeta(vehicle, segment, configuration) expected = 0.08122837 # Should be 0.184 error = Data() error.cn_b_747 = (cn_b - expected) / expected #Parameters Required #Using values for a Beechcraft Model 99 #MODEL DOES NOT ACCOUNT FOR DESTABILIZING EFFECTS OF PROPELLERS! """wing = SUAVE.Components.Wings.Wing() wing.area = 280.0 * Units.feet**2 wing.span = 46.0 * Units.feet wing.sweep_le = 3.0 * Units.deg wing.z_position = 2.2 * Units.feet wing.taper = 0.46 wing.aspect_ratio = wing.span**2/wing.area wing.symmetric = True fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.side_area = 185.36 * Units.feet**2 fuselage.length = 44.0 * Units.feet fuselage.h_max = 6.0 * Units.feet fuselage.w_max = 5.4 * Units.feet fuselage.height_at_vroot_quarter_chord = 2.9 * Units.feet fuselage.height_at_quarter_length = 4.8 * Units.feet fuselage.height_at_three_quarters_length = 4.3 * Units.feet nacelle = SUAVE.Components.Fuselages.Fuselage() nacelle.side_area = 34.45 * Units.feet**2 nacelle.x_front = 7.33 * Units.feet nacelle.length = 14.13 * Units.feet nacelle.h_max = 3.68 * Units.feet nacelle.w_max = 2.39 * Units.feet nacelle.height_at_quarter_length = 3.08 * Units.feet nacelle.height_at_three_quarters_length = 2.12 * Units.feet other_bodies = [nacelle,nacelle] vertical = SUAVE.Components.Wings.Wing() vertical.span = 6.6 * Units.feet vertical.root_chord = 8.2 * Units.feet vertical.tip_chord = 3.6 * Units.feet vertical.sweep_le = 47.0 * Units.deg vertical.x_root_LE1 = 34.8 * Units.feet vertical.symmetric = False dz_centerline = 2.0 * Units.feet ref_vertical = extend_to_ref_area(vertical,dz_centerline) vertical.span = ref_vertical.ref_span vertical.area = ref_vertical.ref_area vertical.aspect_ratio = ref_vertical.ref_aspect_ratio vertical.x_root_LE = vertical.x_root_LE1 + ref_vertical.root_LE_change vertical.taper = vertical.tip_chord/ref_vertical.ref_root_chord vertical.effective_aspect_ratio = 1.57 vertical.x_ac_LE = trapezoid_ac_x(vertical) aircraft = SUAVE.Vehicle() aircraft.wing = wing aircraft.fuselage = fuselage aircraft.other_bodies = other_bodies aircraft.vertical = vertical aircraft.Mass_Props.pos_cg[0] = 17.2 * Units.feet segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment.M = 0.152 segment.atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() altitude = 0.0 * Units.feet segment.a = segment.atmosphere.compute_values(altitude / Units.km, type="a") segment.rho = segment.atmosphere.compute_values(altitude / Units.km, type="rho") segment.mew = segment.atmosphere.compute_values(altitude / Units.km, type="mew") segment.v_inf = segment.M * segment.a #Method Test expected = 0.12 print 'Beech 99 at M = {0} and h = {1} meters'.format(segment.M, altitude) cn_b = taw_cnbeta(aircraft,segment) print 'Cn_beta = {0:.4f}'.format(cn_b) print 'Expected value = {}'.format(expected) print 'Percent Error = {0:.2f}%'.format(100.0*(cn_b-expected)/expected) print ' ' #Parameters Required #Using values for an SIAI Marchetti S-211 wing = SUAVE.Components.Wings.Wing() wing.area = 136.0 * Units.feet**2 wing.span = 26.3 * Units.feet wing.sweep_le = 19.5 * Units.deg wing.z_position = -1.1 * Units.feet wing.taper = 3.1/7.03 wing.aspect_ratio = wing.span**2/wing.area fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.side_area = 116.009 * Units.feet**2 fuselage.length = 30.9 * Units.feet fuselage.h_max = 5.1 * Units.feet fuselage.w_max = 5.9 * Units.feet fuselage.height_at_vroot_quarter_chord = 4.1 * Units.feet fuselage.height_at_quarter_length = 4.5 * Units.feet fuselage.height_at_three_quarters_length = 4.3 * Units.feet other_bodies = [] vertical = SUAVE.Components.Wings.Wing() vertical.span = 5.8 * Units.feet vertical.root_chord = 5.7 * Units.feet vertical.tip_chord = 2.0 * Units.feet vertical.sweep_le = 40.2 * Units.deg vertical.x_root_LE1 = 22.62 * Units.feet vertical.symmetric = False dz_centerline = 2.9 * Units.feet ref_vertical = extend_to_ref_area(vertical,dz_centerline) vertical.span = ref_vertical.ref_span vertical.area = ref_vertical.ref_area vertical.aspect_ratio = ref_vertical.ref_aspect_ratio vertical.x_root_LE = vertical.x_root_LE1 + ref_vertical.root_LE_change vertical.taper = vertical.tip_chord/ref_vertical.ref_root_chord vertical.effective_aspect_ratio = 2.65 vertical.x_ac_LE = trapezoid_ac_x(vertical) aircraft = SUAVE.Vehicle() aircraft.wing = wing aircraft.fuselage = fuselage aircraft.other_bodies = other_bodies aircraft.vertical = vertical aircraft.Mass_Props.pos_cg[0] = 16.6 * Units.feet segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment.M = 0.111 segment.atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() altitude = 0.0 * Units.feet segment.a = segment.atmosphere.compute_values(altitude / Units.km, type="a") segment.rho = segment.atmosphere.compute_values(altitude / Units.km, type="rho") segment.mew = segment.atmosphere.compute_values(altitude / Units.km, type="mew") segment.v_inf = segment.M * segment.a #Method Test print 'SIAI Marchetti S-211 at M = {0} and h = {1} meters'.format(segment.M, altitude) cn_b = taw_cnbeta(aircraft,segment) expected = 0.160 print 'Cn_beta = {0:.4f}'.format(cn_b) print 'Expected value = {}'.format(expected) print 'Percent Error = {0:.2f}%'.format(100.0*(cn_b-expected)/expected) print ' '""" for k, v in error.items(): assert (np.abs(v) < 0.1) return
wing.area = 5500.0 * Units.feet**2 wing.span = 196.0 * Units.feet wing.sweep_le = 42.0 * Units.deg wing.taper = 14.7/54.5 wing.aspect_ratio = wing.span**2/wing.area wing.symmetric = True wing.x_LE = 58.6 * Units.feet wing.x_ac_LE = 112. * Units.feet - wing.x_LE wing.eta = 1.0 wing.downwash_adj = 1.0 Mach = 0.198 reference = SUAVE.Structure.Container() reference.area = wing.area reference.mac = 27.3 * Units.feet reference.CL_alpha_wing = datcom(wing,Mach) wing.CL_alpha = reference.CL_alpha_wing horizontal = SUAVE.Components.Wings.Wing() horizontal.area = 1490.55* Units.feet**2 horizontal.span = 71.6 * Units.feet horizontal.sweep_le = 44.0 * Units.deg horizontal.taper = 7.5/32.6 horizontal.aspect_ratio = horizontal.span**2/horizontal.area horizontal.x_LE = 187.0 * Units.feet horizontal.symmetric= True horizontal.eta = 0.95 horizontal.downwash_adj = 1.0 - 2.0*reference.CL_alpha_wing/np.pi/wing.aspect_ratio horizontal.x_ac_LE = trapezoid_ac_x(horizontal) horizontal.CL_alpha = datcom(horizontal,Mach)
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.sweep = 42.0 * Units.deg # Leading edge wing.taper = 14.7 / 42.9 #14.7/54.5 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([58.6, 0, 0]) * Units.feet wing.aerodynamic_center = np.array([ 112.2 * Units.feet, 0., 0. ]) - wing.origin #16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 Mach = np.array([0.198]) conditions = Data() conditions.lift_curve_slope = datcom(wing, Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55 * Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweep = 44.0 * Units.deg # leading edge wing.taper = 7.5 / 32.6 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.origin = np.array([187.0, 0, 0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0 * main_wing_CLa / np.pi / main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing, Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 77.0 * Units.feet fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([112.2, 0, 0 ]) * Units.feet cm_a = taw_cmalpha(vehicle, Mach, conditions, configuration) expected = -1.627 #Should be -1.45 error = Data() error.cm_a_747 = (cm_a - expected) / expected #Parameters Required #Using values for a Beech 99 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.chords.root = 7.9 * Units.feet wing.sweep = 4.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([15., 0, 0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0., 0.]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 Mach = np.array([0.152]) reference = SUAVE.Core.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing, Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweep = 21. * Units.deg # leading edge wing.taper = 3.1 / 6.17 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.origin = np.array([36.3, 0, 0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0 * main_wing_CLa / np.pi / main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing, Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([17.2, 0, 0 ]) * Units.feet #Method Test cm_a = taw_cmalpha(vehicle, Mach, conditions, configuration) expected = -2.521 #Should be -2.08 error.cm_a_beech_99 = (cm_a - expected) / expected #Parameters Required #Using values for an SIAI Marchetti S-211 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 136.0 * Units.feet**2 wing.spans.projected = 26.3 * Units.feet wing.chords.mean_aerodynamic = 5.4 * Units.feet wing.chords.root = 7.03 * Units.feet wing.chords.tip = 3.1 * Units.feet wing.sweep = 19.5 * Units.deg # Leading edge wing.taper = 3.1 / 7.03 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([13.5, 0, 0]) * Units.feet wing.aerodynamic_center = np.array( [trapezoid_ac_x(wing), 0., 0.]) #16.6, 0. , 0. ]) * Units.feet - wing.origin wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 Mach = np.array([0.111]) conditions = Data() conditions.lift_curve_slope = datcom(wing, Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 36.46 * Units.feet**2 wing.spans.projected = 13.3 * Units.feet wing.sweep = 18.5 * Units.deg # leading edge wing.taper = 1.6 / 3.88 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.origin = np.array([26.07, 0., 0.]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.9 wing.ep_alpha = 2.0 * main_wing_CLa / np.pi / main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing, Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 12.67 * Units.feet fuselage.lengths.total = 30.9 * Units.feet fuselage.width = ((2.94 + 5.9) / 2) * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([16.6, 0, 0 ]) * Units.feet #Method Test cm_a = taw_cmalpha(vehicle, Mach, conditions, configuration) expected = -0.5409 #Should be -0.6 error.cm_a_SIAI = (cm_a - expected) / expected for k, v in error.items(): assert (np.abs(v) < 0.01) return
def vehicle_setup(): vehicle = SUAVE.Vehicle() #print vehicle vehicle.mass_properties.max_zero_fuel = 238780*Units.kg vehicle.mass_properties.max_takeoff = 833000.*Units.lbs vehicle.design_mach_number = 0.92 vehicle.design_range = 6560 * Units.miles vehicle.design_cruise_alt = 35000.0 * Units.ft vehicle.envelope.limit_load = 2.5 vehicle.envelope.ultimate_load = 3.75 vehicle.systems.control = "fully powered" vehicle.systems.accessories = "longe range" # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.chords.tip = 14.7 * Units.feet wing.sweeps.quarter_chord = 42.0 * Units.deg # Leading edge wing.sweeps.leading_edge = 42.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = [[58.6* Units.feet ,0,3.6* Units.feet ]] wing.aerodynamic_center = np.array([112.2*Units.feet,0.,0.])-wing.origin[0]#16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac = compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset = .8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0] = .3*wing.chords.mean_aerodynamic+mac_le_offset wing.thickness_to_chord = 0.14 Mach = np.array([0.198]) conditions = Data() conditions.weights = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights.total_mass = np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference # 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) vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Horizontal_Tail() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.areas.wetted = 1490.55 * Units.feet ** 2 wing.areas.exposed = 1490.55 * Units.feet ** 2 wing.spans.projected = 71.6 * Units.feet wing.sweeps.quarter_chord = 44.0 * Units.deg # leading edge wing.sweeps.leading_edge = 44.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = [[187.0* Units.feet,0,0]] wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing,Mach) wing.thickness_to_chord = 0.1 vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Vertical_Tail() wing.tag = 'vertical_stabilizer' wing.spans.exposed = 32.4 * Units.feet wing.chords.root = 38.7 * Units.feet # vertical.chords.fuselage_intersect wing.chords.tip = 13.4 * Units.feet wing.sweeps.quarter_chord = 50.0 * Units.deg # Leading Edge wing.x_root_LE1 = 180.0 * Units.feet wing.symmetric = False wing.exposed_root_chord_offset = 13.3 * Units.feet wing = extend_to_ref_area(wing) wing.areas.reference = wing.extended.areas.reference wing.areas.wetted = wing.areas.reference wing.areas.exposed = wing.areas.reference wing.spans.projected = wing.extended.spans.projected wing.chords.root = 14.9612585185 dx_LE_vert = wing.extended.root_LE_change wing.taper = 0.272993077083 wing.origin = [[wing.x_root_LE1 + dx_LE_vert,0.,0.]] wing.aspect_ratio = (wing.spans.projected**2)/wing.areas.reference wing.effective_aspect_ratio = 2.2 wing.symmetric = False wing.aerodynamic_center = np.array([trapezoid_ac_x(wing),0.0,0.0]) wing.dynamic_pressure_ratio = .95 Mach = np.array([0.198]) wing.CL_alpha = 0. wing.ep_alpha = 0. wing.thickness_to_chord = 0.1 vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.lengths.total = 229.7 * Units.feet fuselage.areas.side_projected = 4696.16 * Units.feet**2 #used for cnbeta fuselage.heights.maximum = 26.9 * Units.feet #used for cnbeta fuselage.heights.at_quarter_length = 26.0 * Units.feet #used for cnbeta fuselage.heights.at_three_quarters_length = 19.7 * Units.feet #used for cnbeta fuselage.heights.at_wing_root_quarter_chord = 23.8 * Units.feet #used for cnbeta fuselage.x_root_quarter_chord = 77.0 * Units.feet #used for cmalpha fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet fuselage.areas.wetted = 688.64 * Units.feet**2 fuselage.differential_pressure = 5.0e4 * Units.pascal vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity=np.array([[112.2,0,0]]) * Units.feet # ------------------------------------------------------------------ # Turbofan Network # ------------------------------------------------------------------ # instantiate the gas turbine network turbofan = SUAVE.Components.Energy.Networks.Turbofan() turbofan.tag = 'turbofan' # setup turbofan.number_of_engines = 4.0 turbofan.bypass_ratio = 4.8 turbofan.engine_length = 3.934 turbofan.nacelle_diameter = 2.428 turbofan.origin = [[36.56, 22, -1.9], [27, 12, -1.9],[36.56, -22, -1.9], [27, -12, -1.9]] # compute engine areas Awet = 1.1 * np.pi * turbofan.nacelle_diameter * turbofan.engine_length # Assign engine areas turbofan.areas.wetted = Awet # working fluid turbofan.working_fluid = SUAVE.Attributes.Gases.Air() # ------------------------------------------------------------------ # Component 1 - Ram # to convert freestream static to stagnation quantities # instantiate ram = SUAVE.Components.Energy.Converters.Ram() ram.tag = 'ram' # add to the network turbofan.append(ram) # ------------------------------------------------------------------ # Component 2 - Inlet Nozzle # instantiate inlet_nozzle = SUAVE.Components.Energy.Converters.Compression_Nozzle() inlet_nozzle.tag = 'inlet_nozzle' # setup inlet_nozzle.polytropic_efficiency = 0.98 inlet_nozzle.pressure_ratio = 0.98 # add to network turbofan.append(inlet_nozzle) # ------------------------------------------------------------------ # Component 3 - Low Pressure Compressor # instantiate compressor = SUAVE.Components.Energy.Converters.Compressor() compressor.tag = 'low_pressure_compressor' # setup compressor.polytropic_efficiency = 0.91 compressor.pressure_ratio = 1.14 # add to network turbofan.append(compressor) # ------------------------------------------------------------------ # Component 4 - High Pressure Compressor # instantiate compressor = SUAVE.Components.Energy.Converters.Compressor() compressor.tag = 'high_pressure_compressor' # setup compressor.polytropic_efficiency = 0.91 compressor.pressure_ratio = 13.415 # add to network turbofan.append(compressor) # ------------------------------------------------------------------ # Component 5 - Low Pressure Turbine # instantiate turbine = SUAVE.Components.Energy.Converters.Turbine() turbine.tag = 'low_pressure_turbine' # setup turbine.mechanical_efficiency = 0.99 turbine.polytropic_efficiency = 0.93 # add to network turbofan.append(turbine) # ------------------------------------------------------------------ # Component 6 - High Pressure Turbine # instantiate turbine = SUAVE.Components.Energy.Converters.Turbine() turbine.tag = 'high_pressure_turbine' # setup turbine.mechanical_efficiency = 0.99 turbine.polytropic_efficiency = 0.93 # add to network turbofan.append(turbine) # ------------------------------------------------------------------ # Component 7 - Combustor # instantiate combustor = SUAVE.Components.Energy.Converters.Combustor() combustor.tag = 'combustor' # setup combustor.efficiency = 0.99 combustor.alphac = 1.0 combustor.turbine_inlet_temperature = 1450 combustor.pressure_ratio = 0.95 combustor.fuel_data = SUAVE.Attributes.Propellants.Jet_A() # add to network turbofan.append(combustor) # ------------------------------------------------------------------ # Component 8 - Core Nozzle # instantiate nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle() nozzle.tag = 'core_nozzle' # setup nozzle.polytropic_efficiency = 0.95 nozzle.pressure_ratio = 0.99 # add to network turbofan.append(nozzle) # ------------------------------------------------------------------ # Component 9 - Fan Nozzle # instantiate nozzle = SUAVE.Components.Energy.Converters.Expansion_Nozzle() nozzle.tag = 'fan_nozzle' # setup nozzle.polytropic_efficiency = 0.95 nozzle.pressure_ratio = 0.99 # add to network turbofan.append(nozzle) # ------------------------------------------------------------------ # Component 10 - Fan # instantiate fan = SUAVE.Components.Energy.Converters.Fan() fan.tag = 'fan' # setup fan.polytropic_efficiency = 0.93 fan.pressure_ratio = 1.7 # add to network turbofan.append(fan) # ------------------------------------------------------------------ # Component 10 : thrust (to compute the thrust) thrust = SUAVE.Components.Energy.Processes.Thrust() thrust.tag = 'compute_thrust' # total design thrust (includes all the engines) # picked lower range of 747-400 at https://en.wikipedia.org/wiki/Boeing_747 thrust.total_design = 4 * 276000. * Units.N # Newtons # design sizing conditions altitude = 35000.0 * Units.ft mach_number = 0.92 isa_deviation = 0. # Engine setup for noise module # add to network turbofan.thrust = thrust # size the turbofan turbofan_sizing(turbofan, mach_number, altitude) # add gas turbine network turbofan to the vehicle vehicle.append_component(turbofan) #configuration.mass_properties.zero_fuel_center_of_gravity=np.array([76.5,0,0])*Units.feet #just put a number here that got the expected value output; may want to change fuel =SUAVE.Components.Physical_Component() fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel return vehicle
def vehicle_setup(): vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff = 2750 * Units.kg #from Wikipedia vehicle.mass_properties.empty = 1850 * Units.kg vehicle.mass_properties.max_zero_fuel = vehicle.mass_properties.max_takeoff - vehicle.mass_properties.empty + 2. * 225 * Units.lbs #2 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 136.0 * Units.feet**2 wing.spans.projected = 26.3 * Units.feet wing.chords.mean_aerodynamic = 5.4 * Units.feet wing.chords.root = 7.03 * Units.feet wing.chords.tip = 3.1 * Units.feet wing.sweeps.quarter_chord = 19.5 * Units.deg # Leading edge wing.sweeps.leading_edge = 19.5 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 3.1 / 7.03 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([13.5, 0, 0]) * Units.feet wing.aerodynamic_center = np.array( [trapezoid_ac_x(wing), 0., 0.]) #16.6, 0. , 0. ]) * Units.feet - wing.origin wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac = compute_span_location_from_chord_length( wing, wing.chords.mean_aerodynamic) mac_le_offset = .8 * np.sin( wing.sweeps.leading_edge ) * span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[ 0] = .3 * wing.chords.mean_aerodynamic + mac_le_offset Mach = np.array([0.111]) conditions = Data() conditions.lift_curve_slope = datcom(wing, Mach) conditions.weights = Data() conditions.weights.total_mass = np.array( [[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 36.46 * Units.feet**2 wing.spans.projected = 13.3 * Units.feet wing.sweeps.quarter_chord = 18.5 * Units.deg # leading edge wing.sweeps.leading_edge = 18.5 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 1.6 / 3.88 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.origin = np.array([26.07, 0., 0.]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.9 wing.ep_alpha = 2.0 * main_wing_CLa / np.pi / main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing, Mach) span_location_mac = compute_span_location_from_chord_length( wing, wing.chords.mean_aerodynamic) mac_le_offset = .8 * np.sin( wing.sweeps.leading_edge ) * span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[ 0] = .3 * wing.chords.mean_aerodynamic + mac_le_offset vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 12.67 * Units.feet fuselage.lengths.total = 30.9 * Units.feet fuselage.width = ((2.94 + 5.9) / 2) * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([16.6, 0, 0 ]) * Units.feet fuel = SUAVE.Components.Physical_Component() fuel.origin = wing.origin fuel.mass_properties.center_of_gravity = wing.mass_properties.center_of_gravity fuel.mass_properties.mass = vehicle.mass_properties.max_takeoff - vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg = vehicle.mass_properties.center_of_gravity MTOW = vehicle.mass_properties.max_takeoff fuel_cg = fuel.origin + fuel.mass_properties.center_of_gravity fuel_mass = fuel.mass_properties.mass sum_moments_less_fuel = (cg * MTOW - fuel_cg * fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel / vehicle.mass_properties.max_zero_fuel return vehicle
def taw_cnbeta(geometry,conditions,configuration): """ CnBeta = SUAVE.Methods.Flight_Dynamics.Static_Stability.Approximations.Tube_Wing.taw_cnbeta(configuration,conditions) This method computes the static directional stability derivative for a standard Tube-and-Wing aircraft configuration. CAUTION: The correlations used in this method do not account for the destabilizing moments due to propellers. This can lead to higher-than- expected values of CnBeta, particularly for smaller prop-driven aircraft Inputs: geometry - aircraft geometrical features: a data dictionary with the fields: wings['Main Wing'] - the aircraft's main wing areas.reference - wing reference area [meters**2] spans.projected - span of the wing [meters] sweep - sweep of the wing leading edge [radians] aspect_ratio - wing aspect ratio [dimensionless] origin - the position of the wing root in the aircraft body frame [meters] wings['Vertical Stabilizer'] spans.projected - projected span (height for a vertical tail) of the exposed surface [meters] areas.reference - area of the reference vertical tail [meters**2] sweep - leading edge sweep of the aerodynamic surface [radians] chords.root - chord length at the junction between the tail and the fuselage [meters] chords.tip - chord length at the tip of the aerodynamic surface [meters] symmetric - Is the wing symmetric across the fuselage centerline? origin - the position of the vertical tail root in the aircraft body frame [meters] exposed_root_chord_offset - the displacement from the fuselage centerline to the exposed area's physical root chordline [meters] x_v = vert.origin[0] b_v = vert.spans.projected ac_vLE = vert.aerodynamic_center[0] fuselages.Fuselage - a data dictionary with the fields: areas.side_projected - fuselage body side area [meters**2] lengths.total - length of the fuselage [meters] heights.maximum - maximum height of the fuselage [meters] width - maximum width of the fuselage [meters] heights.at_quarter_length - fuselage height at 1/4 of the fuselage length [meters] heights.at_three_quarters_length - fuselage height at 3/4 of fuselage length [meters] heights.at_vertical_root_quarter_chord - fuselage height at the quarter chord of the vertical tail root [meters] vertical - a data dictionary with the fields below: NOTE: This vertical tail geometry will be used to define a reference vertical tail that extends to the fuselage centerline. x_ac_LE - the x-coordinate of the vertical tail aerodynamic center measured relative to the tail root leading edge (root of reference tail area - at fuselage centerline) leading edge, relative to the nose [meters] sweep_le - leading edge sweep of the vertical tail [radians] span - height of the vertical tail [meters] taper - vertical tail taper ratio [dimensionless] aspect_ratio - vertical tail AR: bv/(Sv)^2 [dimensionless] effective_aspect_ratio - effective aspect ratio considering the effects of fuselage and horizontal tail [dimensionless] symmetric - indicates whether the vertical panel is symmetric about the fuselage centerline [Boolean] other_bodies - an list of data dictionaries containing bodies such as nacelles if these are large enough to strongly influence stability. Each body data dictionary contains the same fields as the fuselage data dictionary (described above), except no value is needed for 'height_at_vroot_quarter_chord'. CAN BE EMPTY LIST x_front - This is the only new field needed: the x-coordinate of the nose of the body relative to the fuselage nose conditions - a data dictionary with the fields: v_inf - true airspeed [meters/second] M - flight Mach number rho - air density [kg/meters**3] mew - air dynamic viscosity [kg/meter/second] configuration - a data dictionary with the fields: mass_properties - a data dictionary with the field: center_of_gravity - A vector in 3-space indicating CG position [meters] other - a dictionary of aerodynamic bodies, other than the fuselage, whose effect on directional stability is to be included in the analysis Outputs: CnBeta - a single float value: The static directional stability derivative Assumptions: -Assumes a tube-and-wing configuration with a single centered vertical tail -Uses vertical tail effective aspect ratio, currently calculated by hand, using methods from USAF Stability and Control DATCOM -The validity of correlations for KN is questionable for sqrt(h1/h2) greater than about 4 or h_max/w_max outside [0.3,2]. -This method assumes a small angle of attack, so the vertical tail AC z-position does not affect the sideslip derivative. Correlations: -Correlations are taken from Roskam's Airplane Design, Part VI. """ try: configuration.other except AttributeError: configuration.other = 0 CnBeta_other = [] # Unpack inputs S = geometry.wings['Main Wing'].areas.reference b = geometry.wings['Main Wing'].spans.projected sweep = geometry.wings['Main Wing'].sweep AR = geometry.wings['Main Wing'].aspect_ratio z_w = geometry.wings['Main Wing'].origin[2] S_bs = geometry.fuselages.Fuselage.areas.side_projected l_f = geometry.fuselages.Fuselage.lengths.total h_max = geometry.fuselages.Fuselage.heights.maximum w_max = geometry.fuselages.Fuselage.width h1 = geometry.fuselages.Fuselage.heights.at_quarter_length h2 = geometry.fuselages.Fuselage.heights.at_three_quarters_length d_i = geometry.fuselages.Fuselage.heights.at_vertical_root_quarter_chord other = configuration.other vert = extend_to_ref_area(geometry.wings['Vertical Stabilizer']) S_v = vert.areas.reference x_v = vert.origin[0] b_v = vert.spans.projected ac_vLE = vert.aerodynamic_center[0] x_cg = configuration.mass_properties.center_of_gravity[0] v_inf = conditions.freestream.velocity mu = conditions.freestream.viscosity rho = conditions.freestream.density M = conditions.freestream.mach_number #Compute wing contribution to Cn_beta CnBeta_w = 0.0 #The wing contribution is assumed to be zero except at very #high angles of attack. #Compute fuselage contribution to Cn_beta Re_fuse = rho*v_inf*l_f/mu x1 = x_cg/l_f x2 = l_f**2.0/S_bs x3 = np.sqrt(h1/h2) x4 = h_max/w_max kN_1 = 3.2413*x1 - 0.663345 + 6.1086*np.exp(-0.22*x2) kN_2 = (-0.2023 + 1.3422*x3 - 0.1454*x3**2)*kN_1 kN_3 = (0.7870 + 0.1038*x4 + 0.1834*x4**2 - 2.811*np.exp(-4.0*x4)) K_N = (-0.47899 + kN_3*kN_2)*0.001 K_Rel = 1.0+0.8*np.log(Re_fuse/1.0E6)/np.log(50.) #K_Rel: Correction for fuselage Reynolds number. Roskam VI, page 400. CnBeta_f = -57.3*K_N*K_Rel*S_bs*l_f/S/b #Compute contributions of other bodies on CnBeta if other > 0: for body in other: #Unpack inputs S_bs = body.areas.side_projected x_le = body.origin[0] l_b = body.lengths.total h_max = body.heights.maximum w_max = body.width h1 = body.heights.at_quarter_length h2 = body.heights.at_three_quarters_length #Compute body contribution to Cn_beta x_cg_on_body = (x_cg-x_le)/l_b Re_body = rho*v_inf*l_b/mew x1 = x_cg_on_body/l_b x2 = l_b**2.0/S_bs x3 = np.sqrt(h1/h2) x4 = h_max/w_max kN_1 = 3.2413*x1 - 0.663345 + 6.1086*np.exp(-0.22*x2) kN_2 = (-0.2023 + 1.3422*x3 - 0.1454*x3**2)*kN_1 kN_3 = (0.7870 + 0.1038*x4 + 0.1834*x4**2 - 2.811*np.exp(-4.0*x4)) K_N = (-0.47899 + kN_3*kN_2)*0.001 #K_Rel: Correction for fuselage Reynolds number. Roskam VI, page 400. K_Rel = 1.0+0.8*np.log(Re_body/1.0E6)/np.log(50.) CnBeta_b = -57.3*K_N*K_Rel*S_bs*l_b/S/b CnBeta_other.append(CnBeta_b) #Compute vertical tail contribution l_v = x_v + ac_vLE - x_cg #try: # CLa_v = geometry.wings['Vertical Stabilizer'].CL_alpha #except AttributeError: # CLa_v = datcom(geometry.wings['Vertical Stabilizer'], [M]) try: iter(M) except TypeError: M = [M] CLa_v = datcom(vert,M) #k_v correlated from Roskam Fig. 10.12. NOT SMOOTH. bf = b_v/d_i if bf < 2.0: k_v = 0.76 elif bf < 3.5: k_v = 0.76 + 0.24*(bf-2.0)/1.5 else: k_v = 1.0 quarter_chord_sweep = convert_sweep(geometry.wings['Main Wing']) k_sweep = (1.0+np.cos(quarter_chord_sweep)) dsdb_e = 0.724 + 3.06*((S_v/S)/k_sweep) + 0.4*z_w/h_max + 0.009*AR Cy_bv = -k_v*CLa_v*dsdb_e*(S_v/S) #ASSUMING SINGLE VERTICAL TAIL CnBeta_v = -Cy_bv*l_v/b CnBeta = CnBeta_w + CnBeta_f + CnBeta_v + sum(CnBeta_other) ##print "Wing: {} Fuse: {} Vert: {} Othr: {}".format(CnBeta_w,CnBeta_f,CnBeta_v,sum(CnBeta_other)) return CnBeta
def vehicle_setup(): vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff = 4727*Units.kg #from Wikipedia vehicle.mass_properties.empty = 2515*Units.kg vehicle.mass_properties.max_zero_fuel=vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+15.*225*Units.lbs #15 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.chords.root = 7.9 * Units.feet wing.sweeps.leading_edge = 4.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 4.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([15.,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0. , 0. ]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.152]) reference = SUAVE.Core.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights=Data() conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweeps.leading_edge = 21.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 21.0 * Units.deg # leading edge wing.taper = 3.1/6.17 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([36.3,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([17.2,0,0]) * Units.feet fuel =SUAVE.Components.Physical_Component() fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel return vehicle
def __call__(self, conditions): """ process vehicle to setup geometry, condititon and configuration Inputs: conditions - DataDict() of aerodynamic conditions results - DataDict() of Outputs: Assumptions: """ # unpack configuration = self.configuration geometry = self.geometry stability_model = self.stability_model q = conditions.freestream.dynamic_pressure Sref = geometry.reference_area mach = conditions.freestream.mach_number velocity = conditions.freestream.velocity density = conditions.freestream.density Span = geometry.wings['Main Wing'].spans.projected mac = geometry.wings['Main Wing'].chords.mean_aerodynamic aero = conditions.aerodynamics # Calculate CL_alpha if not conditions.has_key('lift_curve_slope'): conditions.lift_curve_slope = datcom(geometry.wings['Main Wing'], mach) # Calculate change in downwash with respect to change in angle of attack for surf in geometry.wings: e = surf.span_efficiency sref = surf.areas.reference span = (surf.aspect_ratio * sref)**0.5 surf.CL_alpha = datcom(surf, mach) surf.ep_alpha = Supporting_Functions.ep_alpha( surf.CL_alpha, sref, span, e) # Static Stability Methods aero.cm_alpha = taw_cmalpha(geometry, mach, conditions, configuration) aero.cn_beta = taw_cnbeta(geometry, conditions, configuration) if np.count_nonzero( configuration.mass_properties.moments_of_inertia.tensor) > 0: # Dynamic Stability Approximation Methods if not aero.has_key('cn_r'): cDw = aero.drag_breakdown.parasite[ 'Main Wing'].parasite_drag_coefficient # Might not be the correct value l_v = geometry.wings['Vertical Stabilizer'].origin[ 0] + geometry.wings[ 'Vertical Stabilizer'].aerodynamic_center[ 0] - geometry.wings['Main Wing'].origin[ 0] - geometry.wings[ 'Main Wing'].aerodynamic_center[0] aero.cn_r = Supporting_Functions.cn_r( cDw, geometry.wings['Vertical Stabilizer'].areas.reference, Sref, l_v, span, geometry.wings['Vertical Stabilizer'].eta, geometry.wings['Vertical Stabilizer'].CL_alpha) if not aero.has_key('cl_p'): aero.cl_p = 0 # Need to see if there is a low fidelity way to calculate cl_p if not aero.has_key('cl_beta'): aero.cl_beta = 0 # Need to see if there is a low fidelity way to calculate cl_beta l_t = geometry.wings['Horizontal Stabilizer'].origin[ 0] + geometry.wings['Horizontal Stabilizer'].aerodynamic_center[ 0] - geometry.wings['Main Wing'].origin[ 0] - geometry.wings['Main Wing'].aerodynamic_center[ 0] #Need to check this is the length of the horizontal tail moment arm if not aero.has_key('cm_q'): aero.cm_q = Supporting_Functions.cm_q( conditions.lift_curve_slope, l_t, mac) # Need to check Cm_i versus Cm_alpha if not aero.has_key('cm_alpha_dot'): aero.cm_alpha_dot = Supporting_Functions.cm_alphadot( aero.cm_alpha, geometry.wings['Horizontal Stabilizer'].ep_alpha, l_t, mac) # Need to check Cm_i versus Cm_alpha if not aero.has_key('cz_alpha'): aero.cz_alpha = Supporting_Functions.cz_alpha( aero.drag_coefficient, conditions.lift_curve_slope) stability_model.dutch_roll = Approximations.dutch_roll( velocity, aero.cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], aero.cn_r) if aero.cl_p != 0: stability_model.roll_tau = Approximations.roll( configuration.mass_properties.momen[2][2], Sref, density, velocity, Span, aero.cl_p) if aero.cl_beta != 0: aero.cy_phi = Supporting_Functions.cy_phi( aero.lift_coefficient) aero.cl_r = Supporting_Functions.cl_r( aero.lift_coefficient) # Will need to be changed stability_model.spiral_tau = Approximations.spiral( conditions.weights.total_mass, velocity, density, Sref, aero.cl_p, aero.cn_beta, aero.cy_phi, aero.cl_beta, aero.cn_r, aero.cl_r) stability_model.short_period = Approximations.short_period( velocity, density, Sref, mac, aero.cm_q, aero.cz_alpha, conditions.weights.total_mass, aero.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1][1], aero.cm_alpha_dot) stability_model.phugoid = Approximations.phugoid( conditions.freestream.gravity, conditions.freestream.velocity, aero.drag_coefficient, aero.lift_coefficient) # Dynamic Stability Full Linearized Methods if aero.has_key( 'cy_beta') and aero.cl_p != 0 and aero.cl_beta != 0: if not aero.has_key('cy_psi'): theta = conditions.frames.wind.body_rotations[:, 1] aero.cl_psi = Supporting_Functions.cy_psi( aero.lift_coefficient, theta) if not aero.has_key('cz_u'): if not aero.has_key('cL_u'): aero.cL_u = 0 aero.cz_u = Supporting_Functions.cz_u( aero.lift_coefficient, velocity, aero.cL_u) if not aero.has_key('cz_alpha_dot'): aero.cz_alpha_dot = Supporting_Functions.cz_alphadot( aero.cm_alpha, geometry.wings['Horizontal Stabilizer'].ep_alpha) if not aero.has_key('cz_q'): aero.cz_q = Supporting_Functions.cz_q(aero.cm_alpha) if not aero.has_key('cx_u'): aero.cx_u = Supporting_Functions.cx_u( aero.drag_coefficient) if not aero.has_key('cx_alpha'): aero.cx_alpha = Supporting_Functions.cx_alpha( aero.lift_coefficient, conditions.lift_curve_slope) lateral_directional = Full_Linearized_Equations.lateral_directional( velocity, aero.cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2] [2], aero.cn_r, configuration.mass_properties.Moments_Of_Inertia.tensor[0] [0], aero.cl_p, configuration.mass_properties.moments_of_inertia.tensor[0] [2], aero.cl_r, aero.cl_beta, aero.cn_p, aero.cy_phi, aero.cy_psi, aero.cy_beta, conditions.weights.total_mass) longitudinal = Full_Linearized_Equations.longitudinal( velocity, density, Sref, mac, aero.cm_q, aero.cz_alpha, conditions.weights.total_mass, aero.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1] [1], aero.cm_alpha_dot, aero.cz_u, aero.cz_alpha_dot, aero.cz_q, -aero.lift_coefficient, theta, aero.cx_u, aero.cx_alpha) stability_model.dutch_roll.natural_frequency = lateral_directional.dutch_natural_frequency stability_model.dutch_roll.damping_ratio = lateral_directional.dutch_damping_ratio stability_model.spiral_tau = lateral_directional.spiral_tau stability_model.roll_tau = lateral_directional.roll_tau stability_model.short_period.natural_frequency = longitudinal.short_natural_frequency stability_model.short_period.damping_ratio = longitudinal.short_damping_ratio stability_model.phugoid.natural_frequency = longitudinal.phugoid_natural_frequency stability_model.phugoid.damping_ratio = longitudinal.phugoid_damping_ratio return
def compute_dynamic_flight_modes(results, aircraft, flight_conditions, cases): """This function follows the stability axis EOM derivation in Blakelock to return the aircraft's dynamic modes and state space Assumptions: Linerarized Equations are used following the reference below Source: Automatic Control of Aircraft and Missiles by J. Blakelock Pg 23 and 117 Inputs: results.aerodynamics results.stability.static results.stability.dynamic Outputs: results.dynamic_stability.LatModes results.dynamic_stability.LongModes Properties Used: N/A """ # unpack unit conversions g = flight_conditions.freestream.gravity mach = flight_conditions.freestream.mach_number # Calculate change in downwash with respect to change in angle of attack for surf in aircraft.wings: sref = surf.areas.reference span = (surf.aspect_ratio * sref)**0.5 surf.CL_alpha = datcom(surf, mach) surf.ep_alpha = Supporting_Functions.ep_alpha(surf.CL_alpha, sref, span) # Unpack aircraft Properties theta0 = results.aerodynamics.AoA AoA = results.aerodynamics.AoA CLtot = results.aerodynamics.lift_coefficient CDtot = results.aerodynamics.drag_coefficient e = results.aerodynamics.oswald_efficiency st = results.stability.static dy = results.stability.dynamic num_cases = len(AoA) b_ref = results.b_ref c_ref = results.c_ref S_ref = results.S_ref AR = (b_ref**2) / S_ref moments_of_inertia = aircraft.mass_properties.moments_of_inertia.tensor Ixx = moments_of_inertia[0][0] Iyy = moments_of_inertia[1][1] Izz = moments_of_inertia[2][2] if aircraft.mass_properties.mass == 0: m = aircraft.mass_properties.max_takeoff elif aircraft.mass_properties.max_takeoff == 0: m = aircraft.mass_properties.mass else: raise AttributeError("Specify Vehicle Mass") # unpack FLight Conditions rho = flight_conditions.freestream.density u0 = flight_conditions.freestream.velocity qDyn0 = 0.5 * rho * u0**2 st.spiral_stability = st.Cl_beta * st.Cn_r / (st.Cl_r * st.Cn_beta) ## Build longitudinal EOM A Matrix (stability axis) ALon = np.zeros((num_cases, 4, 4)) BLon = np.zeros((num_cases, 4, 1)) CLon = np.zeros((num_cases, 4, 4)) for i in range(num_cases): CLon[i, :, :] = np.eye(4) DLon = np.zeros((num_cases, 4, 1)) Cw = m * g / (qDyn0 * S_ref) Cxu = st.CX_u Xu = rho * u0 * S_ref * Cw * np.sin(theta0) + 0.5 * rho * u0 * S_ref * Cxu Cxalpha = (CLtot - 2 * CLtot / (np.pi * AR * e) * st.CL_alpha) Xw = 0.5 * rho * u0 * S_ref * Cxalpha Xq = 0 Czu = st.CZ_u Zu = -rho * u0 * S_ref * Cw * np.cos(theta0) + 0.5 * rho * u0 * S_ref * Czu Czalpha = -CDtot - st.CL_alpha Zw = 0.5 * rho * u0 * S_ref * Czalpha Czq = -st.CL_q Zq = 0.25 * rho * u0 * c_ref * S_ref * Czq Cmu = st.Cm_q Mu = 0.5 * rho * u0 * c_ref * S_ref * Cmu Mw = 0.5 * rho * u0 * c_ref * S_ref * st.Cm_alpha Mq = 0.25 * rho * u0 * c_ref * c_ref * S_ref * st.Cm_q # Derivative of pitching rate with respect to d(alpha)/d(t) if aircraft.wings['horizontal_stabilizer'] and aircraft.wings['main_wing']: l_t = aircraft.wings['horizontal_stabilizer'].origin[ 0] + aircraft.wings['horizontal_stabilizer'].aerodynamic_center[ 0] - aircraft.wings['main_wing'].origin[0] - aircraft.wings[ 'main_wing'].aerodynamic_center[0] mac = aircraft.wings['main_wing'].chords.mean_aerodynamic st.Cm_alpha_dot = Supporting_Functions.cm_alphadot( st.Cm_alpha, aircraft.wings['horizontal_stabilizer'].ep_alpha, l_t, mac) st.Cz_alpha_dot = Supporting_Functions.cz_alphadot( st.Cm_alpha, aircraft.wings['horizontal_stabilizer'].ep_alpha) else: st.Cm_alpha_dot = 0 st.Cz_alpha_dot = 0 ZwDot = 0.25 * rho * c_ref * S_ref * st.Cz_alpha_dot MwDot = 0.25 * rho * c_ref * S_ref * st.Cm_alpha_dot # Elevator effectiveness for wing in aircraft.wings: if wing.control_surfaces: for cs in wing.control_surfaces: ctrl_surf = wing.control_surfaces[cs] if (type(ctrl_surf) == Elevator): ele = st.control_surfaces_cases[ cases[i].tag].control_surfaces[cs] Xe = 0 # Neglect Ze = 0.5 * rho * u0 * u0 * S_ref * ele.CL Me = 0.5 * rho * u0 * u0 * S_ref * c_ref * ele.Cm BLon[:, 0, 0] = Xe / m BLon[:, 1, 0] = (Ze / (m - ZwDot)).T[0] BLon[:, 2, 0] = (Me / Iyy + MwDot / Iyy * Ze / (m - ZwDot)).T[0] BLon[:, 3, 0] = 0 ALon[:, 0, 0] = (Xu / m).T[0] ALon[:, 0, 1] = (Xw / m).T[0] ALon[:, 0, 2] = Xq / m ALon[:, 0, 3] = (-g * np.cos(theta0)).T[0] ALon[:, 1, 0] = (Zu / (m - ZwDot)).T[0] ALon[:, 1, 1] = (Zw / (m - ZwDot)).T[0] ALon[:, 1, 2] = ((Zq + (m * u0)) / (m - ZwDot)).T[0] ALon[:, 1, 3] = (-m * g * np.sin(theta0) / (m - ZwDot)).T[0] ALon[:, 2, 0] = ((Mu + MwDot * Zu / (m - ZwDot)) / Iyy).T[0] ALon[:, 2, 1] = ((Mw + MwDot * Zw / (m - ZwDot)) / Iyy).T[0] ALon[:, 2, 2] = ((Mq + MwDot * (Zq + m * u0) / (m - ZwDot)) / Iyy).T[0] ALon[:, 2, 3] = (-MwDot * m * g * np.sin(theta0) / (Iyy * (m - ZwDot))).T[0] ALon[:, 3, 0] = 0 ALon[:, 3, 1] = 0 ALon[:, 3, 2] = 1 ALon[:, 3, 3] = 0 # Look at eigenvalues and eigenvectors LonModes = np.zeros((num_cases, 4), dtype=complex) phugoidFreqHz = np.zeros((num_cases, 1)) phugoidDamping = np.zeros((num_cases, 1)) phugoidTimeDoubleHalf = np.zeros((num_cases, 1)) shortPeriodFreqHz = np.zeros((num_cases, 1)) shortPeriodDamping = np.zeros((num_cases, 1)) shortPeriodTimeDoubleHalf = np.zeros((num_cases, 1)) for i in range(num_cases): D, V = np.linalg.eig(ALon[i, :, :]) # State order: u, w, q, theta LonModes[i, :] = D # Find phugoid phugoidInd = np.argmax(V[0, :]) # u is the primary state involved phugoidFreqHz[i] = abs(LonModes[i, phugoidInd]) / 2 / np.pi phugoidDamping[i] = -np.cos(np.angle(LonModes[i, phugoidInd])) phugoidTimeDoubleHalf[i] = np.log(2) / abs( 2 * np.pi * phugoidFreqHz[i] * phugoidDamping[i]) # Find short period shortPeriodInd = np.argmax(V[1, :]) # w is the primary state involved shortPeriodFreqHz[i] = abs(LonModes[i, shortPeriodInd]) / 2 / np.pi shortPeriodDamping[i] = -np.cos(np.angle(LonModes[i, shortPeriodInd])) shortPeriodTimeDoubleHalf[i] = np.log(2) / abs( 2 * np.pi * shortPeriodFreqHz[i] * shortPeriodDamping[i]) ## Build lateral EOM A Matrix (stability axis) ALat = np.zeros((num_cases, 4, 4)) BLat = np.zeros((num_cases, 4, 1)) CLat = np.zeros((num_cases, 4, 4)) for i in range(num_cases): CLat[i, :, :] = np.eye(4) DLat = np.zeros((num_cases, 4, 1)) # Need to compute Ixx, Izz, and Ixz as a function of alpha Ixp = np.zeros((num_cases, 1)) Izp = np.zeros((num_cases, 1)) Ixzp = np.zeros((num_cases, 1)) for i in range(num_cases): R = np.array([[ np.cos(AoA[i][0] * Units.degrees), -np.sin(AoA[i][0] * Units.degrees) ], [ np.sin(AoA[i][0] * Units.degrees), np.cos(AoA[i][0] * Units.degrees) ]]) modI = np.array([[moments_of_inertia[0][0], moments_of_inertia[0][2]], [moments_of_inertia[2][0], moments_of_inertia[2][2]]]) INew = R * modI * np.transpose(R) IxxStab = INew[0, 0] IxzStab = -INew[0, 1] IzzStab = INew[1, 1] Ixp[i] = (IxxStab * IzzStab - IxzStab**2) / IzzStab Izp[i] = (IxxStab * IzzStab - IxzStab**2) / IxxStab Ixzp[i] = IxzStab / (IxxStab * IzzStab - IxzStab**2) Yv = 0.5 * rho * u0 * S_ref * st.CY_beta Yp = 0.25 * rho * u0 * b_ref * S_ref * st.CY_p Yr = 0.25 * rho * u0 * b_ref * S_ref * st.CY_r Lv = 0.5 * rho * u0 * b_ref * S_ref * st.Cl_beta Lp = 0.25 * rho * u0 * b_ref**2 * S_ref * st.Cl_p Lr = 0.25 * rho * u0 * b_ref**2 * S_ref * st.Cl_r Nv = 0.5 * rho * u0 * b_ref * S_ref * st.Cn_beta Np = 0.25 * rho * u0 * b_ref**2 * S_ref * st.Cn_p Nr = 0.25 * rho * u0 * b_ref**2 * S_ref * st.Cn_r # Aileron effectiveness for wing in aircraft.wings: if wing.control_surfaces: for cs in wing.control_surfaces: ctrl_surf = wing.control_surfaces[cs] if (type(ctrl_surf) == Aileron): ail = st.control_surfaces_cases[ cases[i].tag].control_surfaces[cs] Ya = 0.5 * rho * u0 * u0 * S_ref * ail.CY La = 0.5 * rho * u0 * u0 * S_ref * b_ref * ail.Cl Na = 0.5 * rho * u0 * u0 * S_ref * b_ref * ail.Cn BLat[:, 0, 0] = (Ya / m).T[0] BLat[:, 1, 0] = (La / Ixp + Ixzp * Na).T[0] BLat[:, 2, 0] = (Ixzp * La + Na / Izp).T[0] BLat[:, 3, 0] = 0 ALat[:, 0, 0] = (Yv / m).T[0] ALat[:, 0, 1] = (Yp / m).T[0] ALat[:, 0, 2] = (Yr / m - u0).T[0] ALat[:, 0, 3] = (g * np.cos(theta0)).T[0] ALat[:, 1, 0] = (Lv / Ixp + Ixzp * Nv).T[0] ALat[:, 1, 1] = (Lp / Ixp + Ixzp * Np).T[0] ALat[:, 1, 2] = (Lr / Ixp + Ixzp * Nr).T[0] ALat[:, 1, 3] = 0 ALat[:, 2, 0] = (Ixzp * Lv + Nv / Izp).T[0] ALat[:, 2, 1] = (Ixzp * Lp + Np / Izp).T[0] ALat[:, 2, 2] = (Ixzp * Lr + Nr / Izp).T[0] ALat[:, 2, 3] = 0 ALat[:, 3, 0] = 0 ALat[:, 3, 1] = 1 ALat[:, 3, 2] = (np.tan(theta0)).T[0] ALat[:, 3, 3] = 0 LatModes = np.zeros((num_cases, 4), dtype=complex) dutchRollFreqHz = np.zeros((num_cases, 1)) dutchRollDamping = np.zeros((num_cases, 1)) dutchRollTimeDoubleHalf = np.zeros((num_cases, 1)) rollSubsistenceFreqHz = np.zeros((num_cases, 1)) rollSubsistenceTimeConstant = np.zeros((num_cases, 1)) rollSubsistenceDamping = np.zeros((num_cases, 1)) spiralFreqHz = np.zeros((num_cases, 1)) spiralTimeDoubleHalf = np.zeros((num_cases, 1)) spiralDamping = np.zeros((num_cases, 1)) dutchRoll_mode_real = np.zeros((num_cases, 1)) for i in range(num_cases): D, V = np.linalg.eig(ALat[i, :, :]) # State order: u, w, q, theta LatModes[i, :] = D # Find dutch roll (complex pair) done = 0 for j in range(3): for k in range(j + 1, 4): if LatModes[i, j].real == LatModes[i, k].real: dutchRollFreqHz[i] = abs(LatModes[i, j]) / 2 / np.pi dutchRollDamping[i] = -np.cos(np.angle(LatModes[i, j])) dutchRollTimeDoubleHalf[i] = np.log(2) / abs( 2 * np.pi * dutchRollFreqHz[i] * dutchRollDamping[i]) dutchRoll_mode_real[i] = LatModes[i, j].real / 2 / np.pi done = 1 break if done: break # Find roll mode diff_vec = np.arange(0, 4) tmpInd = np.setdiff1d(diff_vec, [j, k]) rollInd = np.argmax(abs( LatModes[i, tmpInd])) # higher frequency than spiral rollInd = tmpInd[rollInd] rollSubsistenceFreqHz[i] = abs(LatModes[i, rollInd]) / 2 / np.pi rollSubsistenceDamping[i] = -np.sign(LatModes[i, rollInd].real) rollSubsistenceTimeConstant[i] = 1 / ( 2 * np.pi * rollSubsistenceFreqHz[i] * rollSubsistenceDamping[i]) # Find spiral mode spiralInd = np.setdiff1d(diff_vec, [j, k, rollInd]) spiralFreqHz[i] = abs(LatModes[i, spiralInd]) / 2 / np.pi spiralDamping[i] = -np.sign(LatModes[i, spiralInd].real) spiralTimeDoubleHalf[i] = np.log(2) / abs( 2 * np.pi * spiralFreqHz[i] * spiralDamping[i]) ## Build longitudinal and lateral state space system. Requires additional toolbox #from control.matlab import ss # control toolbox needed in python. Run "pip (or pip3) install control" #LonSys = {} #LatSys = {} #for i in range(num_cases): #LonSys[cases[i].tag] = ss(ALon[i],BLon[i],CLon[i],DLon[i]) #LatSys[cases[i].tag] = ss(ALat[i],BLat[i],CLat[i],DLat[i]) # Inertial coupling susceptibility # See Etkin & Reid pg. 118 results.dynamic_stability = Data() results.dynamic_stability.LongModes = Data() results.dynamic_stability.LatModes = Data() results.dynamic_stability.pMax = min(min(np.sqrt(-Mw * u0 / (Izz - Ixx))), min(np.sqrt(-Nv * u0 / (Iyy - Ixx)))) # ----------------------------------------------------------------------------------------------------------------------- # Store Results # ------------------------------------------------------------------------------------------------------------------------ results.dynamic_stability.LongModes.LongModes = LonModes #results.dynamic_stability.LongModes.LongSys = LonSys results.dynamic_stability.LongModes.phugoidFreqHz = phugoidFreqHz results.dynamic_stability.LongModes.phugoidDamp = phugoidDamping results.dynamic_stability.LongModes.phugoidTimeDoubleHalf = phugoidTimeDoubleHalf results.dynamic_stability.LongModes.shortPeriodFreqHz = shortPeriodFreqHz results.dynamic_stability.LongModes.shortPeriodDamp = shortPeriodDamping results.dynamic_stability.LongModes.shortPeriodTimeDoubleHalf = shortPeriodTimeDoubleHalf results.dynamic_stability.LatModes.LatModes = LatModes #results.dynamic_stability.LatModes.Latsys = LatSys results.dynamic_stability.LatModes.dutchRollFreqHz = dutchRollFreqHz results.dynamic_stability.LatModes.dutchRollDamping = dutchRollDamping results.dynamic_stability.LatModes.dutchRollTimeDoubleHalf = dutchRollTimeDoubleHalf results.dynamic_stability.LatModes.dutchRoll_mode_real = dutchRoll_mode_real results.dynamic_stability.LatModes.rollSubsistenceFreqHz = rollSubsistenceFreqHz results.dynamic_stability.LatModes.rollSubsistenceTimeConstant = rollSubsistenceTimeConstant results.dynamic_stability.LatModes.rollSubsistenceDamping = rollSubsistenceDamping results.dynamic_stability.LatModes.spiralFreqHz = spiralFreqHz results.dynamic_stability.LatModes.spiralTimeDoubleHalf = spiralTimeDoubleHalf results.dynamic_stability.LatModes.spiralDamping = spiralDamping return results
def vehicle_setup(): vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff = 4727*Units.kg #from Wikipedia vehicle.mass_properties.empty = 2515*Units.kg vehicle.mass_properties.max_zero_fuel =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+15.*225*Units.lbs #15 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.chords.root = 7.9 * Units.feet wing.sweeps.leading_edge = 4.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 4.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = [[15.* Units.feet ,0,0]] wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0. , 0. ]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac = compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0][0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.152]) reference = SUAVE.Core.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights =Data() conditions.weights.total_mass =np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference # control surfaces ------------------------------------------- flap = SUAVE.Components.Wings.Control_Surfaces.Flap() flap.tag = 'flap' flap.span_fraction_start = 0.15 # not correct, only placeholder flap.span_fraction_end = 0.324 # not correct, only placeholder flap.deflection = 1.0 * Units.deg flap.chord_fraction = 0.19 # not correct, only placeholder wing.append_control_surface(flap) slat = SUAVE.Components.Wings.Control_Surfaces.Slat() slat.tag = 'slat' slat.span_fraction_start = 0.324 # not correct, only placeholder slat.span_fraction_end = 0.963 # not correct, only placeholder slat.deflection = 1.0 * Units.deg slat.chord_fraction = 0.1 # not correct, only placeholder wing.append_control_surface(slat) vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweeps.leading_edge = 21.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 21.0 * Units.deg # leading edge wing.taper = 3.1/6.17 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = [[36.3* Units.feet,0,0]] wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([[17.2,0,0]]) * Units.feet fuel = SUAVE.Components.Physical_Component() fuel.origin = wing.origin fuel.mass_properties.center_of_gravity = wing.mass_properties.center_of_gravity fuel.mass_properties.mass = vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg = vehicle.mass_properties.center_of_gravity MTOW = vehicle.mass_properties.max_takeoff fuel_cg = fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass = fuel.mass_properties.mass sum_moments_less_fuel = (cg*MTOW-fuel_cg*fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel return vehicle
wing.area = 5500.0 * Units.feet**2 wing.span = 196.0 * Units.feet wing.sweep_le = 42.0 * Units.deg wing.taper = 14.7 / 54.5 wing.aspect_ratio = wing.span**2 / wing.area wing.symmetric = True wing.x_LE = 58.6 * Units.feet wing.x_ac_LE = 112. * Units.feet - wing.x_LE wing.eta = 1.0 wing.downwash_adj = 1.0 Mach = 0.198 reference = SUAVE.Structure.Container() reference.area = wing.area reference.mac = 27.3 * Units.feet reference.CL_alpha_wing = datcom(wing, Mach) wing.CL_alpha = reference.CL_alpha_wing horizontal = SUAVE.Components.Wings.Wing() horizontal.area = 1490.55 * Units.feet**2 horizontal.span = 71.6 * Units.feet horizontal.sweep_le = 44.0 * Units.deg horizontal.taper = 7.5 / 32.6 horizontal.aspect_ratio = horizontal.span**2 / horizontal.area horizontal.x_LE = 187.0 * Units.feet horizontal.symmetric = True horizontal.eta = 0.95 horizontal.downwash_adj = 1.0 - 2.0 * reference.CL_alpha_wing / np.pi / wing.aspect_ratio horizontal.x_ac_LE = trapezoid_ac_x(horizontal) horizontal.CL_alpha = datcom(horizontal, Mach)
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() #print vehicle vehicle.mass_properties.max_zero_fuel=238780*Units.kg vehicle.mass_properties.max_takeoff =785000.*Units.lbs wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.sweep = 42.0 * Units.deg # Leading edge wing.taper = 14.7/42.9 #14.7/54.5 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([58.6,0,0]) * Units.feet wing.aerodynamic_center = np.array([112.2*Units.feet,0.,0.])-wing.origin#16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweep)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.198]) conditions = Data() conditions.weights = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweep = 44.0 * Units.deg # leading edge wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([187.0,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 77.0 * Units.feet fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity=np.array([112.2,0,0]) * Units.feet #configuration.mass_properties.zero_fuel_center_of_gravity=np.array([76.5,0,0])*Units.feet #just put a number here that got the expected value output; may want to change fuel =SUAVE.Components.Physical_Component() fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel =vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected =-1.56222373 #Should be -1.45 error = Data() error.cm_a_747 = (cm_a - expected)/expected #Parameters Required #Using values for a Beech 99 vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff =4727*Units.kg #from Wikipedia vehicle.mass_properties.empty =2515*Units.kg vehicle.mass_properties.max_zero_fuel=vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+15.*225*Units.lbs #15 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.chords.root = 7.9 * Units.feet wing.sweep = 4.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([15.,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0. , 0. ]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweep)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.152]) reference = SUAVE.Core.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights=Data() conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweep = 21. * Units.deg # leading edge wing.taper = 3.1/6.17 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([36.3,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([17.2,0,0]) * Units.feet fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel = vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #Method Test #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = -2.48843437 #Should be -2.08 error.cm_a_beech_99 = (cm_a - expected)/expected #Parameters Required #Using values for an SIAI Marchetti S-211 vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff =2750*Units.kg #from Wikipedia vehicle.mass_properties.empty =1850*Units.kg vehicle.mass_properties.max_zero_fuel=vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+2.*225*Units.lbs #2 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 136.0 * Units.feet**2 wing.spans.projected = 26.3 * Units.feet wing.chords.mean_aerodynamic = 5.4 * Units.feet wing.chords.root = 7.03 * Units.feet wing.chords.tip = 3.1 * Units.feet wing.sweep = 19.5 * Units.deg # Leading edge wing.taper = 3.1/7.03 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([13.5,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing),0.,0.])#16.6, 0. , 0. ]) * Units.feet - wing.origin wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweep)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.111]) conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights=Data() conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 36.46 * Units.feet**2 wing.spans.projected = 13.3 * Units.feet wing.sweep = 18.5 * Units.deg # leading edge wing.taper = 1.6/3.88 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([26.07,0.,0.]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.9 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweep)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 12.67 * Units.feet fuselage.lengths.total = 30.9 * Units.feet fuselage.width = ((2.94+5.9)/2) * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([16.6,0,0]) * Units.feet fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel = vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #Method Test #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = -0.54071741 #Should be -0.6 error.cm_a_SIAI = (cm_a - expected)/expected print error for k,v in error.items(): assert(np.abs(v)<0.01) return
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.sweep = 42.0 * Units.deg # Leading edge wing.chords.root = 42.9 * Units.feet #54.5 wing.chords.tip = 14.7 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.origin = np.array([58.6,0.,3.6]) * Units.feet reference = SUAVE.Core.Container() vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' vertical = SUAVE.Components.Wings.Wing() vertical.spans.exposed = 32.4 * Units.feet vertical.chords.root = 38.7 * Units.feet # vertical.chords.fuselage_intersect vertical.chords.tip = 13.4 * Units.feet vertical.sweep = 50.0 * Units.deg # Leading Edge vertical.x_root_LE1 = 180.0 * Units.feet vertical.symmetric = False vertical.exposed_root_chord_offset = 13.3 * Units.feet ref_vertical = extend_to_ref_area(vertical) wing.areas.reference = ref_vertical.areas.reference wing.spans.projected = ref_vertical.spans.projected wing.chords.root = ref_vertical.chords.root dx_LE_vert = ref_vertical.root_LE_change wing.chords.tip = vertical.chords.tip wing.aspect_ratio = ref_vertical.aspect_ratio wing.sweep = vertical.sweep wing.taper = wing.chords.tip/wing.chords.root wing.origin = np.array([vertical.x_root_LE1 + dx_LE_vert,0.,0.]) wing.effective_aspect_ratio = 2.2 wing.symmetric = False wing.aerodynamic_center = np.array([trapezoid_ac_x(wing),0.0,0.0]) Mach = np.array([0.198]) wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.areas.side_projected = 4696.16 * Units.feet**2 fuselage.lengths.total = 229.7 * Units.feet fuselage.heights.maximum = 26.9 * Units.feet fuselage.width = 20.9 * Units.feet fuselage.heights.at_quarter_length = 26.0 * Units.feet fuselage.heights.at_three_quarters_length = 19.7 * Units.feet fuselage.heights.at_wing_root_quarter_chord = 23.8 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([112.2,0,6.8]) * Units.feet #segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment = SUAVE.Analyses.Mission.Segments.Segment() segment.freestream = Data() segment.freestream.mach_number = Mach[0] segment.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976() altitude = 0.0 * Units.feet conditions = segment.atmosphere.compute_values(altitude / Units.km) segment.a = conditions.speed_of_sound segment.freestream.density = conditions.density segment.freestream.dynamic_viscosity = conditions.dynamic_viscosity segment.freestream.velocity = segment.freestream.mach_number * segment.a #Method Test cn_b = taw_cnbeta(vehicle,segment,configuration) expected = 0.10045 # Should be 0.184 error = Data() error.cn_b_747 = (cn_b-expected)/expected #Parameters Required #Using values for a Beechcraft Model 99 #MODEL DOES NOT ACCOUNT FOR DESTABILIZING EFFECTS OF PROPELLERS! """wing = SUAVE.Components.Wings.Wing() wing.area = 280.0 * Units.feet**2 wing.span = 46.0 * Units.feet wing.sweep_le = 3.0 * Units.deg wing.z_position = 2.2 * Units.feet wing.taper = 0.46 wing.aspect_ratio = wing.span**2/wing.area wing.symmetric = True fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.side_area = 185.36 * Units.feet**2 fuselage.length = 44.0 * Units.feet fuselage.h_max = 6.0 * Units.feet fuselage.w_max = 5.4 * Units.feet fuselage.height_at_vroot_quarter_chord = 2.9 * Units.feet fuselage.height_at_quarter_length = 4.8 * Units.feet fuselage.height_at_three_quarters_length = 4.3 * Units.feet nacelle = SUAVE.Components.Fuselages.Fuselage() nacelle.side_area = 34.45 * Units.feet**2 nacelle.x_front = 7.33 * Units.feet nacelle.length = 14.13 * Units.feet nacelle.h_max = 3.68 * Units.feet nacelle.w_max = 2.39 * Units.feet nacelle.height_at_quarter_length = 3.08 * Units.feet nacelle.height_at_three_quarters_length = 2.12 * Units.feet other_bodies = [nacelle,nacelle] vertical = SUAVE.Components.Wings.Wing() vertical.span = 6.6 * Units.feet vertical.root_chord = 8.2 * Units.feet vertical.tip_chord = 3.6 * Units.feet vertical.sweep_le = 47.0 * Units.deg vertical.x_root_LE1 = 34.8 * Units.feet vertical.symmetric = False dz_centerline = 2.0 * Units.feet ref_vertical = extend_to_ref_area(vertical,dz_centerline) vertical.span = ref_vertical.ref_span vertical.area = ref_vertical.ref_area vertical.aspect_ratio = ref_vertical.ref_aspect_ratio vertical.x_root_LE = vertical.x_root_LE1 + ref_vertical.root_LE_change vertical.taper = vertical.tip_chord/ref_vertical.ref_root_chord vertical.effective_aspect_ratio = 1.57 vertical.x_ac_LE = trapezoid_ac_x(vertical) aircraft = SUAVE.Vehicle() aircraft.wing = wing aircraft.fuselage = fuselage aircraft.other_bodies = other_bodies aircraft.vertical = vertical aircraft.Mass_Props.pos_cg[0] = 17.2 * Units.feet segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment.M = 0.152 segment.atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() altitude = 0.0 * Units.feet segment.a = segment.atmosphere.compute_values(altitude / Units.km, type="a") segment.rho = segment.atmosphere.compute_values(altitude / Units.km, type="rho") segment.mew = segment.atmosphere.compute_values(altitude / Units.km, type="mew") segment.v_inf = segment.M * segment.a #Method Test expected = 0.12 print 'Beech 99 at M = {0} and h = {1} meters'.format(segment.M, altitude) cn_b = taw_cnbeta(aircraft,segment) print 'Cn_beta = {0:.4f}'.format(cn_b) print 'Expected value = {}'.format(expected) print 'Percent Error = {0:.2f}%'.format(100.0*(cn_b-expected)/expected) print ' ' #Parameters Required #Using values for an SIAI Marchetti S-211 wing = SUAVE.Components.Wings.Wing() wing.area = 136.0 * Units.feet**2 wing.span = 26.3 * Units.feet wing.sweep_le = 19.5 * Units.deg wing.z_position = -1.1 * Units.feet wing.taper = 3.1/7.03 wing.aspect_ratio = wing.span**2/wing.area fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.side_area = 116.009 * Units.feet**2 fuselage.length = 30.9 * Units.feet fuselage.h_max = 5.1 * Units.feet fuselage.w_max = 5.9 * Units.feet fuselage.height_at_vroot_quarter_chord = 4.1 * Units.feet fuselage.height_at_quarter_length = 4.5 * Units.feet fuselage.height_at_three_quarters_length = 4.3 * Units.feet other_bodies = [] vertical = SUAVE.Components.Wings.Wing() vertical.span = 5.8 * Units.feet vertical.root_chord = 5.7 * Units.feet vertical.tip_chord = 2.0 * Units.feet vertical.sweep_le = 40.2 * Units.deg vertical.x_root_LE1 = 22.62 * Units.feet vertical.symmetric = False dz_centerline = 2.9 * Units.feet ref_vertical = extend_to_ref_area(vertical,dz_centerline) vertical.span = ref_vertical.ref_span vertical.area = ref_vertical.ref_area vertical.aspect_ratio = ref_vertical.ref_aspect_ratio vertical.x_root_LE = vertical.x_root_LE1 + ref_vertical.root_LE_change vertical.taper = vertical.tip_chord/ref_vertical.ref_root_chord vertical.effective_aspect_ratio = 2.65 vertical.x_ac_LE = trapezoid_ac_x(vertical) aircraft = SUAVE.Vehicle() aircraft.wing = wing aircraft.fuselage = fuselage aircraft.other_bodies = other_bodies aircraft.vertical = vertical aircraft.Mass_Props.pos_cg[0] = 16.6 * Units.feet segment = SUAVE.Analyses.Mission.Segments.Base_Segment() segment.M = 0.111 segment.atmosphere = SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976() altitude = 0.0 * Units.feet segment.a = segment.atmosphere.compute_values(altitude / Units.km, type="a") segment.rho = segment.atmosphere.compute_values(altitude / Units.km, type="rho") segment.mew = segment.atmosphere.compute_values(altitude / Units.km, type="mew") segment.v_inf = segment.M * segment.a #Method Test print 'SIAI Marchetti S-211 at M = {0} and h = {1} meters'.format(segment.M, altitude) cn_b = taw_cnbeta(aircraft,segment) expected = 0.160 print 'Cn_beta = {0:.4f}'.format(cn_b) print 'Expected value = {}'.format(expected) print 'Percent Error = {0:.2f}%'.format(100.0*(cn_b-expected)/expected) print ' '""" for k,v in error.items(): assert(np.abs(v)<0.1) return
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'Main Wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.sweep = 42.0 * Units.deg # Leading edge wing.taper = 14.7/54.5 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.origin = np.array([58.6,0,0]) * Units.feet wing.aerodynamic_center = np.array([112., 0. , 0. ]) * Units.feet- wing.origin wing.eta = 1.0 wing.downwash_adj = 1.0 wing.ep_alpha = 1. - wing.downwash_adj Mach = np.array([0.198]) reference = SUAVE.Structure.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) lifting_surfaces = [] lifting_surfaces.append(wing) wing = SUAVE.Components.Wings.Wing() wing.tag = 'Horizontal Stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweep = 44.0 * Units.deg # leading edge wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([187.0,0,0]) * Units.feet wing.symmetric= True wing.eta = 0.95 wing.downwash_adj = 1.0 - 2.0*vehicle.wings['Main Wing'].CL_alpha/np.pi/wing.aspect_ratio wing.ep_alpha = 1. - wing.downwash_adj wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] - wing.origin wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) lifting_surfaces.append(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'Fuselage' fuselage.x_root_quarter_chord = 77.0 * Units.feet fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([112.,0,0]) * Units.feet #Method Test cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = 0.93 # Should be -1.45 error = Data() error.cm_a_747 = (cm_a - expected)/expected #Parameters Required #Using values for a Beech 99 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'Main Wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.sweep = 3.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.origin = np.array([14.0,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0. , 0. ]) - wing.origin wing.eta = 1.0 wing.downwash_adj = 1.0 wing.ep_alpha = 1. - wing.downwash_adj Mach = np.array([0.152]) reference = SUAVE.Structure.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) lifting_surfaces = [] lifting_surfaces.append(wing) wing = SUAVE.Components.Wings.Wing() wing.tag = 'Horizontal Stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweep = 21 * Units.deg # leading edge wing.taper = 3.1/6.17 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([36.3,0,0]) * Units.feet wing.symmetric= True wing.eta = 0.95 wing.downwash_adj = 1.0 - 2.0*vehicle.wings['Main Wing'].CL_alpha/np.pi/wing.aspect_ratio wing.ep_alpha = 1. - wing.downwash_adj wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] - wing.origin wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) lifting_surfaces.append(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'Fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([17.2,0,0]) * Units.feet #Method Test cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = 12.57 # Should be -2.08 error.cm_a_beech_99 = (cm_a - expected)/expected #Parameters Required #Using values for an SIAI Marchetti S-211 vehicle = SUAVE.Vehicle() wing = SUAVE.Components.Wings.Wing() wing.tag = 'Main Wing' wing.areas.reference = 136.0 * Units.feet**2 wing.spans.projected = 26.3 * Units.feet wing.chords.mean_aerodynamic = 5.4 * Units.feet wing.sweep = 195 * Units.deg # Leading edge wing.taper = 3.1/7.03 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.origin = np.array([12.11,0,0]) * Units.feet wing.aerodynamic_center = np.array([16.6, 0. , 0. ]) - wing.origin wing.eta = 1.0 wing.downwash_adj = 1.0 wing.ep_alpha = 1. - wing.downwash_adj Mach = np.array([0.111]) reference = SUAVE.Structure.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) lifting_surfaces = [] lifting_surfaces.append(wing) wing = SUAVE.Components.Wings.Wing() wing.tag = 'Horizontal Stabilizer' wing.areas.reference = 36.46 * Units.feet**2 wing.spans.projected = 13.3 * Units.feet wing.sweep = 18.5 * Units.deg # leading edge wing.taper = 1.6/3.88 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([26.07,0.,0.]) * Units.feet wing.symmetric= True wing.eta = 0.9 wing.downwash_adj = 1.0 - 2.0*vehicle.wings['Main Wing'].CL_alpha/np.pi/wing.aspect_ratio wing.ep_alpha = 1. - wing.downwash_adj wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] - wing.origin wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) lifting_surfaces.append(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'Fuselage' fuselage.x_root_quarter_chord = 12.67 * Units.feet fuselage.lengths.total = 30.9 * Units.feet fuselage.width = ((2.94+5.9)/2) * Units.feet vehicle.append_component(fuselage) configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = Data() configuration.mass_properties.center_of_gravity = np.array([16.6,0,0]) * Units.feet #Method Test cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = -27.9 # should be -0.6 error.cm_a_SIAI = (cm_a - expected)/expected for k,v in error.items(): assert(np.abs(v)<0.005) return
def main(): #Parameters Required #Using values for a Boeing 747-200 vehicle = SUAVE.Vehicle() #print vehicle vehicle.mass_properties.max_zero_fuel=238780*Units.kg vehicle.mass_properties.max_takeoff =785000.*Units.lbs wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.sweeps.quarter_chord = 42.0 * Units.deg # Leading edge wing.sweeps.leading_edge = 42.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 14.7/42.9 #14.7/54.5 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([58.6,0,0]) * Units.feet wing.aerodynamic_center = np.array([112.2*Units.feet,0.,0.])-wing.origin#16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.198]) conditions = Data() conditions.weights = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweeps.quarter_chord = 44.0 * Units.deg # leading edge wing.sweeps.leading_edge = 44.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([187.0,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 77.0 * Units.feet fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity=np.array([112.2,0,0]) * Units.feet #configuration.mass_properties.zero_fuel_center_of_gravity=np.array([76.5,0,0])*Units.feet #just put a number here that got the expected value output; may want to change fuel =SUAVE.Components.Physical_Component() fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel =vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected =-1.56222373 #Should be -1.45 error = Data() error.cm_a_747 = (cm_a - expected)/expected #Parameters Required #Using values for a Beech 99 vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff =4727*Units.kg #from Wikipedia vehicle.mass_properties.empty =2515*Units.kg vehicle.mass_properties.max_zero_fuel=vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+15.*225*Units.lbs #15 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 280.0 * Units.feet**2 wing.spans.projected = 46.0 * Units.feet wing.chords.mean_aerodynamic = 6.5 * Units.feet wing.chords.root = 7.9 * Units.feet wing.sweeps.leading_edge = 4.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 4.0 * Units.deg # Leading edge wing.taper = 0.47 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([15.,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0. , 0. ]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.152]) reference = SUAVE.Core.Container() conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights=Data() conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 100.5 * Units.feet**2 wing.spans.projected = 22.5 * Units.feet wing.sweeps.leading_edge = 21.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.sweeps.quarter_chord = 21.0 * Units.deg # leading edge wing.taper = 3.1/6.17 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([36.3,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 5.4 * Units.feet fuselage.lengths.total = 44.0 * Units.feet fuselage.width = 5.4 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([17.2,0,0]) * Units.feet fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel = vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #Method Test #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = -2.48843437 #Should be -2.08 error.cm_a_beech_99 = (cm_a - expected)/expected #Parameters Required #Using values for an SIAI Marchetti S-211 vehicle = SUAVE.Vehicle() vehicle.mass_properties.max_takeoff =2750*Units.kg #from Wikipedia vehicle.mass_properties.empty =1850*Units.kg vehicle.mass_properties.max_zero_fuel=vehicle.mass_properties.max_takeoff-vehicle.mass_properties.empty+2.*225*Units.lbs #2 passenger ac wing = SUAVE.Components.Wings.Wing() wing.tag = 'main_wing' wing.areas.reference = 136.0 * Units.feet**2 wing.spans.projected = 26.3 * Units.feet wing.chords.mean_aerodynamic = 5.4 * Units.feet wing.chords.root = 7.03 * Units.feet wing.chords.tip = 3.1 * Units.feet wing.sweeps.quarter_chord = 19.5 * Units.deg # Leading edge wing.sweeps.leading_edge = 19.5 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 3.1/7.03 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([13.5,0,0]) * Units.feet wing.aerodynamic_center = np.array([trapezoid_ac_x(wing),0.,0.])#16.6, 0. , 0. ]) * Units.feet - wing.origin wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.111]) conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights=Data() conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 36.46 * Units.feet**2 wing.spans.projected = 13.3 * Units.feet wing.sweeps.quarter_chord= 18.5 * Units.deg # leading edge wing.sweeps.leading_edge = 18.5 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 1.6/3.88 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([26.07,0.,0.]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.9 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.CL_alpha = datcom(wing,Mach) span_location_mac =compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset =.8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0]=.3*wing.chords.mean_aerodynamic+mac_le_offset vehicle.append_component(wing) fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.x_root_quarter_chord = 12.67 * Units.feet fuselage.lengths.total = 30.9 * Units.feet fuselage.width = ((2.94+5.9)/2) * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([16.6,0,0]) * Units.feet fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) #now define configuration for calculation configuration = Data() configuration.mass_properties = Data() configuration.mass_properties.center_of_gravity = vehicle.mass_properties.center_of_gravity configuration.mass_properties.max_zero_fuel = vehicle.mass_properties.max_zero_fuel configuration.fuel =fuel configuration.mass_properties.zero_fuel_center_of_gravity=sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel #Method Test #print configuration cm_a = taw_cmalpha(vehicle,Mach,conditions,configuration) expected = -0.54071741 #Should be -0.6 error.cm_a_SIAI = (cm_a - expected)/expected print error for k,v in error.items(): assert(np.abs(v)<0.01) return
def __call__(self,conditions): """ process vehicle to setup geometry, condititon and configuration Inputs: conditions - DataDict() of aerodynamic conditions results - DataDict() of Outputs: Assumptions: """ # unpack configuration = self.configuration geometry = self.geometry stability_model = self.stability_model q = conditions.freestream.dynamic_pressure Sref = geometry.reference_area mach = conditions.freestream.mach_number velocity = conditions.freestream.velocity density = conditions.freestream.density Span = geometry.wings['main_wing'].spans.projected mac = geometry.wings['main_wing'].chords.mean_aerodynamic aero = conditions.aerodynamics # set up data structures static_stability = Data() dynamic_stability = Data() # Calculate CL_alpha if not conditions.has_key('lift_curve_slope'): conditions.lift_curve_slope = datcom(geometry.wings['main_wing'],mach) # Calculate change in downwash with respect to change in angle of attack for surf in geometry.wings: sref = surf.areas.reference span = (surf.aspect_ratio * sref ) ** 0.5 surf.CL_alpha = datcom(surf,mach) surf.ep_alpha = Supporting_Functions.ep_alpha(surf.CL_alpha, sref, span) # Static Stability Methods static_stability.cm_alpha = taw_cmalpha(geometry,mach,conditions,configuration) static_stability.cn_beta = taw_cnbeta(geometry,conditions,configuration) # Dynamic Stability if np.count_nonzero(configuration.mass_properties.moments_of_inertia.tensor) > 0: # Dynamic Stability Approximation Methods - valid for non-zero I tensor # Derivative of yawing moment with respect to the rate of yaw cDw = aero.drag_breakdown.parasite['main_wing'].parasite_drag_coefficient # Might not be the correct value l_v = geometry.wings['vertical_stabilizer'].origin[0] + geometry.wings['vertical_stabilizer'].aerodynamic_center[0] - geometry.wings['main_wing'].origin[0] - geometry.wings['main_wing'].aerodynamic_center[0] dynamic_stability.cn_r = Supporting_Functions.cn_r(cDw, geometry.wings['vertical_stabilizer'].areas.reference, Sref, l_v, span, geometry.wings['vertical_stabilizer'].dynamic_pressure_ratio, geometry.wings['vertical_stabilizer'].CL_alpha) # Derivative of rolling moment with respect to roll rate dynamic_stability.cl_p = 0 # Need to see if there is a low fidelity way to calculate cl_p # Derivative of roll rate with respect to sideslip (dihedral effect) dynamic_stability.cl_beta = 0 # Need to see if there is a low fidelity way to calculate cl_beta # Derivative of pitching moment with respect to pitch rate l_t = geometry.wings['horizontal_stabilizer'].origin[0] + geometry.wings['horizontal_stabilizer'].aerodynamic_center[0] - geometry.wings['main_wing'].origin[0] - geometry.wings['main_wing'].aerodynamic_center[0] #Need to check this is the length of the horizontal tail moment arm dynamic_stability.cm_q = Supporting_Functions.cm_q(conditions.lift_curve_slope, l_t,mac) # Need to check Cm_i versus Cm_alpha # Derivative of pitching rate with respect to d(alpha)/d(t) dynamic_stability.cm_alpha_dot = Supporting_Functions.cm_alphadot(static_stability.cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha, l_t, mac) # Need to check Cm_i versus Cm_alpha # Derivative of Z-axis force with respect to angle of attack dynamic_stability.cz_alpha = Supporting_Functions.cz_alpha(aero.drag_coefficient,conditions.lift_curve_slope) stability_model.dutch_roll = Approximations.dutch_roll(velocity, static_stability.cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], dynamic_stability.cn_r) if dynamic_stability.cl_p != 0: stability_model.roll_tau = Approximations.roll(configuration.mass_properties.momen[2][2], Sref, density, velocity, Span, dynamic_stability.cl_p) dynamic_stability.cy_phi = Supporting_Functions.cy_phi(aero.lift_coefficient) dynamic_stability.cl_r = Supporting_Functions.cl_r( aero.lift_coefficient) # Will need to be changed stability_model.spiral_tau = Approximations.spiral(conditions.weights.total_mass, velocity, density, Sref, dynamic_stability.cl_p, static_stability.cn_beta, dynamic_stability.cy_phi, dynamic_stability.cl_beta, dynamic_stability.cn_r, dynamic_stability.cl_r) stability_model.short_period = Approximations.short_period(velocity, density, Sref, mac, dynamic_stability.cm_q, dynamic_stability.cz_alpha, conditions.weights.total_mass, static_stability.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1][1], dynamic_stability.cm_alpha_dot) stability_model.phugoid = Approximations.phugoid(conditions.freestream.gravity, conditions.freestream.velocity, aero.drag_coefficient, aero.lift_coefficient) # Dynamic Stability Full Linearized Methods if aero.has_key('cy_beta') and dynamic_stability.cl_p != 0 and dynamic_stability.cl_beta != 0: theta = conditions.frames.wind.body_rotations[:,1] dynamic_stability.cy_beta = aero.cy_beta dynamic_stability.cl_psi = Supporting_Functions.cy_psi(aero.lift_coefficient, theta) dynamic_stability.cL_u = 0 dynamic_stability.cz_u = Supporting_Functions.cz_u(aero.lift_coefficient,velocity,dynamic_stability.cL_u) dynamic_stability.cz_alpha_dot = Supporting_Functions.cz_alphadot(static_stability.cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha) dynamic_stability.cz_q = Supporting_Functions.cz_q(static_stability.cm_alpha) dynamic_stability.cx_u = Supporting_Functions.cx_u(aero.drag_coefficient) dynamic_stability.cx_alpha = Supporting_Functions.cx_alpha(aero.lift_coefficient, conditions.lift_curve_slope) lateral_directional = Full_Linearized_Equations.lateral_directional(velocity, static_stability.cn_beta , Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], dynamic_stability.cn_r, configuration.mass_properties.Moments_Of_Inertia.tensor[0][0], dynamic_stability.cl_p, configuration.mass_properties.moments_of_inertia.tensor[0][2], dynamic_stability.cl_r, dynamic_stability.cl_beta, dynamic_stability.cn_p, dynamic_stability.cy_phi, dynamic_stability.cy_psi, dynamic_stability.cy_beta, conditions.weights.total_mass) longitudinal = Full_Linearized_Equations.longitudinal(velocity, density, Sref, mac, dynamic_stability.cm_q, dynamic_stability.cz_alpha, conditions.weights.total_mass, static_stability.cm_alpha, configuration.mass_properties.moments_of_inertia.tensor[1][1], dynamic_stability.cm_alpha_dot, dynamic_stability.cz_u, dynamic_stability.cz_alpha_dot, dynamic_stability.cz_q, -aero.lift_coefficient, theta, dynamic_stability.cx_u, dynamic_stability.cx_alpha) stability_model.dutch_roll.natural_frequency = lateral_directional.dutch_natural_frequency stability_model.dutch_roll.damping_ratio = lateral_directional.dutch_damping_ratio stability_model.spiral_tau = lateral_directional.spiral_tau stability_model.roll_tau = lateral_directional.roll_tau stability_model.short_period.natural_frequency = longitudinal.short_natural_frequency stability_model.short_period.damping_ratio = longitudinal.short_damping_ratio stability_model.phugoid.natural_frequency = longitudinal.phugoid_natural_frequency stability_model.phugoid.damping_ratio = longitudinal.phugoid_damping_ratio # pack results results = Data() results.static = static_stability results.dynamic = dynamic_stability return results
def vehicle_setup(): vehicle = SUAVE.Vehicle() #print vehicle vehicle.mass_properties.max_zero_fuel = 238780 * Units.kg vehicle.mass_properties.max_takeoff = 785000. * Units.lbs # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.chords.tip = 14.7 * Units.feet wing.sweeps.quarter_chord = 42.0 * Units.deg # Leading edge wing.sweeps.leading_edge = 42.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([58.6, 0, 3.6]) * Units.feet wing.aerodynamic_center = np.array([ 112.2 * Units.feet, 0., 0. ]) - wing.origin #16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac = compute_span_location_from_chord_length( wing, wing.chords.mean_aerodynamic) mac_le_offset = .8 * np.sin( wing.sweeps.leading_edge ) * span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[ 0] = .3 * wing.chords.mean_aerodynamic + mac_le_offset Mach = np.array([0.198]) conditions = Data() conditions.weights = Data() conditions.lift_curve_slope = datcom(wing, Mach) conditions.weights.total_mass = np.array( [[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55 * Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweeps.quarter_chord = 44.0 * Units.deg # leading edge wing.sweeps.leading_edge = 44.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 7.5 / 32.6 wing.aspect_ratio = wing.spans.projected**2 / wing.areas.reference wing.origin = np.array([187.0, 0, 0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0 * main_wing_CLa / np.pi / main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing, Mach) vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' wing.spans.exposed = 32.4 * Units.feet wing.chords.root = 38.7 * Units.feet # vertical.chords.fuselage_intersect wing.chords.tip = 13.4 * Units.feet wing.sweeps.quarter_chord = 50.0 * Units.deg # Leading Edge wing.x_root_LE1 = 180.0 * Units.feet wing.symmetric = False wing.exposed_root_chord_offset = 13.3 * Units.feet wing = extend_to_ref_area(wing) wing.areas.reference = wing.extended.areas.reference wing.spans.projected = wing.extended.spans.projected wing.chords.root = 14.9612585185 dx_LE_vert = wing.extended.root_LE_change wing.taper = 0.272993077083 wing.origin = np.array([wing.x_root_LE1 + dx_LE_vert, 0., 0.]) wing.aspect_ratio = (wing.spans.projected**2) / wing.areas.reference wing.effective_aspect_ratio = 2.2 wing.symmetric = False wing.aerodynamic_center = np.array([trapezoid_ac_x(wing), 0.0, 0.0]) wing.dynamic_pressure_ratio = .95 Mach = np.array([0.198]) wing.CL_alpha = 0. wing.ep_alpha = 0. vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.lengths.total = 229.7 * Units.feet fuselage.areas.side_projected = 4696.16 * Units.feet**2 #used for cnbeta fuselage.heights.maximum = 26.9 * Units.feet #used for cnbeta fuselage.heights.at_quarter_length = 26.0 * Units.feet #used for cnbeta fuselage.heights.at_three_quarters_length = 19.7 * Units.feet #used for cnbeta fuselage.heights.at_wing_root_quarter_chord = 23.8 * Units.feet #used for cnbeta fuselage.x_root_quarter_chord = 77.0 * Units.feet #used for cmalpha fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity = np.array([112.2, 0, 0 ]) * Units.feet #configuration.mass_properties.zero_fuel_center_of_gravity=np.array([76.5,0,0])*Units.feet #just put a number here that got the expected value output; may want to change fuel = SUAVE.Components.Physical_Component() fuel.origin = wing.origin fuel.mass_properties.center_of_gravity = wing.mass_properties.center_of_gravity fuel.mass_properties.mass = vehicle.mass_properties.max_takeoff - vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg = vehicle.mass_properties.center_of_gravity MTOW = vehicle.mass_properties.max_takeoff fuel_cg = fuel.origin + fuel.mass_properties.center_of_gravity fuel_mass = fuel.mass_properties.mass sum_moments_less_fuel = (cg * MTOW - fuel_cg * fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel / vehicle.mass_properties.max_zero_fuel return vehicle
def __call__(self, conditions): """ Process vehicle to setup geometry, condititon and configuration Assumptions: None Source: N/A Inputs: conditions - DataDict() of aerodynamic conditions results - DataDict() of moment coeffients and stability and body axis derivatives Outputs: None Properties Used: self.geometry """ # unpack configuration = self.configuration geometry = self.geometry q = conditions.freestream.dynamic_pressure Sref = geometry.reference_area mach = conditions.freestream.mach_number velocity = conditions.freestream.velocity density = conditions.freestream.density Span = geometry.wings['main_wing'].spans.projected mac = geometry.wings['main_wing'].chords.mean_aerodynamic aero = conditions.aerodynamics # set up data structures stability = Data() stability.static = Data() stability.dynamic = Data() # Calculate CL_alpha conditions.lift_curve_slope = datcom(geometry.wings['main_wing'], mach) # Calculate change in downwash with respect to change in angle of attack for surf in geometry.wings: sref = surf.areas.reference span = (surf.aspect_ratio * sref)**0.5 surf.CL_alpha = datcom(surf, mach) surf.ep_alpha = Supporting_Functions.ep_alpha( surf.CL_alpha, sref, span) # Static Stability Methods stability.static.Cm_alpha, stability.static.Cm0, stability.static.CM = taw_cmalpha( geometry, mach, conditions, configuration) if 'vertical_stabilizer' in geometry.wings: stability.static.Cn_beta = taw_cnbeta(geometry, conditions, configuration) else: stability.static.Cn_beta = np.zeros_like(mach) # calculate the static margin stability.static.static_margin = -stability.static.Cm_alpha / conditions.lift_curve_slope # Dynamic Stability if np.count_nonzero( configuration.mass_properties.moments_of_inertia.tensor) > 0: # Dynamic Stability Approximation Methods - valid for non-zero I tensor # Derivative of yawing moment with respect to the rate of yaw cDw = aero.drag_breakdown.parasite[ 'main_wing'].parasite_drag_coefficient # Might not be the correct value l_v = geometry.wings['vertical_stabilizer'].origin[ 0] + geometry.wings['vertical_stabilizer'].aerodynamic_center[ 0] - geometry.wings['main_wing'].origin[ 0] - geometry.wings['main_wing'].aerodynamic_center[0] stability.static.Cn_r = Supporting_Functions.cn_r( cDw, geometry.wings['vertical_stabilizer'].areas.reference, Sref, l_v, span, geometry.wings['vertical_stabilizer'].dynamic_pressure_ratio, geometry.wings['vertical_stabilizer'].CL_alpha) # Derivative of rolling moment with respect to roll rate stability.static.Cl_p = Supporting_Functions.cl_p( conditions.lift_curve_slope, geometry) # Derivative of roll rate with respect to sideslip (dihedral effect) if 'dihedral' in geometry.wings['main_wing']: stability.static.Cl_beta = Supporting_Functions.cl_beta( geometry, stability.static.Cl_p) else: stability.static.Cl_beta = np.zeros(1) stability.static.Cy_beta = 0 # Derivative of pitching moment with respect to pitch rate l_t = geometry.wings['horizontal_stabilizer'].origin[ 0] + geometry.wings['horizontal_stabilizer'].aerodynamic_center[ 0] - geometry.wings['main_wing'].origin[ 0] - geometry.wings['main_wing'].aerodynamic_center[ 0] #Need to check this is the length of the horizontal tail moment arm stability.static.Cm_q = Supporting_Functions.cm_q( conditions.lift_curve_slope, l_t, mac) # Need to check Cm_i versus Cm_alpha # Derivative of pitching rate with respect to d(alpha)/d(t) stability.static.Cm_alpha_dot = Supporting_Functions.cm_alphadot( stability.static.Cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha, l_t, mac) # Need to check Cm_i versus Cm_alpha # Derivative of Z-axis force with respect to angle of attack stability.static.Cz_alpha = Supporting_Functions.cz_alpha( aero.drag_coefficient, conditions.lift_curve_slope) dutch_roll = Approximations.dutch_roll( velocity, stability.static.Cn_beta, Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], stability.static.Cn_r) stability.dynamic.dutchRollFreqHz = dutch_roll.natural_frequency stability.dynamic.dutchRollDamping = dutch_roll.damping_ratio if stability.static.Cl_p.all() != 0: stability.dynamic.rollSubsistenceTimeConstant = Approximations.roll( configuration.mass_properties.moments_of_inertia.tensor[2] [2], Sref, density, velocity, Span, stability.static.Cl_p) stability.static.Cy_phi = Supporting_Functions.cy_phi( aero.lift_coefficient) stability.static.Cl_r = Supporting_Functions.cl_r( aero.lift_coefficient) # Will need to be changed stability.dynamic.spiralSubsistenceTimeConstant = Approximations.spiral(conditions.weights.total_mass, velocity, density, Sref, stability.static.Cl_p, stability.static.Cn_beta, stability.static.Cy_phi,\ stability.static.Cl_beta, stability.static.Cn_r, stability.static.Cl_r) short_period_res = Approximations.short_period(velocity, density, Sref, mac, stability.static.Cm_q, stability.static.Cz_alpha, conditions.weights.total_mass, stability.static.Cm_alpha,\ configuration.mass_properties.moments_of_inertia.tensor[1][1], stability.static.Cm_alpha_dot) stability.dynamic.shortPeriodFreqHz = short_period_res.natural_frequency stability.dynamic.shortPeriodDamp = short_period_res.damping_ratio phugoid_res = Approximations.phugoid( conditions.freestream.gravity, conditions.freestream.velocity, aero.drag_coefficient, aero.lift_coefficient) stability.dynamic.phugoidFreqHz = phugoid_res.natural_frequency stability.dynamic.phugoidDamp = phugoid_res.damping_ratio # Dynamic Stability Full Linearized Methods if stability.static.Cy_beta != 0 and stability.static.Cl_p.all( ) != 0 and stability.static.Cl_beta.all() != 0: theta = conditions.frames.wind.body_rotations[:, 1] stability.static.Cy_psi = Supporting_Functions.cy_psi( aero.lift_coefficient, theta) stability.static.CL_u = 0 stability.static.Cz_u = Supporting_Functions.cz_u( aero.lift_coefficient, velocity, stability.static.cL_u) stability.static.Cz_alpha_dot = Supporting_Functions.cz_alphadot( stability.static.Cm_alpha, geometry.wings['horizontal_stabilizer'].ep_alpha) stability.static.Cz_q = Supporting_Functions.cz_q( stability.static.Cm_alpha) stability.static.Cx_u = Supporting_Functions.cx_u( aero.drag_coefficient) stability.static.Cx_alpha = Supporting_Functions.cx_alpha( aero.lift_coefficient, conditions.lift_curve_slope) lateral_directional = Full_Linearized_Equations.lateral_directional(velocity, stability.static.cn_beta , Sref, density, Span, configuration.mass_properties.moments_of_inertia.tensor[2][2], stability.static.Cn_r,\ configuration.mass_properties.moments_of_inertia.tensor[0][0], stability.static.Cl_p, configuration.mass_properties.moments_of_inertia.tensor[0][2], stability.static.Cl_r, stability.static.Cl_beta,\ stability.static.Cn_p, stability.static.Cy_phi, stability.static.Cy_psi, stability.static.Cy_beta, conditions.weights.total_mass) longitudinal = Full_Linearized_Equations.longitudinal(velocity, density, Sref, mac, stability.static.Cm_q, stability.static.Cz_alpha, conditions.weights.total_mass, stability.static.Cm_alpha, \ configuration.mass_properties.moments_of_inertia.tensor[1][1], stability.static.Cm_alpha_dot, stability.static.Cz_u, stability.static.Cz_alpha_dot, stability.static.Cz_q, -aero.lift_coefficient,\ theta, stability.static.Cx_u, stability.static.Cx_alpha) stability.dynamic.dutchRollFreqHz = lateral_directional.dutch_natural_frequency stability.dynamic.dutchRollDamping = lateral_directional.dutch_damping_ratio stability.dynamic.spiralSubsistenceTimeConstant = lateral_directional.spiral_tau stability.dynamic.rollSubsistenceTimeConstant = lateral_directional.roll_tau stability.dynamic.shortPeriodFreqHz = longitudinal.short_natural_frequency stability.dynamic.shortPeriodDamp = longitudinal.short_damping_ratio stability.dynamic.phugoidFreqHz = longitudinal.phugoid_natural_frequency stability.dynamic.phugoidDamp = longitudinal.phugoid_damping_ratio # pack results results = Data() results = stability return results
wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 44. * Units.feet #54.5ft wing.sweeps.leading_edge = 42.0 * Units.deg # Leading edge wing.taper = 13.85/44. #14.7/54.5 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([59.,0,0]) * Units.feet wing.aerodynamic_center = np.array([112.2*Units.feet,0.,0.])-wing.origin#16.16 * Units.meters,0.,0,])np.array([trapezoid_ac_x(wing),0., 0.])# wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 Mach = np.array([0.198]) conditions = Data() conditions.lift_curve_slope = datcom(wing,Mach) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweeps.leading_edge = 44.0 * Units.deg # leading edge wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([187.0,0,0]) * Units.feet
def __call__(self,conditions): """ process vehicle to setup geometry, condititon and configuration Inputs: conditions - DataDict() of aerodynamic conditions results - DataDict() of Outputs: Assumptions: """ # unpack configuration = self.configuration geometry = self.geometry q = conditions.freestream.dynamic_pressure Sref = geometry.reference_area mach = conditions.freestream.mach_number velocity = conditions.freestream.velocity density = conditions.freestream.density Span = geometry.Wings['Main Wing'].span mac = geometry.Wings['Main Wing'].chord_mac aero = conditions.aerodynamics # Calculate CL_alpha if not conditions.has_key('lift_curve_slope'): conditions.lift_curve_slope = (datcom(geometry.Wings['Main Wing'],mach)) # Calculate change in downwash with respect to change in angle of attack for surf in geometry.Wings: e = surf.e sref = surf.sref span = (surf.ar * sref ) ** 0.5 surf.CL_alpha = datcom(surf,mach) surf.ep_alpha = Supporting_Functions.ep_alpha(surf.CL_alpha, sref, span, e) # Static Stability Methods aero.cm_alpha = taw_cmalpha(geometry,mach,conditions,configuration) aero.cn_beta = taw_cnbeta(geometry,conditions,configuration) if np.count_nonzero(configuration.mass_props.I_cg) > 0: # Dynamic Stability Approximation Methods if not aero.has_key('cn_r'): cDw = aero.drag_breakdown.parasite['Main Wing'].parasite_drag_coefficient # Might not be the correct value l_v = geometry.Wings['Vertical Stabilizer'].origin[0] + geometry.Wings['Vertical Stabilizer'].aero_center[0] - geometry.Wings['Main Wing'].origin[0] - geometry.Wings['Main Wing'].aero_center[0] aero.cn_r = Supporting_Functions.cn_r(cDw, geometry.Wings['Vertical Stabilizer'].sref, Sref, l_v, span, geometry.Wings['Vertical Stabilizer'].eta, geometry.Wings['Vertical Stabilizer'].CL_alpha) if not aero.has_key('cl_p'): aero.cl_p = 0 # Need to see if there is a low fidelity way to calculate cl_p if not aero.has_key('cl_beta'): aero.cl_beta = 0 # Need to see if there is a low fidelity way to calculate cl_beta l_t = geometry.Wings['Horizontal Stabilizer'].origin[0] + geometry.Wings['Horizontal Stabilizer'].aero_center[0] - geometry.Wings['Main Wing'].origin[0] - geometry.Wings['Main Wing'].aero_center[0] #Need to check this is the length of the horizontal tail moment arm if not aero.has_key('cm_q'): aero.cm_q = Supporting_Functions.cm_q(conditions.lift_curve_slope, l_t,mac) # Need to check Cm_i versus Cm_alpha if not aero.has_key('cm_alpha_dot'): aero.cm_alpha_dot = Supporting_Functions.cm_alphadot(aero.cm_alpha, geometry.Wings['Horizontal Stabilizer'].ep_alpha, l_t, mac) # Need to check Cm_i versus Cm_alpha if not aero.has_key('cz_alpha'): aero.cz_alpha = Supporting_Functions.cz_alpha(aero.drag_coefficient,conditions.lift_curve_slope) conditions.dutch_roll = Approximations.dutch_roll(velocity, aero.cn_beta, Sref, density, Span, configuration.mass_props.I_cg[2][2], aero.cn_r) if aero.cl_p != 0: roll_tau = Approximations.roll(configuration.mass_props.I_cg[2][2], Sref, density, velocity, Span, aero.cl_p) if aero.cl_beta != 0: aero.cy_phi = Supporting_Functions.cy_phi(aero.lift_coefficient) aero.cl_r = Supporting_Functions.cl_r( aero.lift_coefficient) # Will need to be changed spiral_tau = Approximations.spiral(conditions.weights.total_mass, velocity, density, Sref, aero.cl_p, aero.cn_beta, aero.cy_phi, aero.cl_beta, aero.cn_r, aero.cl_r) conditions.short_period = Approximations.short_period(velocity, density, Sref, mac, aero.cm_q, aero.cz_alpha, conditions.weights.total_mass, aero.cm_alpha, configuration.mass_props.I_cg[1][1], aero.cm_alpha_dot) conditions.phugoid = Approximations.phugoid(conditions.freestream.gravity, conditions.freestream.velocity, aero.drag_coefficient, aero.lift_coefficient) # Dynamic Stability Full Linearized Methods if aero.has_key('cy_beta') and aero.cl_p != 0 and aero.cl_beta != 0: if not aero.has_key('cy_psi'): theta = conditions.frames.wind.body_rotations[:,1] aero.cl_psi = Supporting_Functions.cy_psi(aero.lift_coefficient, theta) if not aero.has_key('cz_u'): if not aero.has_key('cL_u'): aero.cL_u = 0 aero.cz_u = Supporting_Functions.cz_u(aero.lift_coefficient,velocity,aero.cL_u) if not aero.has_key('cz_alpha_dot'): aero.cz_alpha_dot = Supporting_Functions.cz_alphadot(aero.cm_alpha, geometry.Wings['Horizontal Stabilizer'].ep_alpha) if not aero.has_key('cz_q'): aero.cz_q = Supporting_Functions.cz_q(aero.cm_alpha) if not aero.has_key('cx_u'): aero.cx_u = Supporting_Functions.cx_u(aero.drag_coefficient) if not aero.has_key('cx_alpha'): aero.cx_alpha = Supporting_Functions.cx_alpha(aero.lift_coefficient, conditions.lift_curve_slope) lateral_directional = Full_Linearized_Equations.lateral_directional(velocity, aero.cn_beta , Sref, density, Span, configuration.mass_props.I_cg[2][2], aero.cn_r, configuration.mass_props.I_cg[0][0], aero.cl_p, configuration.mass_props.I_cg[0][2], aero.cl_r, aero.cl_beta, aero.cn_p, aero.cy_phi, aero.cy_psi, aero.cy_beta, conditions.weights.total_mass) longitudinal = Full_Linearized_Equations.longitudinal(velocity, density, Sref, mac, aero.cm_q, aero.cz_alpha, conditions.weights.total_mass, aero.cm_alpha, configuration.mass_props.I_cg[1][1], aero.cm_alpha_dot, aero.cz_u, aero.cz_alpha_dot, aero.cz_q, -aero.lift_coefficient, theta, aero.cx_u, aero.cx_alpha) return
def taw_cnbeta(geometry, conditions, configuration): """ CnBeta = SUAVE.Methods.Flight_Dynamics.Static_Stability.Approximations.Tube_Wing.taw_cnbeta(configuration,conditions) This method computes the static directional stability derivative for a standard Tube-and-Wing aircraft configuration. CAUTION: The correlations used in this method do not account for the destabilizing moments due to propellers. This can lead to higher-than- expected values of CnBeta, particularly for smaller prop-driven aircraft Inputs: geometry - aircraft geometrical features: a data dictionary with the fields: wings['Main Wing'] - the aircraft's main wing areas.reference - wing reference area [meters**2] spans.projected - span of the wing [meters] sweep - sweep of the wing leading edge [radians] aspect_ratio - wing aspect ratio [dimensionless] origin - the position of the wing root in the aircraft body frame [meters] wings['Vertical Stabilizer'] spans.projected - projected span (height for a vertical tail) of the exposed surface [meters] areas.reference - area of the reference vertical tail [meters**2] sweep - leading edge sweep of the aerodynamic surface [radians] chords.root - chord length at the junction between the tail and the fuselage [meters] chords.tip - chord length at the tip of the aerodynamic surface [meters] symmetric - Is the wing symmetric across the fuselage centerline? origin - the position of the vertical tail root in the aircraft body frame [meters] exposed_root_chord_offset - the displacement from the fuselage centerline to the exposed area's physical root chordline [meters] fuselages.Fuselage - a data dictionary with the fields: areas.side_projected - fuselage body side area [meters**2] lengths.total - length of the fuselage [meters] heights.maximum - maximum height of the fuselage [meters] width - maximum width of the fuselage [meters] heights.at_quarter_length - fuselage height at 1/4 of the fuselage length [meters] heights.at_three_quarters_length - fuselage height at 3/4 of fuselage length [meters] heights.at_vertical_root_quarter_chord - fuselage height at the quarter chord of the vertical tail root [meters] vertical - a data dictionary with the fields below: NOTE: This vertical tail geometry will be used to define a reference vertical tail that extends to the fuselage centerline. x_ac_LE - the x-coordinate of the vertical tail aerodynamic center measured relative to the tail root leading edge (root of reference tail area - at fuselage centerline) leading edge, relative to the nose [meters] sweep_le - leading edge sweep of the vertical tail [radians] span - height of the vertical tail [meters] taper - vertical tail taper ratio [dimensionless] aspect_ratio - vertical tail AR: bv/(Sv)^2 [dimensionless] effective_aspect_ratio - effective aspect ratio considering the effects of fuselage and horizontal tail [dimensionless] symmetric - indicates whether the vertical panel is symmetric about the fuselage centerline [Boolean] other_bodies - an list of data dictionaries containing bodies such as nacelles if these are large enough to strongly influence stability. Each body data dictionary contains the same fields as the fuselage data dictionary (described above), except no value is needed for 'height_at_vroot_quarter_chord'. CAN BE EMPTY LIST x_front - This is the only new field needed: the x-coordinate of the nose of the body relative to the fuselage nose conditions - a data dictionary with the fields: v_inf - true airspeed [meters/second] M - flight Mach number rho - air density [kg/meters**3] mew - air dynamic dynamic_viscosity [kg/meter/second] configuration - a data dictionary with the fields: mass_properties - a data dictionary with the field: center_of_gravity - A vector in 3-space indicating CG position [meters] other - a dictionary of aerodynamic bodies, other than the fuselage, whose effect on directional stability is to be included in the analysis Outputs: CnBeta - a single float value: The static directional stability derivative Assumptions: -Assumes a tube-and-wing configuration with a single centered vertical tail -Uses vertical tail effective aspect ratio, currently calculated by hand, using methods from USAF Stability and Control DATCOM -The validity of correlations for KN is questionable for sqrt(h1/h2) greater than about 4 or h_max/w_max outside [0.3,2]. -This method assumes a small angle of attack, so the vertical tail AC z-position does not affect the sideslip derivative. Correlations: -Correlations are taken from Roskam's Airplane Design, Part VI. """ try: configuration.other except AttributeError: configuration.other = 0 CnBeta_other = [] # Unpack inputs S = geometry.wings['main_wing'].areas.reference b = geometry.wings['main_wing'].spans.projected sweep = geometry.wings['main_wing'].sweeps.quarter_chord AR = geometry.wings['main_wing'].aspect_ratio z_w = geometry.wings['main_wing'].origin[2] S_bs = geometry.fuselages['fuselage'].areas.side_projected l_f = geometry.fuselages['fuselage'].lengths.total h_max = geometry.fuselages['fuselage'].heights.maximum w_max = geometry.fuselages['fuselage'].width h1 = geometry.fuselages['fuselage'].heights.at_quarter_length h2 = geometry.fuselages['fuselage'].heights.at_three_quarters_length d_i = geometry.fuselages['fuselage'].heights.at_wing_root_quarter_chord other = configuration.other vert = extend_to_ref_area(geometry.wings['vertical_stabilizer']) S_v = vert.extended.areas.reference x_v = vert.extended.origin[0] b_v = vert.extended.spans.projected ac_vLE = vert.aerodynamic_center[0] x_cg = configuration.mass_properties.center_of_gravity[0] v_inf = conditions.freestream.velocity mu = conditions.freestream.dynamic_viscosity rho = conditions.freestream.density M = conditions.freestream.mach_number #Compute wing contribution to Cn_beta CnBeta_w = 0.0 #The wing contribution is assumed to be zero except at very #high angles of attack. #Compute fuselage contribution to Cn_beta Re_fuse = rho * v_inf * l_f / mu x1 = x_cg / l_f x2 = l_f * l_f / S_bs x3 = np.sqrt(h1 / h2) x4 = h_max / w_max kN_1 = 3.2413 * x1 - 0.663345 + 6.1086 * np.exp(-0.22 * x2) kN_2 = (-0.2023 + 1.3422 * x3 - 0.1454 * x3 * x3) * kN_1 kN_3 = (0.7870 + 0.1038 * x4 + 0.1834 * x4 * x4 - 2.811 * np.exp(-4.0 * x4)) K_N = (-0.47899 + kN_3 * kN_2) * 0.001 K_Rel = 1.0 + 0.8 * np.log(Re_fuse / 1.0E6) / np.log(50.) #K_Rel: Correction for fuselage Reynolds number. Roskam VI, page 400. CnBeta_f = -57.3 * K_N * K_Rel * S_bs * l_f / S / b #Compute contributions of other bodies on CnBeta if other > 0: for body in other: #Unpack inputs S_bs = body.areas.side_projected x_le = body.origin[0] l_b = body.lengths.total h_max = body.heights.maximum w_max = body.width h1 = body.heights.at_quarter_length h2 = body.heights.at_three_quarters_length #Compute body contribution to Cn_beta x_cg_on_body = (x_cg - x_le) / l_b Re_body = rho * v_inf * l_b / mew x1 = x_cg_on_body / l_b x2 = l_b * l_b / S_bs x3 = np.sqrt(h1 / h2) x4 = h_max / w_max kN_1 = 3.2413 * x1 - 0.663345 + 6.1086 * np.exp(-0.22 * x2) kN_2 = (-0.2023 + 1.3422 * x3 - 0.1454 * x3 * x3) * kN_1 kN_3 = (0.7870 + 0.1038 * x4 + 0.1834 * x4 * x4 - 2.811 * np.exp(-4.0 * x4)) K_N = (-0.47899 + kN_3 * kN_2) * 0.001 #K_Rel: Correction for fuselage Reynolds number. Roskam VI, page 400. K_Rel = 1.0 + 0.8 * np.log(Re_body / 1.0E6) / np.log(50.) CnBeta_b = -57.3 * K_N * K_Rel * S_bs * l_b / S / b CnBeta_other.append(CnBeta_b) #Compute vertical tail contribution l_v = x_v + ac_vLE - x_cg try: iter(M) except TypeError: M = [M] CLa_v = datcom(vert, M) #k_v correlated from Roskam Fig. 10.12. NOT SMOOTH. bf = b_v / d_i if bf < 2.0: k_v = 0.76 elif bf < 3.5: k_v = 0.76 + 0.24 * (bf - 2.0) / 1.5 else: k_v = 1.0 quarter_chord_sweep = convert_sweep(geometry.wings['main_wing']) k_sweep = (1.0 + np.cos(quarter_chord_sweep)) dsdb_e = 0.724 + 3.06 * ( (S_v / S) / k_sweep) + 0.4 * z_w / h_max + 0.009 * AR Cy_bv = -k_v * CLa_v * dsdb_e * (S_v / S) #ASSUMING SINGLE VERTICAL TAIL CnBeta_v = -Cy_bv * l_v / b CnBeta = CnBeta_w + CnBeta_f + CnBeta_v + sum(CnBeta_other) return CnBeta
def vehicle_setup(): vehicle = SUAVE.Vehicle() #print vehicle vehicle.mass_properties.max_zero_fuel=238780*Units.kg vehicle.mass_properties.max_takeoff =785000.*Units.lbs # ------------------------------------------------------------------ # Main Wing # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Main_Wing() wing.tag = 'main_wing' wing.areas.reference = 5500.0 * Units.feet**2 wing.spans.projected = 196.0 * Units.feet wing.chords.mean_aerodynamic = 27.3 * Units.feet wing.chords.root = 42.9 * Units.feet #54.5ft wing.chords.tip = 14.7 * Units.feet wing.sweeps.quarter_chord = 42.0 * Units.deg # Leading edge wing.sweeps.leading_edge = 42.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = wing.chords.tip / wing.chords.root wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.symmetric = True wing.vertical = False wing.origin = np.array([58.6,0,3.6]) * Units.feet wing.aerodynamic_center = np.array([112.2*Units.feet,0.,0.])-wing.origin#16.16 * Units.meters,0.,0,]) wing.dynamic_pressure_ratio = 1.0 wing.ep_alpha = 0.0 span_location_mac = compute_span_location_from_chord_length(wing, wing.chords.mean_aerodynamic) mac_le_offset = .8*np.sin(wing.sweeps.leading_edge)*span_location_mac #assume that 80% of the chord difference is from leading edge sweep wing.mass_properties.center_of_gravity[0] = .3*wing.chords.mean_aerodynamic+mac_le_offset Mach = np.array([0.198]) conditions = Data() conditions.weights = Data() conditions.lift_curve_slope = datcom(wing,Mach) conditions.weights.total_mass=np.array([[vehicle.mass_properties.max_takeoff]]) wing.CL_alpha = conditions.lift_curve_slope vehicle.reference_area = wing.areas.reference vehicle.append_component(wing) main_wing_CLa = wing.CL_alpha main_wing_ar = wing.aspect_ratio # ------------------------------------------------------------------ # Horizontal Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'horizontal_stabilizer' wing.areas.reference = 1490.55* Units.feet**2 wing.spans.projected = 71.6 * Units.feet wing.sweeps.quarter_chord = 44.0 * Units.deg # leading edge wing.sweeps.leading_edge = 44.0 * Units.deg # Same as the quarter chord sweep (ignore why EMB) wing.taper = 7.5/32.6 wing.aspect_ratio = wing.spans.projected**2/wing.areas.reference wing.origin = np.array([187.0,0,0]) * Units.feet wing.symmetric = True wing.vertical = False wing.dynamic_pressure_ratio = 0.95 wing.ep_alpha = 2.0*main_wing_CLa/np.pi/main_wing_ar wing.aerodynamic_center = [trapezoid_ac_x(wing), 0.0, 0.0] wing.CL_alpha = datcom(wing,Mach) vehicle.append_component(wing) # ------------------------------------------------------------------ # Vertical Stabilizer # ------------------------------------------------------------------ wing = SUAVE.Components.Wings.Wing() wing.tag = 'vertical_stabilizer' wing.spans.exposed = 32.4 * Units.feet wing.chords.root = 38.7 * Units.feet # vertical.chords.fuselage_intersect wing.chords.tip = 13.4 * Units.feet wing.sweeps.quarter_chord = 50.0 * Units.deg # Leading Edge wing.x_root_LE1 = 180.0 * Units.feet wing.symmetric = False wing.exposed_root_chord_offset = 13.3 * Units.feet wing = extend_to_ref_area(wing) wing.areas.reference = wing.extended.areas.reference wing.spans.projected = wing.extended.spans.projected wing.chords.root = 14.9612585185 dx_LE_vert = wing.extended.root_LE_change wing.taper = 0.272993077083 wing.origin = np.array([wing.x_root_LE1 + dx_LE_vert,0.,0.]) wing.aspect_ratio = (wing.spans.projected**2)/wing.areas.reference wing.effective_aspect_ratio = 2.2 wing.symmetric = False wing.aerodynamic_center = np.array([trapezoid_ac_x(wing),0.0,0.0]) wing.dynamic_pressure_ratio = .95 Mach = np.array([0.198]) wing.CL_alpha = 0. wing.ep_alpha = 0. vehicle.append_component(wing) # ------------------------------------------------------------------ # Fuselage # ------------------------------------------------------------------ fuselage = SUAVE.Components.Fuselages.Fuselage() fuselage.tag = 'fuselage' fuselage.lengths.total = 229.7 * Units.feet fuselage.areas.side_projected = 4696.16 * Units.feet**2 #used for cnbeta fuselage.heights.maximum = 26.9 * Units.feet #used for cnbeta fuselage.heights.at_quarter_length = 26.0 * Units.feet #used for cnbeta fuselage.heights.at_three_quarters_length = 19.7 * Units.feet #used for cnbeta fuselage.heights.at_wing_root_quarter_chord = 23.8 * Units.feet #used for cnbeta fuselage.x_root_quarter_chord = 77.0 * Units.feet #used for cmalpha fuselage.lengths.total = 229.7 * Units.feet fuselage.width = 20.9 * Units.feet vehicle.append_component(fuselage) vehicle.mass_properties.center_of_gravity=np.array([112.2,0,0]) * Units.feet #configuration.mass_properties.zero_fuel_center_of_gravity=np.array([76.5,0,0])*Units.feet #just put a number here that got the expected value output; may want to change fuel =SUAVE.Components.Physical_Component() fuel.origin =wing.origin fuel.mass_properties.center_of_gravity =wing.mass_properties.center_of_gravity fuel.mass_properties.mass =vehicle.mass_properties.max_takeoff-vehicle.mass_properties.max_zero_fuel #find zero_fuel_center_of_gravity cg =vehicle.mass_properties.center_of_gravity MTOW =vehicle.mass_properties.max_takeoff fuel_cg =fuel.origin+fuel.mass_properties.center_of_gravity fuel_mass =fuel.mass_properties.mass sum_moments_less_fuel=(cg*MTOW-fuel_cg*fuel_mass) vehicle.fuel = fuel vehicle.mass_properties.zero_fuel_center_of_gravity = sum_moments_less_fuel/vehicle.mass_properties.max_zero_fuel return vehicle