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 __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 __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
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 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 __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