def test_Vstall(self):

        t0 = time.clock()
        print("time start= ", t0)

        atmosphere = Atmosphere()
        earth = Earth()
        print(
            '==================== Stall Speed according to airport field elevation ==================== '
            + time.strftime("%c"))
        acBd = BadaAircraftDatabase()
        aircraftICAOcode = 'B743'
        if acBd.read():
            if (acBd.aircraftExists(aircraftICAOcode)
                    and acBd.aircraftPerformanceFileExists(
                        acBd.getAircraftPerformanceFile(aircraftICAOcode))):

                print(
                    '==================== aircraft found  ==================== '
                    + time.strftime("%c"))
                aircraft = BadaAircraft(
                    ICAOcode=aircraftICAOcode,
                    aircraftFullName=acBd.getAircraftFullName(
                        aircraftICAOcode),
                    badaPerformanceFilePath=acBd.getAircraftPerformanceFile(
                        aircraftICAOcode),
                    atmosphere=atmosphere,
                    earth=earth)
                aircraft.dump()

        print('==================== Airport database ==================== ' +
              time.strftime("%c"))
        airportsDB = AirportsDatabase()
        assert airportsDB.read()
        for airport in airportsDB.getAirports():
            print('============' + airport.getName() + ' ============')
            #print airport
            aircraft = BadaAircraft(
                ICAOcode=aircraftICAOcode,
                aircraftFullName=acBd.getAircraftFullName(aircraftICAOcode),
                badaPerformanceFilePath=acBd.getAircraftPerformanceFile(
                    aircraftICAOcode),
                atmosphere=atmosphere,
                earth=earth)
            print('airport field elevation= {0:.2f} meters'.format(
                airport.getFieldElevationAboveSeaLevelMeters()))
            CAS = aircraft.computeStallSpeedCasKnots()
            print('V stall Calibrated AirSpeed= {0:.2f} knots'.format(CAS))
            TAS = cas2tas(
                cas=CAS,
                altitude=airport.getFieldElevationAboveSeaLevelMeters(),
                temp='std',
                speed_units='kt',
                alt_units='m',
                temp_units=default_temp_units,
            )
            print('V stall True AirSpeed= {0:.2f} knots'.format(TAS))
 def test_Vstall(self):
     
     
     t0 = time.clock()
     print "time start= ", t0
     
     atmosphere = Atmosphere()
     earth = Earth()
     print '==================== Stall Speed according to airport field elevation ==================== '+ time.strftime("%c")
     acBd = BadaAircraftDatabase()
     aircraftICAOcode = 'B743'
     if acBd.read():
         if ( acBd.aircraftExists(aircraftICAOcode) 
              and acBd.aircraftPerformanceFileExists(acBd.getAircraftPerformanceFile(aircraftICAOcode))):
             
             print '==================== aircraft found  ==================== '+ time.strftime("%c")
             aircraft = BadaAircraft(ICAOcode = aircraftICAOcode, 
                                     aircraftFullName = acBd.getAircraftFullName(aircraftICAOcode),
                                     badaPerformanceFilePath = acBd.getAircraftPerformanceFile(aircraftICAOcode),
                                     atmosphere = atmosphere,
                                     earth = earth)
             aircraft.dump()
             
     print '==================== Airport database ==================== '+ time.strftime("%c")
     airportsDB = AirportsDatabase()
     assert airportsDB.read()
     for airport in airportsDB.getAirports():
         print '============' + airport.getName() + ' ============'
         #print airport
         aircraft = BadaAircraft(ICAOcode =  aircraftICAOcode, 
                                     aircraftFullName = acBd.getAircraftFullName(aircraftICAOcode),
                                     badaPerformanceFilePath = acBd.getAircraftPerformanceFile(aircraftICAOcode),
                                     atmosphere = atmosphere,
                                     earth = earth)
         print 'airport field elevation= {0:.2f} meters'.format( airport.getFieldElevationAboveSeaLevelMeters())
         CAS = aircraft.computeStallSpeedCasKnots()
         print 'V stall Calibrated AirSpeed= {0:.2f} knots'.format(CAS) 
         TAS = cas2tas(cas = CAS , 
               altitude = airport.getFieldElevationAboveSeaLevelMeters(),
               temp = 'std',
               speed_units = 'kt',
               alt_units = 'm',
               temp_units=default_temp_units,
               )
         print 'V stall True AirSpeed= {0:.2f} knots'.format(TAS) 
Example #3
0
    def buildNewSimulatedArrivalTurnLeg(self,
                                        deltaTimeSeconds,
                                        elapsedTimeSeconds=0.0,
                                        distanceStillToFlyMeters=0.0,
                                        simulatedAltitudeSeaLevelMeters=660.0,
                                        flightPathAngleDegrees=3.0,
                                        bankAngleDegrees=5.0):
        ''' if it is the last turn then need to reach the final way point => top of glide slope '''
        tasMetersPerSecond = cas2tas(
            cas=self.aircraft.computeLandingStallSpeedCasKnots(),
            altitude=simulatedAltitudeSeaLevelMeters,
            temp='std',
            speed_units='kt',
            alt_units='m') * Knot2MetersPerSecond
        tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
        ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
        radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (
            9.81 * math.tan(math.radians(bankAngleDegrees)))
        print(
            self.className +
            ': tas= {0:.2f} knots - radius of turn= {1:.2f} meters - radius of turn= {2:.2f} nautics'
            .format(tasKnots, radiusOfTurnMeters, radiusOfTurnMeters *
                    Meter2NauticalMiles))
        ''' index used to initialise the loop '''
        index = 0
        ''' build a list that can be reversed afterwards '''
        turnLegList = []
        ''' initial altitude '''
        altitudeMeanSeaLevelMeters = simulatedAltitudeSeaLevelMeters
        ''' initial time management '''
        ''' 1.0 seconds delta time means THREE degrees turn every second '''
        elapsedTimeSeconds = elapsedTimeSeconds
        ''' loop from initial heading to final heading '''
        continueTurning = True
        currentHeadingDegrees = self.initialHeadingDegrees
        print(self.className + ': initial heading= {0:.2f} degrees'.format(
            self.initialHeadingDegrees))
        passedThrough360 = False

        while (continueTurning == True):
            ''' init the loop '''
            if index == 0:
                ''' set initial way Point altitude '''
                self.initialWayPoint.setAltitudeAboveSeaLevelMeters(
                    altitudeMeanSeaLevelMeters)
                ''' prepare for the next round '''
                intermediateWayPoint = self.initialWayPoint

            deltaDistanceMeters = tasMetersPerSecond * deltaTimeSeconds
            ''' compute delta heading '''
            deltaHeadingDegrees = math.degrees(
                math.atan(deltaDistanceMeters / radiusOfTurnMeters))

            if self.stepDegrees > 0:
                ''' turn clock-wise => angle increases '''
                currentHeadingDegrees += deltaHeadingDegrees
                # print currentHeadingDegrees ,
                if self.initialHeadingDegrees <= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees <=
                                       self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 before increasing again '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees <= 360.0:
                            continueTurning = (currentHeadingDegrees <= 360.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(
                                currentHeadingDegrees, 360.0)
                            continueTurning = (currentHeadingDegrees <=
                                               self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(
                            currentHeadingDegrees, 360.0)
                        continueTurning = (currentHeadingDegrees <=
                                           self.finalHeadingDegrees)

            else:
                ''' turning anti clock-wise => angle decreases '''
                currentHeadingDegrees -= deltaHeadingDegrees
                if self.initialHeadingDegrees >= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees >=
                                       self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees >= 0.0:
                            continueTurning = (currentHeadingDegrees >= 0.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(
                                currentHeadingDegrees + 360.0, 360.0)
                            continueTurning = (currentHeadingDegrees >=
                                               self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(
                            currentHeadingDegrees + 360.0, 360.0)
                        continueTurning = (currentHeadingDegrees >=
                                           self.finalHeadingDegrees)
            ''' define the name of the new way-point '''
            name = 'turn-pt-{0}-{1:.2f}-degrees'.format(
                index, currentHeadingDegrees)
            # print self.className + ' next way-point= ' + name
            ''' convert heading into bearing '''
            bearingDegrees = math.fmod(currentHeadingDegrees + 180.0,
                                       360.0) - 180.0
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(
                Name=name,
                DistanceMeters=deltaDistanceMeters,
                BearingDegrees=bearingDegrees)
            newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(
                altitudeMeanSeaLevelMeters)
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
            '''  28 March 2015 - final angle needs to be updated as the aircraft turns '''
            self.finalHeadingDegrees = newIntermediateWayPoint.getBearingDegreesTo(
                self.finalWayPoint)
            ''' increment the index '''
            index += 1
            ''' insert in the route '''
            # print index , type(index)
            turnLegList.append(newIntermediateWayPoint)
            ''' copy the intermediate '''
            intermediateWayPoint = newIntermediateWayPoint
            ''' reverse the list if needed => and build the route  '''
        if self.reverse == True:
            ''' reverse the order and build the graph '''
            for point in reversed(turnLegList):
                self.addVertex(point)
                index += 1
        else:
            ''' do not reverse it '''
            for point in turnLegList:
                self.addVertex(point)
Example #4
0
 def buildSimulatedArrivalTurnLeg(self,
                                  deltaTimeSeconds,
                                  elapsedTimeSeconds=0.0,
                                  distanceStillToFlyMeters=0.0,
                                  simulatedAltitudeSeaLevelMeters=0.0,
                                  flightPathAngleDegrees=3.0):
     ''' the simulated arrival turn leg is built backwards 
     from the start of the descending glide slope backwards to a distance as top of glide slope '''
     ''' use base class that returns a list of angles in degrees '''
     ''' WARNING = 3 degrees per second => if delta time = 1 second then step Degrees = 3 degrees '''
     baseTurnLeg = BaseTurnLeg(self.initialHeadingDegrees,
                               self.finalHeadingDegrees, self.stepDegrees)
     self.listOfAngleDegrees = baseTurnLeg.build()
     ''' index used to initialise the loop '''
     index = 0
     ''' build a list that can be reversed afterwards '''
     turnLegList = []
     ''' initial altitude '''
     altitudeMeanSeaLevelMeters = simulatedAltitudeSeaLevelMeters
     ''' initial time management '''
     ''' 1.0 seconds delta time means THREE degrees turn every second '''
     elapsedTimeSeconds = elapsedTimeSeconds
     ''' loop through the list of angles '''
     for angleDegrees in self.listOfAngleDegrees:
         ''' initial index - loop initialisation '''
         # print 'altitude= ' + str(altitudeMeanSeaLevelMeters) + ' meters'
         ''' init the loop '''
         if index == 0:
             ''' set initial way Point altitude '''
             self.initialWayPoint.setAltitudeAboveSeaLevelMeters(
                 altitudeMeanSeaLevelMeters)
             ''' prepare for the next round '''
             intermediateWayPoint = self.initialWayPoint
         ''' aircraft fly '''
         trueAirspeedMeterSeconds = cas2tas(
             cas=self.aircraft.computeLandingStallSpeedCasKnots(),
             altitude=simulatedAltitudeSeaLevelMeters,
             temp='std',
             speed_units='kt',
             alt_units='m') * Knot2MetersPerSecond
         deltaDistanceMeters = trueAirspeedMeterSeconds * deltaTimeSeconds
         altitudeMeanSeaLevelMeters = altitudeMeanSeaLevelMeters + trueAirspeedMeterSeconds * math.sin(
             math.radians(flightPathAngleDegrees))
         ''' update elapsed time '''
         elapsedTimeSeconds += deltaTimeSeconds
         ''' distance over flown for each degree - depends upon true air speed '''
         # print self.className + ': distance flown when 1 degrees of heading angle changes= '+ str(distanceMeters) + ' meters'
         ''' define the name of the new way-point '''
         name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index, angleDegrees)
         # print self.className + ' next way-point= ' + name
         ''' convert heading into bearing '''
         bearingDegrees = math.fmod(angleDegrees + 180.0, 360.0) - 180.0
         newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(
             Name=name,
             DistanceMeters=deltaDistanceMeters,
             BearingDegrees=bearingDegrees)
         newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(
             altitudeMeanSeaLevelMeters)
         newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
         ''' increment the index '''
         index += 1
         ''' insert in the route '''
         # print index , type(index)
         turnLegList.append(newIntermediateWayPoint)
         ''' copy the intermediate '''
         intermediateWayPoint = newIntermediateWayPoint
     ''' reverse the list if needed => and build the route  '''
     if self.reverse == True:
         ''' reverse the order and build the graph '''
         index = 0
         for point in reversed(turnLegList):
             self.addVertex(index, point)
             index += 1
     else:
         ''' do not reverse it '''
         index = 0
         for point in turnLegList:
             self.addVertex(index, point)
             index += 1
     '''''' ''' print location of the last point of the route '''
     assert (self.getNumberOfVertices() > 1)
     lastVertex = self.getVertex(self.getNumberOfVertices() - 1)
     lastWayPoint = lastVertex.getWeight()
     print('location of the last point ' + str(lastWayPoint))
Example #5
0
    def buildTurnLeg(self,
                     deltaTimeSeconds,
                     elapsedTimeSeconds,
                     distanceStillToFlyMeters,
                     distanceToLastFixMeters,
                     finalHeadingDegrees=0.0,
                     lastTurn=False,
                     bankAngleDegrees=15.0):
        ''' start building a set of turning legs from initial heading to final heading '''
        ''' heading changes according to an aircraft speed => radius of turn '''
        ''' for the last turn => final heading is the heading of run-way '''
        if lastTurn == True:
            self.finalHeadingDegrees = finalHeadingDegrees
        ''' initial altitude '''
        altitudeMeanSeaLevelMeters = self.aircraft.getCurrentAltitudeSeaLevelMeters(
        )
        ''' if it is the last turn then need to reach the final way point => top of glide slope '''
        tasMetersPerSecond = self.aircraft.getCurrentTrueAirSpeedMetersSecond()
        tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
        ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
        radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (
            9.81 * math.tan(math.radians(bankAngleDegrees)))
        if ((2 * radiusOfTurnMeters) >
                self.initialWayPoint.getDistanceMetersTo(self.finalWayPoint)):
            ''' increase bank angle to 25 degrees and decrease turn radius '''
            radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (
                9.81 * math.tan(math.radians(25.0)))
        ''' case of last turn '''
        if lastTurn == True:
            tasMetersPerSecond = cas2tas(
                cas=self.aircraft.computeLandingStallSpeedCasKnots(),
                altitude=altitudeMeanSeaLevelMeters,
                temp='std',
                speed_units='kt',
                alt_units='m') * Knot2MetersPerSecond
            tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
            ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
            radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (
                9.81 * math.tan(math.radians(bankAngleDegrees)))

        print(
            self.className +
            ': tas= {0:.2f} knots - radius of turn= {1:.2f} meters - radius of turn= {2:.2f} nautics'
            .format(tasKnots, radiusOfTurnMeters, radiusOfTurnMeters *
                    Meter2NauticalMiles))
        ''' index used to initialise the loop '''
        index = 0
        ''' build a list that can be reversed afterwards '''
        turnLegList = []
        ''' initial time management '''
        ''' 1.0 seconds delta time means THREE degrees turn every second '''
        elapsedTimeSeconds = elapsedTimeSeconds
        ''' loop from initial heading to final heading '''
        continueTurning = True
        currentHeadingDegrees = self.initialHeadingDegrees
        print(self.className + ': initial heading= {0:.2f} degrees'.format(
            self.initialHeadingDegrees))
        passedThrough360 = False
        endOfSimulation = False
        while ((endOfSimulation == False) and (continueTurning == True)):
            ''' initial index - loop initialisation '''
            # print 'altitude= ' + str(altitudeMeanSeaLevelMeters) + ' meters'
            ''' init the loop '''
            if index == 0:
                ''' set initial way Point altitude '''
                self.initialWayPoint.setAltitudeAboveSeaLevelMeters(
                    altitudeMeanSeaLevelMeters)
                ''' prepare for the next round '''
                intermediateWayPoint = self.initialWayPoint
            ''' aircraft fly '''
            endOfSimulation, deltaDistanceMeters, altitudeMeanSeaLevelMeters = self.aircraft.fly(
                elapsedTimeSeconds=elapsedTimeSeconds,
                deltaTimeSeconds=deltaTimeSeconds,
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                currentPosition=intermediateWayPoint,
                distanceToLastFixMeters=distanceToLastFixMeters)
            ''' update elapsed time seconds '''
            elapsedTimeSeconds += deltaTimeSeconds
            ''' update distance to fly '''
            distanceStillToFlyMeters -= deltaDistanceMeters
            ''' compute delta heading '''
            deltaHeadingDegrees = math.degrees(
                math.atan(deltaDistanceMeters / radiusOfTurnMeters))
            # print self.className + ': delta distance= {0:.2f} meters - delta Heading = {1:.2f} degrees'.format(deltaDistanceMeters, deltaHeadingDegrees)
            if self.stepDegrees > 0:
                ''' turn clock-wise => angle increases '''
                currentHeadingDegrees += deltaHeadingDegrees
                # print currentHeadingDegrees ,
                if self.initialHeadingDegrees <= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees <=
                                       self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 before increasing again '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees <= 360.0:
                            continueTurning = (currentHeadingDegrees <= 360.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(
                                currentHeadingDegrees, 360.0)
                            continueTurning = (currentHeadingDegrees <=
                                               self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(
                            currentHeadingDegrees, 360.0)
                        continueTurning = (currentHeadingDegrees <=
                                           self.finalHeadingDegrees)

            else:
                ''' turning anti clock-wise => angle decreases '''
                currentHeadingDegrees -= deltaHeadingDegrees
                if self.initialHeadingDegrees >= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees >=
                                       self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees >= 0.0:
                            continueTurning = (currentHeadingDegrees >= 0.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(
                                currentHeadingDegrees + 360.0, 360.0)
                            continueTurning = (currentHeadingDegrees >=
                                               self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(
                            currentHeadingDegrees + 360.0, 360.0)
                        continueTurning = (currentHeadingDegrees >=
                                           self.finalHeadingDegrees)
            ''' define the name of the new way-point '''
            name = 'turn-pt-{0}-{1:.2f}-degrees'.format(
                index, currentHeadingDegrees)
            ''' patch do not define a name as it slows opening the KML file in Google Earth '''
            name = ''
            # print self.className + ' next way-point= ' + name
            ''' convert heading into bearing '''
            bearingDegrees = math.fmod(currentHeadingDegrees + 180.0,
                                       360.0) - 180.0
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(
                Name=name,
                DistanceMeters=deltaDistanceMeters,
                BearingDegrees=bearingDegrees)

            #             if lastTurn == True:
            #                 arrivalTouchDownWayPoint = self.aircraft.getArrivalRunwayTouchDownWayPoint()
            #                 distanceToArrivalTouchDownMeters = newIntermediateWayPoint.getDistanceMetersTo(arrivalTouchDownWayPoint)
            #                 arrivalRunWayBearingDegrees = math.fmod ( self.finalHeadingDegrees + 180.0 , 360.0 )
            #                 pointAlongRunwayAxis = arrivalTouchDownWayPoint.getWayPointAtDistanceBearing(Name = '',
            #                                                                                       DistanceMeters = distanceToArrivalTouchDownMeters,
            #                                                                                       BearingDegrees = arrivalRunWayBearingDegrees)
            #                 distanceToArrivalRunwayAxis = newIntermediateWayPoint.getDistanceMetersTo(pointAlongRunwayAxis)
            #                 print self.className + ': distance to arrival runway axis= {0:.2f} meters'.format(distanceToArrivalRunwayAxis)
            #                 if (self.previousDistanceToArrivalAxisMeters > 1.0) and (distanceToArrivalRunwayAxis > self.previousDistanceToArrivalAxisMeters):
            #                     continueTurning = False
            #                 self.previousDistanceToArrivalAxisMeters = distanceToArrivalRunwayAxis

            newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(
                altitudeMeanSeaLevelMeters)
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
            '''  28 March 2015 - final angle needs to be updated as the aircraft turns '''
            ''' except if we are performing the last turn '''
            if lastTurn == False:
                self.finalHeadingDegrees = newIntermediateWayPoint.getBearingDegreesTo(
                    self.finalWayPoint)
            ''' increment the index '''
            index += 1
            ''' insert in the route '''
            # print index , type(index)
            turnLegList.append(newIntermediateWayPoint)
            ''' copy the intermediate '''
            intermediateWayPoint = newIntermediateWayPoint
        ''' set name of last point '''
        name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index,
                                                    currentHeadingDegrees)
        newIntermediateWayPoint.setName(name)
        ''' reverse the list if needed => and build the route  '''
        if self.reverse == True:
            ''' reverse the order and build the graph '''
            for point in reversed(turnLegList):
                self.addVertex(point)
        else:
            ''' do not reverse it '''
            for point in turnLegList:
                self.addVertex(point)
        '''' print final heading  '''
        print(self.className +
              ': final heading= {0:.2f} degrees'.format(currentHeadingDegrees))
        return endOfSimulation
    def buildNewSimulatedArrivalTurnLeg(self, 
                                        deltaTimeSeconds,
                                     elapsedTimeSeconds = 0.0, 
                                     distanceStillToFlyMeters = 0.0,
                                     simulatedAltitudeSeaLevelMeters = 660.0,
                                     flightPathAngleDegrees = 3.0 ,
                                     bankAngleDegrees = 5.0):
        
        ''' if it is the last turn then need to reach the final way point => top of glide slope '''
        tasMetersPerSecond = cas2tas(cas = self.aircraft.computeLandingStallSpeedCasKnots(),
                                               altitude = simulatedAltitudeSeaLevelMeters,
                                               temp = 'std',
                                               speed_units = 'kt',
                                               alt_units = 'm' ) * Knot2MetersPerSecond
        tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
        
        ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
        radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (9.81 * math.tan(math.radians(bankAngleDegrees)))
        print self.className + ': tas= {0:.2f} knots - radius of turn= {1:.2f} meters - radius of turn= {2:.2f} nautics'.format(tasKnots, radiusOfTurnMeters, radiusOfTurnMeters*Meter2NauticalMiles)            
 
        ''' index used to initialise the loop '''        
        index = 0
        ''' build a list that can be reversed afterwards '''
        turnLegList = []
        ''' initial altitude '''
        altitudeMeanSeaLevelMeters = simulatedAltitudeSeaLevelMeters
        ''' initial time management '''
        ''' 1.0 seconds delta time means THREE degrees turn every second '''
        elapsedTimeSeconds = elapsedTimeSeconds
        
        ''' loop from initial heading to final heading '''
        continueTurning = True
        currentHeadingDegrees = self.initialHeadingDegrees
        print self.className + ': initial heading= {0:.2f} degrees'.format(self.initialHeadingDegrees)
        passedThrough360 = False

        while (  continueTurning == True ):
            
            ''' init the loop '''
            if index == 0:
                ''' set initial way Point altitude '''
                self.initialWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)             
                ''' prepare for the next round '''
                intermediateWayPoint = self.initialWayPoint
    
            deltaDistanceMeters = tasMetersPerSecond * deltaTimeSeconds
            ''' compute delta heading '''
            deltaHeadingDegrees = math.degrees(math.atan(deltaDistanceMeters / radiusOfTurnMeters))

            if self.stepDegrees > 0:
                ''' turn clock-wise => angle increases '''
                currentHeadingDegrees += deltaHeadingDegrees
                #print currentHeadingDegrees ,
                if self.initialHeadingDegrees <= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 before increasing again '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees <= 360.0:
                            continueTurning = (currentHeadingDegrees <= 360.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(currentHeadingDegrees, 360.0)
                            continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(currentHeadingDegrees, 360.0)
                        continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                        
            else:
                ''' turning anti clock-wise => angle decreases '''
                currentHeadingDegrees -= deltaHeadingDegrees
                if self.initialHeadingDegrees >= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees >= 0.0:
                            continueTurning = (currentHeadingDegrees >= 0.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(currentHeadingDegrees + 360.0, 360.0)
                            continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(currentHeadingDegrees + 360.0, 360.0)
                        continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                
            ''' define the name of the new way-point '''
            name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index, currentHeadingDegrees)
            #print self.className + ' next way-point= ' + name
            ''' convert heading into bearing '''
            bearingDegrees = math.fmod ( currentHeadingDegrees + 180.0 , 360.0 ) - 180.0
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(Name=name, 
                                                                                  DistanceMeters=deltaDistanceMeters, 
                                                                                  BearingDegrees=bearingDegrees)
            newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
            '''  28 March 2015 - final angle needs to be updated as the aircraft turns '''
            self.finalHeadingDegrees = newIntermediateWayPoint.getBearingDegreesTo(self.finalWayPoint)

            ''' increment the index '''
            index += 1
            ''' insert in the route '''
            #print index , type(index)
            turnLegList.append(newIntermediateWayPoint)
            ''' copy the intermediate '''
            intermediateWayPoint = newIntermediateWayPoint
    
            ''' reverse the list if needed => and build the route  '''
        if self.reverse == True:
            ''' reverse the order and build the graph '''
            for point in reversed(turnLegList):
                self.addVertex(point)
                index += 1
        else:
            ''' do not reverse it '''
            for point in turnLegList:
                self.addVertex(point)
    def buildSimulatedArrivalTurnLeg(self, 
                                     deltaTimeSeconds,
                                     elapsedTimeSeconds = 0.0, 
                                     distanceStillToFlyMeters = 0.0,
                                     simulatedAltitudeSeaLevelMeters = 0.0,
                                     flightPathAngleDegrees = 3.0 ):
        
        ''' the simulated arrival turn leg is built backwards 
        from the start of the descending glide slope backwards to a distance as top of glide slope '''
        
        ''' use base class that returns a list of angles in degrees '''
        ''' WARNING = 3 degrees per second => if delta time = 1 second then step Degrees = 3 degrees '''
        baseTurnLeg = BaseTurnLeg(self.initialHeadingDegrees, self.finalHeadingDegrees, self.stepDegrees)
        self.listOfAngleDegrees = baseTurnLeg.build()
        
        ''' index used to initialise the loop '''        
        index = 0
            
        ''' build a list that can be reversed afterwards '''
        turnLegList = []
        ''' initial altitude '''
        altitudeMeanSeaLevelMeters = simulatedAltitudeSeaLevelMeters
        ''' initial time management '''
        ''' 1.0 seconds delta time means THREE degrees turn every second '''
        elapsedTimeSeconds = elapsedTimeSeconds
        
        ''' loop through the list of angles '''
        for angleDegrees in self.listOfAngleDegrees:
            ''' initial index - loop initialisation '''
            #print 'altitude= ' + str(altitudeMeanSeaLevelMeters) + ' meters'
            
            ''' init the loop '''
            if index == 0:
                ''' set initial way Point altitude '''
                self.initialWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)             
                ''' prepare for the next round '''
                intermediateWayPoint = self.initialWayPoint
            
            ''' aircraft fly '''
            trueAirspeedMeterSeconds = cas2tas(cas = self.aircraft.computeLandingStallSpeedCasKnots(),
                                               altitude = simulatedAltitudeSeaLevelMeters,
                                               temp = 'std',
                                               speed_units = 'kt',
                                               alt_units = 'm' ) * Knot2MetersPerSecond
            deltaDistanceMeters = trueAirspeedMeterSeconds * deltaTimeSeconds 
            altitudeMeanSeaLevelMeters = altitudeMeanSeaLevelMeters + trueAirspeedMeterSeconds * math.sin(math.radians(flightPathAngleDegrees))
            ''' update elapsed time '''
            elapsedTimeSeconds += deltaTimeSeconds

            ''' distance over flown for each degree - depends upon true air speed '''
            #print self.className + ': distance flown when 1 degrees of heading angle changes= '+ str(distanceMeters) + ' meters'
                
            ''' define the name of the new way-point '''
            name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index, angleDegrees)
            #print self.className + ' next way-point= ' + name
            ''' convert heading into bearing '''
            bearingDegrees = math.fmod ( angleDegrees + 180.0 , 360.0 ) - 180.0
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(Name=name, 
                                                                                  DistanceMeters=deltaDistanceMeters, 
                                                                                  BearingDegrees=bearingDegrees)
            newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)

            ''' increment the index '''
            index += 1
            ''' insert in the route '''
            #print index , type(index)
            turnLegList.append(newIntermediateWayPoint)
            ''' copy the intermediate '''
            intermediateWayPoint = newIntermediateWayPoint
        
         
        ''' reverse the list if needed => and build the route  '''
        if self.reverse == True:
            ''' reverse the order and build the graph '''
            index = 0
            for point in reversed(turnLegList):
                self.addVertex(index, point)
                index += 1
        else:
            ''' do not reverse it '''
            index = 0
            for point in turnLegList:
                self.addVertex(index, point)
                index += 1
        
        ''''''''' print location of the last point of the route '''
        assert (self.getNumberOfVertices()>1)
        lastVertex = self.getVertex(self.getNumberOfVertices()-1)
        lastWayPoint = lastVertex.getWeight()
        print 'location of the last point ' + str(lastWayPoint)
    def buildTurnLeg(self, 
                     deltaTimeSeconds,
                     elapsedTimeSeconds,
                     distanceStillToFlyMeters,
                     distanceToLastFixMeters,
                     finalHeadingDegrees = 0.0,
                     lastTurn = False,
                     bankAngleDegrees = 15.0):
        
        ''' start building a set of turning legs from initial heading to final heading '''
        ''' heading changes according to an aircraft speed => radius of turn '''
        ''' for the last turn => final heading is the heading of run-way '''
        if lastTurn == True:
            self.finalHeadingDegrees = finalHeadingDegrees
        
        ''' initial altitude '''
        altitudeMeanSeaLevelMeters = self.aircraft.getCurrentAltitudeSeaLevelMeters()
        
        ''' if it is the last turn then need to reach the final way point => top of glide slope '''
        tasMetersPerSecond = self.aircraft.getCurrentTrueAirSpeedMetersSecond()
        tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
        
        ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
        radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (9.81 * math.tan(math.radians(bankAngleDegrees)))
        if ((2*radiusOfTurnMeters) > self.initialWayPoint.getDistanceMetersTo(self.finalWayPoint)):
            ''' increase bank angle to 25 degrees and decrease turn radius '''
            radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (9.81 * math.tan(math.radians(25.0)))
        ''' case of last turn '''
        if lastTurn == True:
            tasMetersPerSecond = cas2tas(cas = self.aircraft.computeLandingStallSpeedCasKnots(),
                                               altitude = altitudeMeanSeaLevelMeters,
                                               temp = 'std',
                                               speed_units = 'kt',
                                               alt_units = 'm' ) * Knot2MetersPerSecond
            tasKnots = tasMetersPerSecond * MeterPerSecond2Knots
        
            ''' Radius = (tas*tas) / (gravity * tan(bank angle = 15 degrees)) '''
            radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (9.81 * math.tan(math.radians(bankAngleDegrees)))
        
        print self.className + ': tas= {0:.2f} knots - radius of turn= {1:.2f} meters - radius of turn= {2:.2f} nautics'.format(tasKnots, radiusOfTurnMeters, radiusOfTurnMeters*Meter2NauticalMiles)            
        ''' index used to initialise the loop '''        
        index = 0
            
        ''' build a list that can be reversed afterwards '''
        turnLegList = []
        
        ''' initial time management '''
        ''' 1.0 seconds delta time means THREE degrees turn every second '''
        elapsedTimeSeconds = elapsedTimeSeconds
        
        ''' loop from initial heading to final heading '''
        continueTurning = True
        currentHeadingDegrees = self.initialHeadingDegrees
        print self.className + ': initial heading= {0:.2f} degrees'.format(self.initialHeadingDegrees)
        passedThrough360 = False
        endOfSimulation = False
        while ( (endOfSimulation == False) and (continueTurning == True)):
            ''' initial index - loop initialisation '''
            #print 'altitude= ' + str(altitudeMeanSeaLevelMeters) + ' meters'
            
            ''' init the loop '''
            if index == 0:
                ''' set initial way Point altitude '''
                self.initialWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)             
                ''' prepare for the next round '''
                intermediateWayPoint = self.initialWayPoint
            
            ''' aircraft fly '''
            endOfSimulation, deltaDistanceMeters , altitudeMeanSeaLevelMeters = self.aircraft.fly(
                                                                    elapsedTimeSeconds = elapsedTimeSeconds,
                                                                    deltaTimeSeconds = deltaTimeSeconds , 
                                                                     distanceStillToFlyMeters = distanceStillToFlyMeters,
                                                                     currentPosition = intermediateWayPoint,
                                                                     distanceToLastFixMeters = distanceToLastFixMeters)
            ''' update elapsed time seconds '''
            elapsedTimeSeconds += deltaTimeSeconds
            ''' update distance to fly '''
            distanceStillToFlyMeters -= deltaDistanceMeters
            ''' compute delta heading '''
            deltaHeadingDegrees = math.degrees(math.atan(deltaDistanceMeters / radiusOfTurnMeters))
            #print self.className + ': delta distance= {0:.2f} meters - delta Heading = {1:.2f} degrees'.format(deltaDistanceMeters, deltaHeadingDegrees)
            if self.stepDegrees > 0:
                ''' turn clock-wise => angle increases '''
                currentHeadingDegrees += deltaHeadingDegrees
                #print currentHeadingDegrees ,
                if self.initialHeadingDegrees <= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 before increasing again '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees <= 360.0:
                            continueTurning = (currentHeadingDegrees <= 360.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(currentHeadingDegrees, 360.0)
                            continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(currentHeadingDegrees, 360.0)
                        continueTurning = (currentHeadingDegrees <= self.finalHeadingDegrees)
                        
            else:
                ''' turning anti clock-wise => angle decreases '''
                currentHeadingDegrees -= deltaHeadingDegrees
                if self.initialHeadingDegrees >= self.finalHeadingDegrees:
                    continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                else:
                    ''' need to pass through 360.0 '''
                    if passedThrough360 == False:
                        if currentHeadingDegrees >= 0.0:
                            continueTurning = (currentHeadingDegrees >= 0.0)
                        else:
                            passedThrough360 = True
                            currentHeadingDegrees = math.fmod(currentHeadingDegrees + 360.0, 360.0)
                            continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                    else:
                        currentHeadingDegrees = math.fmod(currentHeadingDegrees + 360.0, 360.0)
                        continueTurning = (currentHeadingDegrees >= self.finalHeadingDegrees)
                
            ''' define the name of the new way-point '''
            name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index, currentHeadingDegrees)
            ''' patch do not define a name as it slows opening the KML file in Google Earth '''
            name = ''
            #print self.className + ' next way-point= ' + name
            ''' convert heading into bearing '''
            bearingDegrees = math.fmod ( currentHeadingDegrees + 180.0 , 360.0 ) - 180.0
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(
                                                                                        Name = name, 
                                                                                  DistanceMeters = deltaDistanceMeters, 
                                                                                  BearingDegrees = bearingDegrees)
            
#             if lastTurn == True:
#                 arrivalTouchDownWayPoint = self.aircraft.getArrivalRunwayTouchDownWayPoint()
#                 distanceToArrivalTouchDownMeters = newIntermediateWayPoint.getDistanceMetersTo(arrivalTouchDownWayPoint)
#                 arrivalRunWayBearingDegrees = math.fmod ( self.finalHeadingDegrees + 180.0 , 360.0 )
#                 pointAlongRunwayAxis = arrivalTouchDownWayPoint.getWayPointAtDistanceBearing(Name = '',
#                                                                                       DistanceMeters = distanceToArrivalTouchDownMeters,
#                                                                                       BearingDegrees = arrivalRunWayBearingDegrees)
#                 distanceToArrivalRunwayAxis = newIntermediateWayPoint.getDistanceMetersTo(pointAlongRunwayAxis)
#                 print self.className + ': distance to arrival runway axis= {0:.2f} meters'.format(distanceToArrivalRunwayAxis)
#                 if (self.previousDistanceToArrivalAxisMeters > 1.0) and (distanceToArrivalRunwayAxis > self.previousDistanceToArrivalAxisMeters):
#                     continueTurning = False 
#                 self.previousDistanceToArrivalAxisMeters = distanceToArrivalRunwayAxis
                
            newIntermediateWayPoint.setAltitudeAboveSeaLevelMeters(altitudeMeanSeaLevelMeters)
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
            '''  28 March 2015 - final angle needs to be updated as the aircraft turns '''
            ''' except if we are performing the last turn '''
            if lastTurn == False:
                self.finalHeadingDegrees = newIntermediateWayPoint.getBearingDegreesTo(self.finalWayPoint)

            ''' increment the index '''
            index += 1
            ''' insert in the route '''
            #print index , type(index)
            turnLegList.append(newIntermediateWayPoint)
            ''' copy the intermediate '''
            intermediateWayPoint = newIntermediateWayPoint
            
        ''' set name of last point '''
        name = 'turn-pt-{0}-{1:.2f}-degrees'.format(index, currentHeadingDegrees)
        newIntermediateWayPoint.setName(name)
        ''' reverse the list if needed => and build the route  '''
        if self.reverse == True:
            ''' reverse the order and build the graph '''
            for point in reversed(turnLegList):
                self.addVertex(point)
        else:
            ''' do not reverse it '''
            for point in turnLegList:
                self.addVertex(point)
        
        '''' print final heading  '''
        print self.className + ': final heading= {0:.2f} degrees'.format(currentHeadingDegrees)
        return endOfSimulation
          time.strftime("%c"))
    runWaysDB = RunWayDataBase()
    assert runWaysDB.read()

    arrivalRunway = runWaysDB.getFilteredRunWays(
        arrivalAirportCode, 'Landing', aircraft.WakeTurbulenceCategory)
    print(arrivalRunway)

    aircraft.setArrivalAirportElevationMeters(
        arrivalAirport.getFieldElevationAboveSeaLevelMeters())

    CAS = aircraft.computeLandingStallSpeedCasKnots()
    TAS = cas2tas(
        cas=CAS,
        altitude=arrivalAirport.getFieldElevationAboveSeaLevelMeters(),
        temp='std',
        speed_units='kt',
        alt_units='m',
        temp_units=default_temp_units,
    )
    aircraft.initStateVector(elapsedTimeSeconds=0.0,
                             trueAirSpeedMetersSecond=TAS,
                             altitudeMeanSeaLevelMeters=arrivalAirport.
                             getFieldElevationAboveSeaLevelMeters(),
                             deltaDistanceFlownMeters=0.0)
    aircraft.setLandingConfiguration(0.0)
    groundRun = GroundRunLeg(runway=arrivalRunway,
                             aircraft=aircraft,
                             airport=arrivalAirport)

    groundRun.buildArrivalGroundRun(0.0)
    groundRun.createXlsxOutputFile()
Example #10
0
if __name__ == '__main__':
    
    atmosphere = Atmosphere()

    print ( '=========== main start ==================' )
    for tas in range(0,100,1):
        cas1 = tas2cas(tas = tas , altitude = 100.0, temp='std', speed_units = 'm/s', alt_units='m')
        cas2 = atmosphere.tas2cas(tas, altitude = 100.0, speed_units = 'm/s', alt_units = 'm')
        print ( tas, cas1, cas2 )
    
    print ( '=========== main start ==================' )

    for altitude in range(0, 10000, 100):
        cas = 100.0 # 100 m/s
        tas1 = cas2tas(cas = cas, altitude = altitude, temp='std', speed_units = 'm/s', alt_units='m')
        tas2 = atmosphere.cas2tas(cas = cas, altitudeMeters = altitude, speed_units = 'm/s', altitude_units = 'm')
        print ( 'altitude= {0} meters ... cas= {1} m/s constant ... tas1= {2} m/s ... tas2= {3} m/s'.format(altitude, cas, tas1, tas2) )
    
    print ( '=========== main start ==================' )

    earth = Earth()
    acBd = BadaAircraftDatabase()
    assert acBd.read()
    aircraftIcaoCode = 'B742'
    if ( acBd.aircraftExists(aircraftIcaoCode) 
        and acBd.aircraftPerformanceFileExists(aircraftIcaoCode)):
        aircraft = BadaAircraft(aircraftIcaoCode,
                                acBd.getAircraftFullName(aircraftIcaoCode),
                                acBd.getAircraftPerformanceFile(aircraftIcaoCode),
                                atmosphere,