Exemple #1
0
    def __init__(self,
                 runway,
                 aircraft,
                 arrivalAirport,
                 descentGlideSlopeDegrees=3.0):
        '''
        arrival Airport provides the field elevation above sea level in meters
        '''
        self.className = self.__class__.__name__
        Graph.__init__(self)

        assert isinstance(descentGlideSlopeDegrees, float)
        self.descentGlideSlopeDegrees = descentGlideSlopeDegrees

        # sanity check
        assert isinstance(arrivalAirport, Airport)
        self.arrivalAirport = arrivalAirport
        ''' sanity check RunWay '''
        assert isinstance(runway, RunWay)
        self.runway = runway

        assert isinstance(aircraft, BadaAircraft)
        self.aircraft = aircraft

        fieldElevationAboveSeaLevelMeters = arrivalAirport.getFieldElevationAboveSeaLevelMeters(
        )
        print(self.className +
              ': airport field Elevation Above Sea Level= {0:.2f} meters'.
              format(fieldElevationAboveSeaLevelMeters))

        strName = arrivalAirport.getName(
        ) + '-' + 'RunWay' + '-' + self.runway.getName()
        self.runWayEndPoint = WayPoint(
            Name=strName,
            LatitudeDegrees=runway.getLatitudeDegrees(),
            LongitudeDegrees=runway.getLongitudeDegrees(),
            AltitudeMeanSeaLevelMeters=fieldElevationAboveSeaLevelMeters)
        ''' touch down is provided from BADA Ground Movement Landing Length '''
        landingDistanceMeters = self.aircraft.groundMovement.getLandingLengthMeters(
        )
        #print self.className + ': {0} aircraft landing length: {1:.2F} meters'.format(self.aircraft.ICAOcode, landingDistanceMeters)
        runWayOrientationDegrees = self.runway.getTrueHeadingDegrees()
        ''' if orientation is 270 degrees from runway end point then ... touch down bearing is 360-270=90 bearing from end point '''
        self.runWayTouchDownPoint = self.runWayEndPoint.getWayPointAtDistanceBearing(
            Name='runway-touch-down',
            DistanceMeters=landingDistanceMeters,
            BearingDegrees=runWayOrientationDegrees)
        ''' elevation of touch down point = field elevation'''
        self.runWayTouchDownPoint.setAltitudeMeanSeaLevelMeters(
            fieldElevationAboveSeaLevelMeters)
        strMsg = "{0} - distance from RunWay - TouchDown to RunWay - End= {1:.2f} meters".format(
            self.className,
            self.runWayTouchDownPoint.getDistanceMetersTo(self.runWayEndPoint))
        print(strMsg)

        self.bearingDegrees = self.runWayTouchDownPoint.getBearingDegreesTo(
            self.runWayEndPoint)
        print(self.className +
              ": bearing from touch-down to runway end= {0:.2f} degrees".
              format(self.bearingDegrees))
Exemple #2
0
    def read(self):
        assert len(self.FilePath) > 0
        self.book = open_workbook(self.FilePath)
        ''' assert there is only one sheet '''
        sheet = self.book.sheet_by_name('WayPoints')
        for row in range(sheet.nrows):
            rowValues = sheet.row_values(row,
                                         start_colx=0,
                                         end_colx=sheet.ncols)
            # Print the values of the row formatted to 10 characters wide
            if row == 0:
                self.ColumnNames = {}
                index = 0
                for column in rowValues:
                    if column not in fieldNames:
                        print(
                            self.className +
                            ': ERROR - expected way-points column name= {0} not in field names'
                            .format(column))
                        return False
                    else:
                        self.ColumnNames[column] = index
                    index += 1
            else:
                WayPointName = str(rowValues[0]).strip().upper()
                if not (WayPointName in self.WayPointsDict.keys()):

                    wayPointDict = {}
                    for column in self.ColumnNames:
                        if column == 'Latitude' or column == 'Longitude':
                            ''' replace degree character '''
                            strLatLong = (
                                rowValues[self.ColumnNames[column]]).strip()
                            if '°' in strLatLong:
                                strLatLong = (strLatLong).replace('°', '-')
                                #strLatLong = strLatLong.encode('ascii', 'ignore')

                            strLatLong = str(strLatLong).strip().replace(
                                "'", '-').replace(' ', '').replace('"', '')
                            #print 'lat-long= '+ strLatLong
                            wayPointDict[
                                column] = convertDegreeMinuteSecondToDecimal(
                                    strLatLong)

                        else:
                            wayPointDict[column] = str(
                                rowValues[self.ColumnNames[column]]).strip()
                    ''' create a way point '''
                    wayPoint = WayPoint(wayPointDict['WayPoint'],
                                        wayPointDict['Latitude'],
                                        wayPointDict['Longitude'])
                    self.WayPointsDict[WayPointName] = wayPoint
                else:
                    print(
                        "duplicates found in Way Points database - way Point= {0}"
                        .format(WayPointName))
        return True
Exemple #3
0
    def test_waypoint(self):

        print("=========== WayPoint start  =========== " + time.strftime("%c"))
        London = WayPoint('London-Heathrow', 51.5, 0.0)
        Orly = WayPoint('Orly', 48.726254, 2.365247)
        print("distance from London to Orly= ",
              London.getDistanceMetersTo(Orly), " meters")
        print("bearing from London to Orly= ", London.getBearingDegreesTo(Orly),
              " degrees")

        # Zurich = WayPoint('Zurich-Kloten', 47.458215, 8.555424)
        Marseille = WayPoint('Marseille-Marignane', 43.438431, 5.214382)
        Zurich = WayPoint('Zurich-Kloten', 47.458215, 8.555424)

        print("=========== WayPoint resume  =========== " + time.strftime("%c"))

        print("distance from Marseille to Zurich= ",
              Marseille.getDistanceMetersTo(Zurich), " meters")
        print("bearing from Zurich to Marseille = ",
              Zurich.getBearingDegreesTo(Marseille), " degrees")

        distanceMeters = 321584.699454
        bearingDegrees = Zurich.getBearingDegreesTo(Marseille)
        # bearingDegrees = Marseille.getBearingDegreesTo(Zurich)
        Zurich.dump()
        Marseille.dump()
        TopOfDescent = Zurich.getWayPointAtDistanceBearing('TopOfDescent',
                                                           distanceMeters,
                                                           bearingDegrees)
        TopOfDescent.dump()

        print("=========== WayPoint resume  =========== " + time.strftime("%c"))
        London.dump()
        Orly.dump()
        bearingDegrees = Orly.getBearingDegreesTo(London)
        print("bearing from London to Orly= ", London.getBearingDegreesTo(Orly),
              " degrees")

        TopOfDescent = Orly.getWayPointAtDistanceBearing('TopOfDescent',
                                                         distanceMeters,
                                                         bearingDegrees)
        TopOfDescent.dump()
 def computeTouchDownWayPoint(self):
     ''' get landing length in meters '''
     landingLengthMeters = self.aircraft.getLandingLengthMeters()
     ''' run-way orientation '''
     runwayTrueHeadingDegrees = self.runway.getTrueHeadingDegrees()
     
     ''' run-way end point '''
     strRunWayEndPointName = self.airport.getName() + '-' + 'Rwy'+'-'+self.runway.getName()
     runWayEndPoint = WayPoint (Name = strRunWayEndPointName, 
                                 LatitudeDegrees = self.runway.getLatitudeDegrees(),
                                 LongitudeDegrees = self.runway.getLongitudeDegrees(),
                                 AltitudeMeanSeaLevelMeters =self.airport.getFieldElevationAboveSeaLevelMeters())
     
     strTouchDownWayPointName = self.airport.getName() + '-' + 'Rwy'+'-' + self.runway.getName() + '-' + 'touch-down'
     touchDownWayPoint = runWayEndPoint.getWayPointAtDistanceBearing(Name = strTouchDownWayPointName, 
                                                                     DistanceMeters = landingLengthMeters, 
                                                                     BearingDegrees = runwayTrueHeadingDegrees)
     touchDownWayPoint.setAltitudeMeanSeaLevelMeters(self.airport.getFieldElevationAboveSeaLevelMeters())
     return touchDownWayPoint
    def read(self):

        workbook = xlrd.open_workbook(self.FilePath)
        worksheet = workbook.sheet_by_index(0)

        self.rows = []
        for i, row in enumerate(range(worksheet.nrows)):

            r = []
            for j, col in enumerate(range(worksheet.ncols)):
                r.append(worksheet.cell_value(i, j))
            if (i == 0):
                self.headers = r
            else:
                self.rows.append(r)
                self.geoPoints.append(WayPoint(r[1], r[2], r[3]))

        print("{0} - read {1} rows".format(self.className, len(self.rows)))
        print(self.headers)  # Print column headings
        print(self.rows[0])  # Print first data row sample
        return (len(self.rows) > 0)
Exemple #6
0
    def test_DescentGlideSlope(self):

        atmosphere = Atmosphere()
        earth = Earth()
        print '==================== three degrees Descent Slope Start  ==================== ' + time.strftime(
            "%c")

        acBd = BadaAircraftDatabase()
        aircraftICAOcode = 'A320'
        if acBd.read():
            if (acBd.aircraftExists(aircraftICAOcode)
                    and acBd.aircraftPerformanceFileExists(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()

        assert not (aircraft is None)
        print '==================== runways database ==================== ' + time.strftime(
            "%c")
        runWaysDatabase = RunWayDataBase()
        assert runWaysDatabase.read()

        runway = runWaysDatabase.getFilteredRunWays(airportICAOcode='LFML',
                                                    runwayName='')
        print runway

        print "=========== arrival airport  =========== " + time.strftime("%c")
        airportsDB = AirportsDatabase()
        assert (airportsDB.read())

        MarseilleMarignane = airportsDB.getAirportFromICAOCode('LFML')
        print MarseilleMarignane

        print "=========== descent glide slope  =========== " + time.strftime(
            "%c")
        threeDegreesGlideSlope = DescentGlideSlope(
            runway=runway,
            aircraft=aircraft,
            arrivalAirport=MarseilleMarignane)

        initialWayPoint = WayPoint(Name='startOfDescentGlideSlope', )
        print "=========== DescentGlideSlope build the glide slope  =========== " + time.strftime(
            "%c")
        #     threeDegreesGlideSlope.buildGlideSlope(deltaTimeSeconds = 0.1,
        #                         elapsedTimeSeconds = 0.0,
        #                         initialWayPoint = None,
        #                         flownDistanceMeters = 0.0,
        #                         distanceStillToFlyMeters = 100000.0,
        #                         distanceToLastFixMeters = 100000.0)

        threeDegreesGlideSlope.buildSimulatedGlideSlope(
            descentGlideSlopeSizeNautics=5.0)

        print "=========== DescentGlideSlope  =========== " + time.strftime(
            "%c")
        for node in threeDegreesGlideSlope.getVertices():
            print node

        print "=========== DescentGlideSlope length =========== " + time.strftime(
            "%c")
        print "get number of vertices= {0}".format(
            threeDegreesGlideSlope.getNumberOfVertices())
        print "get number of edges= {0}".format(
            threeDegreesGlideSlope.getNumberOfEdges())
        print 'Glide Slope overall length= {0} meters'.format(
            threeDegreesGlideSlope.computeLengthMeters())

        threeDegreesGlideSlope.createKmlOutputFile()
        threeDegreesGlideSlope.createXlsxOutputFile()
        print '==================== three degrees Descent Slope End  ==================== ' + time.strftime(
            "%c")
    def computeGreatCircle(self, 
                           deltaTimeSeconds,
                           elapsedTimeSeconds,
                           distanceStillToFlyMeters,
                           distanceToLastFixMeters):
        ''' internally modified '''
        initialDeltaTimeSeconds = deltaTimeSeconds
        '''
        build the great circle
        '''
        distance_radians = 2 * math.asin(math.sqrt(math.pow((math.sin((self.ptlat1_radians-self.ptlat2_radians)/2)),2) + math.cos(self.ptlat1_radians) * math.cos(self.ptlat2_radians)*math.pow((math.sin((self.ptlon1_radians-self.ptlon2_radians)/2)),2)))
        ''' 6371.009 represents the mean radius of the earth'''
        ''' shortest path distance'''
        distanceMeters = EarthMeanRadiusMeters * distance_radians
        #print self.className + ': computeGreatCircle shortest path distance= ' + str(distanceMeters) + ' meters'

        ''' init the loop index '''
        index = 0
        elapsedTimeSeconds = elapsedTimeSeconds
        
        #print self.className + ': initial True Air Speed= ' + str(trueAirSpeedMetersSecond) + ' meters/second'
        overflownDistanceMeters = 0.0
        ''' loop over the over-flown distance '''
        endOfSimulation = False
        while ( (endOfSimulation == False) and (overflownDistanceMeters <  distanceMeters)):
            
            ''' initialization of the loop '''
            if index == 0:
                print ( self.className + ': initial way-point= {0}'.format(self.initialWayPoint) )
                intermediateWayPoint = self.initialWayPoint
            
            if self.aircraft.isCruiseSpeedReached():
                ''' speed up the computation => step = 10 seconds '''
                deltaTimeSeconds = 10.0
            else:
                deltaTimeSeconds = initialDeltaTimeSeconds
                
            ''' fly => increase in true air speed '''
            endOfSimulation, deltaDistanceMeters , altitudeMeanSeaLevelMeters = self.aircraft.fly(
                                                                    elapsedTimeSeconds = elapsedTimeSeconds,
                                                                    deltaTimeSeconds = deltaTimeSeconds, 
                                                                    distanceStillToFlyMeters = distanceStillToFlyMeters,
                                                                    currentPosition = intermediateWayPoint,
                                                                    distanceToLastFixMeters = distanceToLastFixMeters)
            #print self.className + ': True AirSpeed= ' + str(trueAirSpeedMetersSecond) + ' meters/second'

            ''' cumulated  over-flown distance '''
            overflownDistanceMeters += deltaDistanceMeters
            distanceStillToFlyMeters -= deltaDistanceMeters
            distanceToLastFixMeters -= deltaDistanceMeters
            fprime = overflownDistanceMeters / distanceMeters
            
            #print self.className + ': altitude= ' + str(altitudeMeanSeaLevelMeters) + ' meters'

            ''' fprime is expressed as a fraction along the route from point 1 to point 2 '''
            A = math.sin((1-fprime)*distance_radians) / math.sin(distance_radians)
            B = math.sin(fprime*distance_radians) / math.sin(distance_radians)
                
            x = A * math.cos(self.ptlat1_radians) * math.cos(self.ptlon1_radians) + B * math.cos(self.ptlat2_radians) * math.cos(self.ptlon2_radians)
            y = A * math.cos(self.ptlat1_radians) * math.sin(self.ptlon1_radians) +  B * math.cos(self.ptlat2_radians) * math.sin(self.ptlon2_radians)
            z = A * math.sin(self.ptlat1_radians) + B * math.sin(self.ptlat2_radians)

            newLatitudeRadians = math.atan2(z, math.sqrt(math.pow(x,2)+math.pow(y,2)))
            newLongitudeRadians = math.atan2(y,x)
                
            newlat_degrees = math.degrees(newLatitudeRadians)
            newlon_degrees = math.degrees(newLongitudeRadians)
                
            #name = 'gc-pt-{0}-{1:.2f}-Nm'.format(index, overflownDistanceMeters*Meter2NauticalMiles)
            name = ''
            ''' new way point is built with an altitude  '''
            newWayPoint = WayPoint(Name = name,
                                   LatitudeDegrees = newlat_degrees,
                                   LongitudeDegrees = newlon_degrees,
                                   AltitudeMeanSeaLevelMeters = altitudeMeanSeaLevelMeters)
            
            ''' update new point '''
            elapsedTimeSeconds += deltaTimeSeconds            
            newWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)

            ''' build the route '''
            self.addVertex(newWayPoint)
            ''' set new intermediate way-point '''
            intermediateWayPoint = newWayPoint
            ''' increment index needed when adding vertex '''
            index += 1
        
        ''' rename the final way point '''
        intermediateWayPoint.setName(self.finalWayPoint.getName())
#         minutes, seconds = divmod(elapsedTimeSeconds, 60)
#         strMsg = ': passing way-point: {0} ... altitude= {1:.2f} feet ... distance= {2:.2f} nautics ... elapsed time= {3:.2f} sec ... elapsed time= {4} min {5} sec'.format(
#                                                     self.finalWayPoint.getName(), 
#                                                     altitudeMeanSeaLevelMeters * Meter2Feet,
#                                                     self.computeLengthMeters()* Meter2NauticalMiles,
#                                                     elapsedTimeSeconds, int(minutes), int(seconds))
#         print self.className + strMsg                                               
        print ( self.className + ': final way-point= {0}'.format(intermediateWayPoint) )
        return endOfSimulation
    def buildDepartureGroundRun(self, 
                                deltaTimeSeconds,
                                elapsedTimeSeconds,
                                distanceStillToFlyMeters,
                                distanceToLastFixMeters):
        ''' build the departure ground run
        '''
        
        ''' elapsedTimeSeconds in seconds '''
        elapsedTimeSeconds = elapsedTimeSeconds

        ''' run-way end point '''
        strRunWayEndPointName = self.airport.getName() + '-' + 'Rwy'+'-'+self.runway.getName()
        runWayEndPoint = WayPoint (Name=strRunWayEndPointName, 
                                    LatitudeDegrees=self.runway.getLatitudeDegrees(),
                                    LongitudeDegrees=self.runway.getLongitudeDegrees(),
                                    AltitudeMeanSeaLevelMeters=self.airport.getFieldElevationAboveSeaLevelMeters())
        ''' run-way true heading '''
        runwayTrueHeadingDegrees = self.runway.getTrueHeadingDegrees()
        ''' call base class Graph to build Climb Ramp core of the route '''
        index = 0
        self.addVertex(runWayEndPoint)
        index += 1
        
        ''' departure ground run => initial speed is null '''
        trueAirSpeedMetersSecond = 0.1
        ''' ground run leg distance '''
        totalLegDistanceMeters = 0.0
        self.aircraft.initStateVector(    elapsedTimeSeconds,
                                            trueAirSpeedMetersSecond,
                                            self.airport.getFieldElevationAboveSeaLevelMeters())
        ''' 
        Usually, the lift-off speed is designated to be 1.2 * Vstall 
        at a given weight, an aircraft will rotate and climb, stall or fly at an approach to landing at approx the same CAS.
        regardless of the elevation (height above sea level) , even though the true airspeed and ground-speed may differ significantly.
        These V speeds are normally published as IAS rather than CAS so they can be read directly from the airspeed indicator.
        '''
        VStallSpeedCASKnots = self.aircraft.computeStallSpeedCasKnots()
        print self.className + ': V stall Calibrated AirSpeed= {0:.2f} knots'.format(VStallSpeedCASKnots)
        ''' loop until Stall CAS reached '''
        endOfSimulation = False
        while ((endOfSimulation == False) and
               ( tas2cas(tas = trueAirSpeedMetersSecond ,
                       altitude = self.airport.getFieldElevationAboveSeaLevelMeters(),
                                                  temp='std',
                                                  speed_units = 'm/s',
                                                  alt_units = 'm') * MeterPerSecond2Knots )  < (1.2 * VStallSpeedCASKnots)):
            ''' initial loop index '''
            if index == 1:
                intermediateWayPoint = runWayEndPoint
                
            ''' fly => increase in true air speed '''
            ''' during ground run => all the energy is used to increase the Kinetic energy => no potential energy increase '''
            endOfSimulation, deltaDistanceMeters , altitudeMeters = self.aircraft.fly(
                                                                    elapsedTimeSeconds = elapsedTimeSeconds,
                                                                     deltaTimeSeconds = deltaTimeSeconds, 
                                                                     distanceStillToFlyMeters = distanceStillToFlyMeters,
                                                                     currentPosition  = intermediateWayPoint,
                                                                     distanceToLastFixMeters = distanceToLastFixMeters)
            trueAirSpeedMetersSecond = self.aircraft.getCurrentTrueAirSpeedMetersSecond()
            assert (((self.airport.getFieldElevationAboveSeaLevelMeters() - 10.0) <= altitudeMeters) and
                    ( altitudeMeters <= (self.airport.getFieldElevationAboveSeaLevelMeters() + 10.0)))
            #print self.className + ': delta distance= ' + str(deltaDistanceMeters) + ' meters'
            # name of the next point            
            totalLegDistanceMeters += deltaDistanceMeters
            distanceStillToFlyMeters -= deltaDistanceMeters
            distanceToLastFixMeters -= deltaDistanceMeters
            
            Name = ''
            if index == 1:
                Name = 'ground-run-pt-{0}-{1:.2f}-meters'.format(index-1, totalLegDistanceMeters)
            #bearingDegrees = math.fmod ( runwayTrueHeadingDegrees + 180.0 , 360.0 )
            bearingDegrees = runwayTrueHeadingDegrees
            newIntermediateWayPoint = intermediateWayPoint.getWayPointAtDistanceBearing(Name = Name, 
                                                                                  DistanceMeters = deltaDistanceMeters, 
                                                                                  BearingDegrees = bearingDegrees)
            ''' during the ground run - altitude = airport field elevation '''
            newIntermediateWayPoint.setAltitudeMeanSeaLevelMeters(self.airport.getFieldElevationAboveSeaLevelMeters())
            
            ''' update route waypoint '''
            elapsedTimeSeconds += deltaTimeSeconds
            newIntermediateWayPoint.setElapsedTimeSeconds(elapsedTimeSeconds)
 
            ''' insert in the route '''
            self.addVertex(newIntermediateWayPoint)
            
            ''' copy the intermediate way-point '''
            intermediateWayPoint = newIntermediateWayPoint 
            ''' increment the index '''
            index += 1
            
        ''' rename last point as take-off '''
        intermediateWayPoint.setName(Name = 'Take-Off-{0:.2f}-meters'.format(totalLegDistanceMeters))