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
class DescentGlideSlope(Graph): ''' the glide slope starts 5 Nautical miles ahead of the touch-down point ''' className = '' descentGlideSlopeDegrees = 0.0 runWayTouchDownPoint= None runWayEndPoint = None runway = None aircraft = None arrivalAirport = None 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 = self.className + ": distance from RunWay - TouchDown to RunWay - End= " strMsg += str(self.runWayTouchDownPoint.getDistanceMetersTo(self.runWayEndPoint)) + " meters" 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) def buildGlideSlope(self, deltaTimeSeconds, elapsedTimeSeconds, initialWayPoint, flownDistanceMeters, distanceStillToFlyMeters, distanceToLastFixMeters): ''' sanity checks ''' assert isinstance(initialWayPoint, WayPoint) '''=====================================================''' ''' hopefully in approach or landing configuration dh/dt such as dh/ds between 3 and 5 degrees ''' '''=====================================================''' ''' descent stops when altitude Mean Sea Level meters <= airport field MSL meters ''' fieldElevationAboveSeaLevelMeters = self.arrivalAirport.getFieldElevationAboveSeaLevelMeters() ''' initial conditions ''' index = 0 aircraftAltitudeMeanSeaLevelMeters = self.aircraft.getCurrentAltitudeSeaLevelMeters() endOfSimulation = False newIntermediatePoint = None while ( (endOfSimulation == False) and (aircraftAltitudeMeanSeaLevelMeters >= fieldElevationAboveSeaLevelMeters) and not( self.aircraft.isArrivalGroundRun()) ): ''' initial way point ''' if index == 0: intermediateWayPoint = initialWayPoint ''' correct bearing to each touch down ''' self.bearingDegrees = intermediateWayPoint.getBearingDegreesTo(self.runWayTouchDownPoint) #print self.className + ': bearing to touch down= {0:.2f} degrees'.format(self.bearingDegrees) ''' aircraft fly ''' endOfSimulation, deltaDistanceMeters , aircraftAltitudeMeanSeaLevelMeters = self.aircraft.fly( elapsedTimeSeconds = elapsedTimeSeconds, deltaTimeSeconds = deltaTimeSeconds , distanceStillToFlyMeters = distanceStillToFlyMeters, currentPosition = intermediateWayPoint, distanceToLastFixMeters = distanceToLastFixMeters) flownDistanceMeters += deltaDistanceMeters distanceStillToFlyMeters -= deltaDistanceMeters distanceToLastFixMeters -= deltaDistanceMeters ''' update aircraft state vector ''' elapsedTimeSeconds += deltaTimeSeconds Name = '' ''' only the first and the last point has a name ''' if index == 0: Name = 'slope-pt-{0}-{1:.2f}-Nm'.format(index, flownDistanceMeters*Meter2NauticalMiles) newIntermediatePoint = intermediateWayPoint.getWayPointAtDistanceBearing( Name = Name, DistanceMeters = deltaDistanceMeters, BearingDegrees = self.bearingDegrees) ''' set altitude ''' if isinstance(newIntermediatePoint, WayPoint): newIntermediatePoint.setAltitudeMeanSeaLevelMeters(aircraftAltitudeMeanSeaLevelMeters) newIntermediatePoint.setElapsedTimeSeconds(elapsedTimeSeconds) ''' append the new point to the list ''' self.addVertex(newIntermediatePoint) ''' replace the intermediate point ''' intermediateWayPoint = newIntermediatePoint index += 1 ''' set the name of the last point ''' Name = 'slope-pt-{0}-{1:.2f}-Nm'.format(index, flownDistanceMeters*Meter2NauticalMiles) if not(newIntermediatePoint is None): newIntermediatePoint.setName(Name = Name) def buildSimulatedGlideSlope(self, descentGlideSlopeSizeNautics): '''=====================================================''' ''' build the three degrees glide slope ''' ''' the slope is built backwards and then it is reversed ''======================================================''' #print self.className + ' ======= simulated glide slope =========' glideSlopeLengthMeters = descentGlideSlopeSizeNautics * NauticalMiles2Meters print self.className + ': glide slope Length= ' + str(glideSlopeLengthMeters), ' meters' bearingDegrees = self.runway.getTrueHeadingDegrees() print self.className + ': glide slope orientation= ' + str(bearingDegrees) + ' degrees' fieldElevationAboveSeaLevelMeters = self.arrivalAirport.getFieldElevationAboveSeaLevelMeters() ''' internal list that will be reversed ''' intermediateGlideSlopeRoute = [] '''==============================''' index = 0 initialIndex = index elapsedTimeSeconds = 0.0 '''==================================================================''' ''' glide slope to intercept the landing ILS beam ''' '''==================================================================''' ''' glide slope is split into 100 parts ''' distanceMeters = 0.0 while (distanceMeters < glideSlopeLengthMeters) : distanceMeters += glideSlopeLengthMeters/NumberOfSlopeParts #print 'index= ', index if index == initialIndex: ''' first point is the run way touch down ''' intermediatePoint = self.runWayTouchDownPoint #intermediatePoint.dump() ''' glide slope angle needs to be positive here : because slope is built backwards from run-way threshold ''' altitudeMeters = math.tan(math.radians(abs(self.descentGlideSlopeDegrees))) * distanceMeters name = 'glide-slope-pt-{0}-{1}-meters'.format(index, distanceMeters) ''' distance between each slope point is slope length divided by number of parts ''' newIntermediatePoint = intermediatePoint.getWayPointAtDistanceBearing(Name=name, DistanceMeters=glideSlopeLengthMeters/NumberOfSlopeParts, BearingDegrees=bearingDegrees) ''' set altitude ''' if isinstance(newIntermediatePoint, WayPoint): ''' need to add altitude above ground to field elevation ''' altitudeMeters += fieldElevationAboveSeaLevelMeters newIntermediatePoint.setAltitudeMeanSeaLevelMeters(altitudeMeters) elapsedTimeSeconds += 0.1 newIntermediatePoint.setElapsedTimeSeconds(elapsedTimeSeconds = elapsedTimeSeconds) ''' append the new point to the list ''' intermediateGlideSlopeRoute.append(newIntermediatePoint) ''' replace the intermediate point ''' intermediatePoint = newIntermediatePoint index += 1 '''=============================================================''' ''' reverse the order of the temporary list and build the graph ''' '''=============================================================''' for point in reversed(intermediateGlideSlopeRoute): self.addVertex(point) simulatedGlideSlopeLengthMeters = newIntermediatePoint.getDistanceMetersTo(self.runWayTouchDownPoint) print self.className + ': distance from last way point to touch-down: {0:.2f} nautics'.format(simulatedGlideSlopeLengthMeters * Meter2NauticalMiles)
class DescentGlideSlope(Graph): ''' the glide slope starts 5 Nautical miles ahead of the touch-down point ''' className = '' descentGlideSlopeDegrees = 0.0 runWayTouchDownPoint = None runWayEndPoint = None runway = None aircraft = None arrivalAirport = None 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 = self.className + ": distance from RunWay - TouchDown to RunWay - End= " strMsg += str( self.runWayTouchDownPoint.getDistanceMetersTo( self.runWayEndPoint)) + " meters" 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) def buildGlideSlope(self, deltaTimeSeconds, elapsedTimeSeconds, initialWayPoint, flownDistanceMeters, distanceStillToFlyMeters, distanceToLastFixMeters): ''' sanity checks ''' assert isinstance(initialWayPoint, WayPoint) '''=====================================================''' ''' hopefully in approach or landing configuration dh/dt such as dh/ds between 3 and 5 degrees ''' '''=====================================================''' ''' descent stops when altitude Mean Sea Level meters <= airport field MSL meters ''' fieldElevationAboveSeaLevelMeters = self.arrivalAirport.getFieldElevationAboveSeaLevelMeters( ) ''' initial conditions ''' index = 0 aircraftAltitudeMeanSeaLevelMeters = self.aircraft.getCurrentAltitudeSeaLevelMeters( ) endOfSimulation = False newIntermediatePoint = None while ((endOfSimulation == False) and (aircraftAltitudeMeanSeaLevelMeters >= fieldElevationAboveSeaLevelMeters) and not (self.aircraft.isArrivalGroundRun())): ''' initial way point ''' if index == 0: intermediateWayPoint = initialWayPoint ''' correct bearing to each touch down ''' self.bearingDegrees = intermediateWayPoint.getBearingDegreesTo( self.runWayTouchDownPoint) #print self.className + ': bearing to touch down= {0:.2f} degrees'.format(self.bearingDegrees) ''' aircraft fly ''' endOfSimulation, deltaDistanceMeters, aircraftAltitudeMeanSeaLevelMeters = self.aircraft.fly( elapsedTimeSeconds=elapsedTimeSeconds, deltaTimeSeconds=deltaTimeSeconds, distanceStillToFlyMeters=distanceStillToFlyMeters, currentPosition=intermediateWayPoint, distanceToLastFixMeters=distanceToLastFixMeters) flownDistanceMeters += deltaDistanceMeters distanceStillToFlyMeters -= deltaDistanceMeters distanceToLastFixMeters -= deltaDistanceMeters ''' update aircraft state vector ''' elapsedTimeSeconds += deltaTimeSeconds Name = '' ''' only the first and the last point has a name ''' if index == 0: Name = 'slope-pt-{0}-{1:.2f}-Nm'.format( index, flownDistanceMeters * Meter2NauticalMiles) newIntermediatePoint = intermediateWayPoint.getWayPointAtDistanceBearing( Name=Name, DistanceMeters=deltaDistanceMeters, BearingDegrees=self.bearingDegrees) ''' set altitude ''' if isinstance(newIntermediatePoint, WayPoint): newIntermediatePoint.setAltitudeMeanSeaLevelMeters( aircraftAltitudeMeanSeaLevelMeters) newIntermediatePoint.setElapsedTimeSeconds(elapsedTimeSeconds) ''' append the new point to the list ''' self.addVertex(newIntermediatePoint) ''' replace the intermediate point ''' intermediateWayPoint = newIntermediatePoint index += 1 ''' set the name of the last point ''' Name = 'slope-pt-{0}-{1:.2f}-Nm'.format( index, flownDistanceMeters * Meter2NauticalMiles) if not (newIntermediatePoint is None): newIntermediatePoint.setName(Name=Name) def buildSimulatedGlideSlope(self, descentGlideSlopeSizeNautics): '''=====================================================''' ''' build the three degrees glide slope ''' ''' the slope is built backwards and then it is reversed ''======================================================''' #print self.className + ' ======= simulated glide slope =========' glideSlopeLengthMeters = descentGlideSlopeSizeNautics * NauticalMiles2Meters print self.className + ': glide slope Length= ' + str( glideSlopeLengthMeters), ' meters' bearingDegrees = self.runway.getTrueHeadingDegrees() print self.className + ': glide slope orientation= ' + str( bearingDegrees) + ' degrees' fieldElevationAboveSeaLevelMeters = self.arrivalAirport.getFieldElevationAboveSeaLevelMeters( ) ''' internal list that will be reversed ''' intermediateGlideSlopeRoute = [] '''==============================''' index = 0 initialIndex = index elapsedTimeSeconds = 0.0 '''==================================================================''' ''' glide slope to intercept the landing ILS beam ''' '''==================================================================''' ''' glide slope is split into 100 parts ''' distanceMeters = 0.0 while (distanceMeters < glideSlopeLengthMeters): distanceMeters += glideSlopeLengthMeters / NumberOfSlopeParts #print 'index= ', index if index == initialIndex: ''' first point is the run way touch down ''' intermediatePoint = self.runWayTouchDownPoint #intermediatePoint.dump() ''' glide slope angle needs to be positive here : because slope is built backwards from run-way threshold ''' altitudeMeters = math.tan( math.radians(abs( self.descentGlideSlopeDegrees))) * distanceMeters name = 'glide-slope-pt-{0}-{1}-meters'.format( index, distanceMeters) ''' distance between each slope point is slope length divided by number of parts ''' newIntermediatePoint = intermediatePoint.getWayPointAtDistanceBearing( Name=name, DistanceMeters=glideSlopeLengthMeters / NumberOfSlopeParts, BearingDegrees=bearingDegrees) ''' set altitude ''' if isinstance(newIntermediatePoint, WayPoint): ''' need to add altitude above ground to field elevation ''' altitudeMeters += fieldElevationAboveSeaLevelMeters newIntermediatePoint.setAltitudeMeanSeaLevelMeters( altitudeMeters) elapsedTimeSeconds += 0.1 newIntermediatePoint.setElapsedTimeSeconds( elapsedTimeSeconds=elapsedTimeSeconds) ''' append the new point to the list ''' intermediateGlideSlopeRoute.append(newIntermediatePoint) ''' replace the intermediate point ''' intermediatePoint = newIntermediatePoint index += 1 '''=============================================================''' ''' reverse the order of the temporary list and build the graph ''' '''=============================================================''' for point in reversed(intermediateGlideSlopeRoute): self.addVertex(point) simulatedGlideSlopeLengthMeters = newIntermediatePoint.getDistanceMetersTo( self.runWayTouchDownPoint) print self.className + ': distance from last way point to touch-down: {0:.2f} nautics'.format( simulatedGlideSlopeLengthMeters * Meter2NauticalMiles)