def example1():
    # run trim analysis
    import aircraft
    ac = aircraft.load('V0510')
    fc = flightConditions()
    CG = numpy.array([1.7,0,0])
    I = numpy.array([500., 1000, 1000])
    M = 600.
    V = 50.
    density = 1.2255
    Cd0 = ac.get_drag(V,0.0)
    fc.addTrimmedFlightCondition('cruise1',M,CG,I,V,density,CmTrim=0.0,Cd0=Cd0)
    a3d = aero3d_VLM(ac)
    rslt = a3d.runVLM(fc,False)
    print 'GENERAL'
    rslt.results[0].display()
    print 'PHUGOID'
    rslt.results[0].dynamicStability.phugoid.display()
    print 'SHORT PERIOD'
    rslt.results[0].dynamicStability.shortPeriod.display()
    print 'DUTCH ROLL'
    rslt.results[0].dynamicStability.dutchRoll.display()
    print 'SPIRAL'
    rslt.results[0].dynamicStability.spiral.display()
    print 'ROLL'
    rslt.results[0].dynamicStability.roll.display()
def calc_hinges():
    import aircraft
    ac = aircraft.load('V0510')
    fc = flightConditions()
    CG = [1.824,0.0,-0.125]
    I = ac.get_inertia()
    m = 620.0
    V = 75.0
    rho = 1.2255
    CD0 = ac.get_drag(V,0.0)
    n = 1.0
    fc.add_flight_condition('hinge',m,CG,I,V,rho,n,CD0,alpha=20.0,elevator=30.0)
    aero3d = aero3d_VLM(ac)
    rslt = aero3d.runVLM(fc)
    rslt.results[0].hingeMoments.display()
def run_test():
    import aircraft
    ac = aircraft.load('V0510')
    fc = flightConditions()
    CG = ac.get_CG(False)
    I = ac.get_inertia(False)
    M = ac.get_mass_total(False)
    V = 1.0
    rho = 1.2255
    Cd0 = ac.get_drag(V,0.0)
    fc.addTrimmedFlightCondition('trim',M, CG, I, V, rho)
    fc.flightConditionList[0].setRudder(0.)
    aero3D = aero3d_VLM(ac)
    rslt = aero3D.runVLM(fc)
    rslt.results[0].display()
 def add_flight_condition(self,name,mass,CG,inertia,velocity,density,
                          loadFactor=1.0,CD0=0.0,alpha=0.0,beta=0.0,flap=0.0
                          ,elevator=0.0,aileron=0.0,rudder=0.0):
     """
     Non trimmed flight conditions
     """
     newFC                      =self._flightCondition()
     newFC.pitchTrim            =False
     newFC.CG                   =CG
     newFC.name                 =name
     newFC.mass                 =float(mass)
     newFC.inertia              =inertia   
     newFC.velocity             =float(velocity)
     newFC.density              =float(density)
     newFC.densityAltitude      =fc.get_density_altitude(newFC.density)
     atm                        =fc.ISAtmosphere(newFC.densityAltitude,0.0)
     newFC.soundSpeed           =atm.soundSpeed
     newFC.pressure             =atm.pressure
     newFC.temperature          =atm.temperature
     newFC.Mach                 =newFC.velocity/newFC.soundSpeed
     newFC.loadFactor           =loadFactor
     newFC.Cd0                  =CD0
     newFC.alpha                =alpha
     newFC.beta                 =beta
     newFC.flap                 =flap
     newFC.elevator             =elevator
     newFC.aileron              =aileron
     newFC.rudder               =rudder
     self.flightConditionList.append(newFC)
Exemple #5
0
 def run_climbRate(self,airspeed,powerSetting):
     """
     Calculates the climb rate at a given airspeed and power setting.
     Supports descent calculations which will appear as negative climb
     rates. Does not utilize small angle approximations.
     """
     basicInput = self.bi
     thrustModule = self.tm
     V       =airspeed
     rho     =basicInput.density
     Cd0     =basicInput.Cd0
     g       =basicInput.g
     k       =basicInput.k
     S       =basicInput.refArea
     W       =basicInput.mass*g
     Q       =0.5*rho*V*V
     tol     =1.0e-4
     change  =tol+1.0
     CA      =0.0 #climb angle, rad
     iMax    =100
     i       =0
     if powerSetting>=5.0:
         tm=thrustModule.runAnalysis
     else:
         tm=thrustModule._zeroThrustModule
     while change>tol and i<=iMax:            
         tm(V,rho,powerSetting)
         T  =thrustModule.thrust
         L  =W*np.cos(CA)-T*np.sin(CA)
         Cl =L/Q/S
         Cd =Cd0+k*Cl*Cl
         D  =Q*S*Cd
         PR =D*V
         PA =T*V
         RC =(PA-PR)/W
         ca =CA
         CA =np.arcsin(RC/V)
         change=np.abs(ca-CA)
         i+=1
     self.__init__(self.bi, self.tm)
     self.velocity          =V
     self.equivalentAirspeed=self.EAS(V,basicInput.density)
     self.densityAltitude   =fc.get_density_altitude(basicInput.density)
     self.density           =basicInput.density
     self.climbRate         =RC
     self.climbAngle        =CA
     self.fuelFlow          =thrustModule.fuelFlow
     self.RPM               =thrustModule.RPM
     self.powerSetting      =powerSetting
     self.thrust            =T
     self.power             =PA
     self.propEfficiency    =thrustModule.propEfficiency
     self.beta              =thrustModule.beta
     self.SAR_km_per_kg     =thrustModule.SAR_km_per_kg
     self.lift              =L
     self.drag              =D
     self.L_D               =L/D   
     self.turnRadius        =0.0
     self.bankAngle         =0.0
     self.loadFactor        =1.0
 def addTrimmedFlightCondition(self,name,mass,CG,inertia,velocity,density,
                               loadFactor=1.0,Cd0=0.0,CmTrim=0.0,flapDefl=0.0,
                               aileron=0.0,rudder=0.0):
     """
     Sets and stores a list of flight conditions to be analyzed by the
     aerodynamics solvers.
     
     Parameters
     ----------
     
     name : string
         name of the flight condition case
     mass : float, kg
         total mass of the aircraft
     CG : float array, m
         array of CG coordinates [x,y,z]
     inertia : float array
         array of moments of inertia [Ixx, Iyy, Izz]
     velocity : float, m/sec
         aircraft TAS
     density : float, kg/m**3
         atmospheric density
     loadFactor : float
         load factor for steady pull-out flight conditions
     Cd0 : float
         zero lift drag coefficient of aircraft
     CmTrim : float
         trim pitch moment coefficient. Set CmTrim=None if non-trimmed flight 
         condition is required
     flapDefl : float, deg
         plain flap deflection angle
     """
     newFC                      =self._flightCondition()
     newFC.pitchTrim            =True
     newFC.CG                   =CG
     newFC.name                 =name
     newFC.mass                 =float(mass)
     newFC.inertia              =inertia   
     newFC.velocity             =float(velocity)
     newFC.density              =float(density)
     newFC.densityAltitude      =fc.get_density_altitude(newFC.density)
     atm                        =fc.ISAtmosphere(newFC.densityAltitude,0.0)
     newFC.soundSpeed           =atm.soundSpeed
     newFC.pressure             =atm.pressure
     newFC.temperature          =atm.temperature
     newFC.Mach                 =newFC.velocity/newFC.soundSpeed
     newFC.loadFactor           =loadFactor
     newFC.Cd0                  =Cd0
     newFC.CmTrim               =CmTrim
     newFC.flap                 =flapDefl
     newFC.aileron              =aileron
     newFC.rudder               =rudder
     self.flightConditionList.append(newFC)
def run_test3():
    import aircraft
    import matplotlib.pyplot as plt
    ac = aircraft.load('V0510')
    fc = flightConditions()
    CG = ac.get_CG()
    I = ac.get_inertia()
    m = ac.get_mass_total()
    V = 50.0
    rho = 1.2255
    CD0 = ac.get_drag(V,0.0)
    ail = [-10,0,2,5,7,10]
    ailDisp = list()
    r = 15
    for a in ail:
        fc.add_flight_condition('untrimmed',m,CG,I,V,rho,CD0=CD0,aileron=a,rudder=r)
        ailDisp.append(a)
    aero3d = aero3d_VLM(ac)
    rslt = aero3d.runVLM(fc)
    cl = [rslt.results[i].coefficients.Cl for i in range(len(ail))]
    plt.plot(ailDisp,cl,'ro-')
    plt.show()
 def update_notrim(self,velocity,density,loadFactor=1.0,flap=0.0,aileron=0.0,
                   elevator=0.0,rudder=0.0,alpha=0.0,beta=0.0,mass=None,
                   CG=None,inertia=None):
     """
     Performs aerodynamic analysis at specified flight conditions.
     
     Parameters
     ----------
     
     velocity : float, m/s
     density : float, kg/m**3
     loadFactor : float
     flap : float,deg
         flap deflection angle. Note that plain flap is analyzed, slotted flap 
         analysis is not available
     aileron : +float, deg
         aileron deflection angle. Deflection is mirrored.
     elevator : float, deg
         elevator deflection angle
     rudder : float, deg
         rudder deflection angle
     alpha : float, deg
         angle of attack. Note that solver may fail on high angles of attack. 
         Use values [-5;5].
     beta : float, deg
         sideslip angle.
     mass : float, kg
         if mass is not defined, than it will be obtained from current 
         aircraft configuration
     CG : float vector, m
         aircraft center of gravity in format [x,y,z]. 
         If CG is not defined it will be obtained from current aircraft configuration
     inertia : float vector, kg*m**2
         aircraft moment of inertia in format [Ixx,Iyy,Izz].
     """
     if mass==None:
         mass = self.aircraft.get_mass_total()
     if CG==None:
         CG = self.aircraft.get_CG()
     if inertia==None:
         inertia = self.aircraft.get_inertia()
     altitude = fc.get_density_altitude(density)
     CD0 = self.aircraft.get_drag(velocity,altitude)
     flightCond = flightConditions()
     flightCond.add_flight_condition('untrimmed',mass,CG,inertia,velocity,density,
                             loadFactor,CD0,alpha,beta,flap,elevator,
                             aileron,rudder)
     vlm = aero3d_VLM(self.aircraft)
     out = vlm.runVLM(flightCond)
     return out.results[0]
 def getCd0(self,V,rho):
     """
     Executes AeroCD0 skin friction / form factor drag analysis code
     Returns parasite drag (Cd0)
     
     Parameters
     ----------
     
     V : float, m/sec
         velocity
     rho : float, kg/m**3
         density
     """
     alt = fc.get_density_altitude(rho)
     Cd0= self.aircraft.get_drag(V,alt)
     return Cd0
Exemple #10
0
 def _setAttributes(self,velocity):
     drag=self.requiredThrust(velocity)
     self.__init__(self.bi, self.tm)
     self.tm.matchRequiredThrust(velocity,self.bi.density,drag)
     self.velocity          =velocity
     self.equivalentAirspeed=self.get_EAS(velocity,self.bi.density)
     self.densityAltitude   =fc.get_density_altitude(self.bi.density)
     self.density           =self.bi.density
     self.fuelFlow          =self.tm.fuelFlow
     self.RPM               =self.tm.RPM
     self.powerSetting      =self.tm.powerSetting
     self.thrust            =self.tm.thrust
     self.power             =self.tm.power
     self.propEfficiency    =self.tm.propEfficiency
     self.beta              =self.tm.beta
     self.SAR_km_per_kg     =self.tm.SAR_km_per_kg
     self.drag              =drag
     self.lift              =self.bi.wt
     self.L_D               =self.lift/self.drag
Exemple #11
0
 def update(self,velocity,density,loadFactor=1.0,CmTrim=0.0,flapDefl=0.0,
            mass=None,CG=None,inertia=None,name='default'):
     """
     Updates aerodynamics results in self.results
     
     Parameters
     ----------
     
     velocity : float, m/sec
         aircraft TAS
     density : float, kg/m**3
         air density
     loadFactor : float
         load factor
     CmTrim : float
         trim pitch moment coefficient
     flapDefl : float, deg
         plain flap deflection
     """
     self.flightConditions =flightConditions()
     densityAltitude       =fc.get_density_altitude(density)
     if mass==None:
         mass                  =self.aircraft.get_mass_total()
     if CG==None:
         CG                    =self.aircraft.get_CG()
     if inertia==None:
         inertia               =self.aircraft.get_inertia()
     Cd0                   =self.aircraft.get_drag(velocity,densityAltitude)
     self.flightConditions.addTrimmedFlightCondition(name,mass,CG,inertia,velocity,density,loadFactor,Cd0,CmTrim,flapDefl)
     vlm                   =aero3d_VLM(self.aircraft)
     out                   =vlm.runVLM(self.flightConditions)
     self.results          =out.results[0]
     self.results.name = name
     NP = self.results.xNP
     self.results.SM = (NP-CG[0])/self.aircraft.wing.MAC
     self.results.mass = mass
     self.results.CG = CG
     self.results.inertia = inertia
     self.results.velocity = velocity
     self.results.density = density
Exemple #12
0
 def _setAttributes(self,n,airspeed,powerSetting):
     V                      =airspeed
     rho                    =self.bi.density
     Cd0                    =self.bi.Cd0
     g                      =self.bi.g
     k                      =self.bi.k
     S                      =self.bi.refArea
     W                      =self.bi.mass*g        
     Q                      =0.5*rho*V**2
     self.tm.runAnalysis(V,rho,powerSetting)
     phi                    =np.arccos(1./n)
     turnRadius             =V**2/(g*(n**2-1.)**.5)
     turnRate               =g*(n**2-1)**.5/V
     L                      =n*W
     Cl                     =L/Q/S
     Cd                     =Cd0+k*Cl**2
     D                      =Q*S*Cd
     self.tm.matchRequiredThrust(V,self.bi.density,D)
     self.__init__(self.bi,self.tm)
     self.velocity          =V
     self.equivalentAirspeed=self.EAS(V,self.bi.density)
     self.densityAltitude   =fc.get_density_altitude(self.bi.density)
     self.density           =self.bi.density
     self.fuelFlow          =self.tm.fuelFlow
     self.RPM               =self.tm.RPM   
     self.powerSetting      =powerSetting 
     self.thrust            =self.tm.thrust
     self.power             =self.tm.power
     self.propEfficiency    =self.tm.propEfficiency
     self.beta              =self.tm.beta
     self.SAR_km_per_kg     =self.tm.SAR_km_per_kg
     self.lift              =L
     self.drag              =D
     self.L_D               =L/D   
     self.turnRadius        =turnRadius
     self.bankAngle         =phi
     self.loadFactor        =n
     self.turnRate          =turnRate
Exemple #13
0
    def analyze_prop(self,betaSet,N,V,rho):
        """
        Performs propeller analysis using BEMT. In case of poor convergence 
        (required J cannot be achieved at given rpm and airspeed) 
        function returns advance ratio and CP=None, CT=None, effy=None.
        Method returns thrust, power required, propeller advance ratio *J*, 
        thrust coefficient *CT*, power coefficient *CP* and efficiency *effy* 
        at given pitch angle, rpm, velocity and density
        
        Parameters
        ----------
        
        betaSet : float, degree
            pitch angle setting at 75% of diameter
        N : float, rpm
            propeller rotation speed
        V : float, m/sec
            true airspeed of aircraft (propeller)
        rho : float, kg/m^3
            air density

        
        Returns
        -------
        J : float
            advance ratio
        CT : float
            thrust coefficient
        CP : float
            power coefficient
        effy : float
            propeller efficiency
        """
        if N*V*rho==0.0:
            return zeros(6)
        if betaSet!=None:
            self.set_beta(betaSet)
        Jcorr = 0.97
        n  = N/60.0
        d  = self.diameter
        B  = self.numBlades
        dT = list()
        dQ = list()
        altitude   = FlightConditions.get_density_altitude(rho)
        soundSpeed = FlightConditions.ISAtmosphere(altitude).soundSpeed
        Jreq       = Jcorr * V / (n*d)
        def master_func(alpha,beta,x,r,B,soundSpeed,d,af,c,n):
            phi = radians(beta - alpha)
            # compute Prandtl loss factor
            sinPhiL1 = (1.0 + 1.0/(x*tan(phi))**2)**0.5
            f = B * (1.0/x-1.0) * sinPhiL1/2.0
            F = 2.0 * arccos(exp(-f)) / pi
            vLocal = pi*x*n*d / cos(phi)
            mach = vLocal / soundSpeed
            cl = float(af.polar.clAlpha(mach,alpha))
            cd = float(af.polar.cdAlpha(mach,alpha))
            sinPhi = sin(phi)
            cosPhi = cos(phi)
            lambdaT = cl*cosPhi - cd*sinPhi
            lambdaP = cl*sinPhi + cd*cosPhi
            sigma   = c*B / (2.0*pi*r)
            J = pi*x*(4.0*F*sinPhi**2 - lambdaT*sigma) / (4.0*F*sinPhi*cosPhi + lambdaP*sigma)
            return J,vLocal, lambdaT,lambdaP
        def get_J(alpha,Jreq,beta,x,r,B,soundSpeed,d,af,c,n):
            rslt = master_func(alpha,beta,x,r,B,soundSpeed,d,af,c,n)
            return rslt[0] - Jreq
        for i in range(self.numStations):
            x      = self.x[i]
            c      = self.chord[i]
            beta   = self.beta[i]
            r      = self.r[i]
            alpha0List = [-20,-10,-5,0,5,10,20,30,40,50]
            af     = self.airfoil[i]
            for alpha0 in alpha0List:
                try:
                    alpha  = newton(get_J,alpha0,args=(Jreq,beta,x,r,B,soundSpeed,d,af,c,n),tol=0.01)
                    break
                except RuntimeError:
                    return 0.0,0.0,Jreq, 0.0, 0.0, 0.0
            J,vLocal,lambdaT,lambdaP = master_func(alpha,beta,x,r,B,soundSpeed,d,af,c,n)
            dT.append(  rho*vLocal**2*lambdaT*c*B / 2.0  )
            dQ.append(  rho*vLocal**2*lambdaP*c*B*r / 2.0  )
        dT.insert(0,0.0)
        dQ.insert(0,0.0)
        dT.append(0.0)
        dQ.append(0.0)
        r_ = copy(self.r)
        radius = self.diameter/2.0
        r_ = hstack([0.0,r_,radius])
        T  = simps(dT,r_)
        Q  = simps(dQ,r_)
        CT   = T / (rho*n**2*d**4)
        CQ   = Q / (rho*n**2*d**5)
        effy = CT/CQ*Jreq/(2.0*pi)
        effy = effy
        CP   = Jreq*CT/effy
        P    = CP*rho*n**3*d**5
        if CT<=0.0 or CT>1.0:
            CT=0.0
            effy = 0.0
        if CQ<=0.0 or CQ>1.0:
            CQ=0.0
            effy = 0.0
        if CP<=0.0:
            CP=0.0
        if not effy==None:
            effy = effy*0.95
        return T,P,Jreq/Jcorr,CT,CP,effy