예제 #1
0
    def buildSimulatedArrivalPhase(self):

        print(
            self.className +
            '=========== add final turn, descent and ground run ==================='
        )
        arrivalGroundRun = GroundRunLeg(runway=self.arrivalRunway,
                                        aircraft=self.aircraft,
                                        airport=self.arrivalAirport)
        self.touchDownWayPoint = arrivalGroundRun.computeTouchDownWayPoint()
        # add touch down to constraint list
        self.constraintsList.append(
            ArrivalRunWayTouchDownConstraint(self.touchDownWayPoint))

        print(self.touchDownWayPoint)
        ''' distance from last fix to touch down '''
        distanceToLastFixNautics = self.touchDownWayPoint.getDistanceMetersTo(
            self.getLastWayPoint()) * Meter2NauticalMiles

        print(
            self.className +
            '===================== final 3 degrees descending glide slope ================'
        )
        descentGlideSlope = DescentGlideSlope(
            runway=self.arrivalRunway,
            aircraft=self.aircraft,
            arrivalAirport=self.arrivalAirport,
            descentGlideSlopeDegrees=3.0)
        ''' if there is a fix nearer to 5 nautics of the touch-down then limit size of simulated glide slope '''
        descentGlideSlopeSizeNautics = min(distanceToLastFixNautics / 2.0, 5.0)
        ''' build simulated glide slope '''
        descentGlideSlope.buildSimulatedGlideSlope(
            descentGlideSlopeSizeNautics)
        self.firstGlideSlopeWayPoint = descentGlideSlope.getVertex(
            v=0).getWeight()
        print(self.className + ': top of arrival glide slope= {0}'.format(
            self.firstGlideSlopeWayPoint))

        print(
            self.className +
            ' ================= need a turn leg to find the junction point the last way-point in the fix list to the top of the final glide slope'
        )
        '''
        initial heading is the orientation of the run-way
        '''
        lastFixListWayPoint = self.wayPointsDict[self.fixList[-1]]
        initialHeadingDegrees = self.arrivalRunway.getTrueHeadingDegrees()

        print("=====> arrival runway - true heading degrees = {0}".format(
            initialHeadingDegrees))

        lastTurnLeg = TurnLeg(initialWayPoint=self.firstGlideSlopeWayPoint,
                              finalWayPoint=lastFixListWayPoint,
                              initialHeadingDegrees=initialHeadingDegrees,
                              aircraft=self.aircraft,
                              reverse=True)
        lastTurnLeg.buildNewSimulatedArrivalTurnLeg(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=0.0,
            distanceStillToFlyMeters=0.0,
            simulatedAltitudeSeaLevelMeters=self.firstGlideSlopeWayPoint.
            getAltitudeMeanSeaLevelMeters(),
            flightPathAngleDegrees=3.0,
            bankAngleDegrees=5.0)
        descentGlideSlope.addGraph(lastTurnLeg)
        #print self.className + ': compute arrival phase length= {0:.2f} meters'.format(descentGlideSlope.getLengthMeters())
        #descentGlideSlope.createXlsxOutputFile()
        #descentGlideSlope.createKmlOutputFile()
        ''' prepare next step '''
        beginOfLastTurnLeg = lastTurnLeg.getVertex(v=0).getWeight()
        print(self.className +
              ': begin of last turn= {0}'.format(beginOfLastTurnLeg))
        ''' add to constraint list '''
        self.constraintsList.append(
            TargetApproachConstraint(beginOfLastTurnLeg))
        ''' add the three last way-points in the fix list '''
        self.insert(position='end', wayPoint=beginOfLastTurnLeg)
        ''' update the length of the flight path '''
        self.distanceFromApproachToTouchDownMeters = descentGlideSlope.getLengthMeters(
        )
        self.flightLengthMeters = self.computeLengthMeters(
        ) + descentGlideSlope.getLengthMeters()

        print(self.className +
              ': updated flight path length= {0:.2f} nautics'.format(
                  self.flightLengthMeters * Meter2NauticalMiles))
        ''' target approach fix is equal to the begin of the SIMULATED last turn leg '''
        self.aircraft.setTargetApproachWayPoint(beginOfLastTurnLeg)
        self.aircraft.setArrivalRunwayTouchDownWayPoint(self.touchDownWayPoint)
        print(self.className + ': fix list= {0}'.format(self.fixList))
예제 #2
0
    def buildArrivalPhase(self, initialHeadingDegrees):

        print(
            self.className +
            ': initial heading= {0:.2f} degrees'.format(initialHeadingDegrees))

        print(self.className +
              '==================== add last turn ==================== ')
        if self.isDomestic() or self.isInBound():
            endOfLastGreatCircleWayPoint = self.finalRoute.getLastVertex(
            ).getWeight()

            finalHeadingDegrees = self.arrivalRunway.getTrueHeadingDegrees()
            finalHeadingDegrees = math.fmod(finalHeadingDegrees + 180.0, 360.0)
            print(self.className +
                  ': runway final heading= {0:.2f} degrees'.format(
                      finalHeadingDegrees))

            turnLeg = TurnLeg(
                initialWayPoint=endOfLastGreatCircleWayPoint,
                #finalWayPoint    = self.firstGlideSlopeWayPoint,
                finalWayPoint=self.touchDownWayPoint,
                initialHeadingDegrees=initialHeadingDegrees,
                aircraft=self.aircraft,
                reverse=False)

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters(
            )
            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfLastGreatCircleWayPoint,
                fixListIndex=self.flightListIndex)
            distanceToLastFixMeters = distanceStillToFlyMeters
            ''' for the last turn => final heading towards the runway orientation '''
            deltaTimeSeconds = 0.1
            turnLeg.buildTurnLeg(
                deltaTimeSeconds=deltaTimeSeconds,
                elapsedTimeSeconds=endOfLastGreatCircleWayPoint.
                getElapsedTimeSeconds(),
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters,
                finalHeadingDegrees=finalHeadingDegrees,
                lastTurn=True,
                bankAngleDegrees=5.0,
                arrivalRunway=self.arrivalRunway)
            self.finalRoute.addGraph(turnLeg)

            endOfTurnLegWayPoint = self.finalRoute.getLastVertex().getWeight()
            ''' ============= use touch-down way-point to compute distance to fly ============='''
            distanceStillToFlyMeters = endOfTurnLegWayPoint.getDistanceMetersTo(
                self.touchDownWayPoint)
            print(self.className +
                  ': distance still to fly= {0:.2f} nautics'.format(
                      distanceStillToFlyMeters * Meter2NauticalMiles))

            #print '==================== add descent slope ================= '
            descentGlideSlope = DescentGlideSlope(
                runway=self.arrivalRunway,
                aircraft=self.aircraft,
                arrivalAirport=self.arrivalAirport,
                descentGlideSlopeDegrees=3.0)

            flownDistanceMeters = self.finalRoute.getLengthMeters()
            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters(
            )
            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfTurnLegWayPoint,
                fixListIndex=self.flightListIndex)
            distanceToLastFixMeters = distanceStillToFlyMeters

            descentGlideSlope.buildGlideSlope(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfTurnLegWayPoint.getElapsedTimeSeconds(
                ),
                initialWayPoint=endOfTurnLegWayPoint,
                flownDistanceMeters=flownDistanceMeters,
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters)
            self.finalRoute.addGraph(descentGlideSlope)
            endOfDescentGlideSlope = self.finalRoute.getLastVertex().getWeight(
            )

            #print '================= add arrival ground run ================'
            arrivalGroundRun = GroundRunLeg(runway=self.arrivalRunway,
                                            aircraft=self.aircraft,
                                            airport=self.arrivalAirport)
            arrivalGroundRun.buildArrivalGroundRun(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfDescentGlideSlope.
                getElapsedTimeSeconds(),
                initialWayPoint=endOfDescentGlideSlope)
            self.finalRoute.addGraph(arrivalGroundRun)
        print('great circle length= ' +
              str(greatCircle.computeLengthMeters()) + ' meters')

        '======== get the first edge => defines the target heading after the turn leg ====== '
        initialGreatCircleEdge = greatCircle.getEdge(0)
        initialGreatCircleLeg = initialGreatCircleEdge.getWeight()
        print('initial leg bearing= ' +
              str(initialGreatCircleLeg.getBearingTailHeadDegrees()) +
              ' degrees')

        print(' ================== Departure Turn Leg  =============== ')
        departureTurnLeg = TurnLeg(
            initialWayPoint=endOfClimbRampWayPoint,
            finalWayPoint=LondonHeathrow,
            initialHeadingDegrees=lastClimbRampLeg.getBearingTailHeadDegrees(),
            finalHeadingDegrees=initialGreatCircleLeg.
            getBearingTailHeadDegrees(),
            aircraft=aircraft,
            aircraftConfiguration='take-off',
            reverse=False)
        departureTurnLeg.buildTurnLeg()

        print(
            ' =========== add Turn Leg to the Departure Climb Slope ============== '
        )
        climbRamp.addGraph(departureTurnLeg)

        print(
            ' ================== last point of climb ramp + turn leg =============== '
        )
        lastVertex = climbRamp.getVertex(climbRamp.getNumberOfVertices() - 1)
예제 #4
0
    def turnAndFly(self, tailWayPoint, headWayPoint, initialHeadingDegrees,
                   headWayPointIndex):
        ''' 
        execute a turn to align true heading and then fly a great circle 
        '''
        print(
            ' ================== one Turn Leg for each fix in the list =============== '
        )
        turnLeg = TurnLeg(initialWayPoint=tailWayPoint,
                          finalWayPoint=headWayPoint,
                          initialHeadingDegrees=initialHeadingDegrees,
                          aircraft=self.aircraft,
                          reverse=False)

        distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
            currentPosition=tailWayPoint, fixListIndex=headWayPointIndex)
        print(self.className +
              ': distance to last fix= {0:.2f} nautics'.format(
                  distanceToLastFixMeters * Meter2NauticalMiles))
        distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters(
        )
        print(self.className + ': still to fly= {0:.2f} nautics'.format(
            distanceStillToFlyMeters * Meter2NauticalMiles))

        endOfSimulation = turnLeg.buildTurnLeg(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=tailWayPoint.getElapsedTimeSeconds(),
            distanceStillToFlyMeters=distanceStillToFlyMeters,
            distanceToLastFixMeters=distanceToLastFixMeters)
        self.finalRoute.addGraph(turnLeg)

        if (endOfSimulation == False):
            print(
                ' ==================== end of turn leg  ==================== ')

            endOfTurnLegWayPoint = self.finalRoute.getLastVertex().getWeight()
            lastLeg = self.finalRoute.getLastEdge()
            print(self.className +
                  ': end of turn orientation= {0:.2f} degrees'.format(
                      lastLeg.getBearingTailHeadDegrees()))
            '''==================== check if anticipated turn or fly by is applicable '''
            anticipatedTurnWayPoint = None
            if (self.flightListIndex + 2) < len(self.fixList):
                ''' still another fix in the list '''
                firstAngleDegrees = endOfTurnLegWayPoint.getBearingDegreesTo(
                    headWayPoint)
                secondAngleDegrees = headWayPoint.getBearingDegreesTo(
                    self.wayPointsDict[self.fixList[self.flightListIndex + 2]])
                firstAngleRadians = math.radians(firstAngleDegrees)
                secondAngleRadians = math.radians(secondAngleDegrees)

                angleDifferenceDegrees = math.degrees(
                    math.atan2(
                        math.sin(secondAngleRadians - firstAngleRadians),
                        math.cos(secondAngleRadians - firstAngleRadians)))
                print(self.className + ': difference= {0:.2f} degrees'.format(
                    angleDifferenceDegrees))

                tasMetersPerSecond = self.aircraft.getCurrentTrueAirSpeedMetersSecond(
                )
                radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond
                                      ) / (9.81 * math.tan(math.radians(15.0)))

                anticipatedTurnStartMeters = radiusOfTurnMeters * math.tan(
                    math.radians((180.0 - abs(angleDifferenceDegrees)) / 2.0))
                print(self.className +
                      ': anticipated turn start from end point= {0:.2f} meters'
                      .format(anticipatedTurnStartMeters))

                if ((endOfTurnLegWayPoint.getDistanceMetersTo(headWayPoint) >
                     (1.1 * anticipatedTurnStartMeters)
                     and abs(angleDifferenceDegrees) > 30.)):
                    print(self.className +
                          ': Envisage anticipated Fly By turn !!!')
                    bearingDegrees = math.fmod(firstAngleDegrees + 180.0,
                                               360.0)
                    anticipatedTurnWayPoint = headWayPoint.getWayPointAtDistanceBearing(
                        Name='Anticipated-Turn-' + headWayPoint.getName(),
                        DistanceMeters=anticipatedTurnStartMeters,
                        BearingDegrees=bearingDegrees)
                    headWayPoint = anticipatedTurnWayPoint

            print(
                ' ==================== great circle ======================== ')
            greatCircle = GreatCircleRoute(
                initialWayPoint=endOfTurnLegWayPoint,
                finalWayPoint=headWayPoint,
                aircraft=self.aircraft)

            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfTurnLegWayPoint,
                fixListIndex=headWayPointIndex)
            print(self.className +
                  ': distance to last fix= {0} nautics'.format(
                      distanceToLastFixMeters * Meter2NauticalMiles))

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters(
            )
            print(self.className + ': still to fly= {0} nautics'.format(
                distanceStillToFlyMeters * Meter2NauticalMiles))

            endOfSimulation = greatCircle.computeGreatCircle(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfTurnLegWayPoint.getElapsedTimeSeconds(
                ),
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters)
            ''' update final route '''
            self.finalRoute.addGraph(greatCircle)

            print(
                ' ================== end of great circle ================== ')

            finalWayPoint = self.finalRoute.getLastVertex().getWeight()
            #print self.className + ': current end way point= ' + str(finalWayPoint)

            lastLeg = self.finalRoute.getLastEdge()
            finalHeadingDegrees = lastLeg.getBearingTailHeadDegrees()
            #print self.className + ': last leg orientation= {0:.2f} degrees'.format(finalHeadingDegrees)

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters(
            )
            print(
                self.className +
                ': still to fly= {0:.2f} meters - still to fly= {1:.2f} nautics'
                .format(distanceStillToFlyMeters, distanceStillToFlyMeters *
                        Meter2NauticalMiles))
            ''' print the way point that has been passed right now '''
            self.printPassedWayPoint(finalWayPoint)
        ''' return to caller '''
        return endOfSimulation, finalHeadingDegrees, finalWayPoint.getElapsedTimeSeconds(
        ), anticipatedTurnWayPoint
    def buildArrivalPhase(self, initialHeadingDegrees):

        print self.className + "==================== add last turn ==================== "
        if self.isDomestic() or self.isInBound():
            endOfLastGreatCircleWayPoint = self.finalRoute.getLastVertex().getWeight()

            finalHeadingDegrees = self.arrivalRunway.getTrueHeadingDegrees()
            finalHeadingDegrees = math.fmod(finalHeadingDegrees + 180.0, 360.0)
            print self.className + ": runway final heading= {0:.2f} degrees".format(finalHeadingDegrees)

            turnLeg = TurnLeg(
                initialWayPoint=endOfLastGreatCircleWayPoint,
                # finalWayPoint    = self.firstGlideSlopeWayPoint,
                finalWayPoint=self.touchDownWayPoint,
                initialHeadingDegrees=initialHeadingDegrees,
                aircraft=self.aircraft,
                reverse=False,
            )

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters()
            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfLastGreatCircleWayPoint, fixListIndex=self.flightListIndex
            )
            distanceToLastFixMeters = distanceStillToFlyMeters
            """ for the last turn => final heading towards the runway orientation """
            deltaTimeSeconds = 0.1
            turnLeg.buildTurnLeg(
                deltaTimeSeconds=deltaTimeSeconds,
                elapsedTimeSeconds=endOfLastGreatCircleWayPoint.getElapsedTimeSeconds(),
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters,
                finalHeadingDegrees=finalHeadingDegrees,
                lastTurn=True,
                bankAngleDegrees=5.0,
            )
            self.finalRoute.addGraph(turnLeg)

            endOfTurnLegWayPoint = self.finalRoute.getLastVertex().getWeight()
            """ ============= use touch-down way-point to compute distance to fly ============="""
            distanceStillToFlyMeters = endOfTurnLegWayPoint.getDistanceMetersTo(self.touchDownWayPoint)
            print self.className + ": distance still to fly= {0:.2f} nautics".format(
                distanceStillToFlyMeters * Meter2NauticalMiles
            )

            # print '==================== add descent slope ================= '
            descentGlideSlope = DescentGlideSlope(
                runway=self.arrivalRunway,
                aircraft=self.aircraft,
                arrivalAirport=self.arrivalAirport,
                descentGlideSlopeDegrees=3.0,
            )

            flownDistanceMeters = self.finalRoute.getLengthMeters()
            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters()
            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfTurnLegWayPoint, fixListIndex=self.flightListIndex
            )
            distanceToLastFixMeters = distanceStillToFlyMeters

            descentGlideSlope.buildGlideSlope(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfTurnLegWayPoint.getElapsedTimeSeconds(),
                initialWayPoint=endOfTurnLegWayPoint,
                flownDistanceMeters=flownDistanceMeters,
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters,
            )
            self.finalRoute.addGraph(descentGlideSlope)
            endOfDescentGlideSlope = self.finalRoute.getLastVertex().getWeight()

            # print '================= add arrival ground run ================'
            arrivalGroundRun = GroundRunLeg(
                runway=self.arrivalRunway, aircraft=self.aircraft, airport=self.arrivalAirport
            )
            arrivalGroundRun.buildArrivalGroundRun(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfDescentGlideSlope.getElapsedTimeSeconds(),
                initialWayPoint=endOfDescentGlideSlope,
            )
            self.finalRoute.addGraph(arrivalGroundRun)
예제 #6
0
          str(initialLeg.getBearingTailHeadDegrees()) + ' degrees')

    print(' ================== Take-Off V Stall Speed  =============== ')
    takeOffVStallSpeedMetersSecond = aircraft.computeStallSpeedCasKnots(
        aircraftConfiguration='Take-Off',
        airport=departureAirport) * Knots2MetersPerSecond
    print('take-off Vstall Kcas= ' + str(takeOffVStallSpeedMetersSecond) +
          ' meters per second')

    print(' ================== Departure Turn Leg  =============== ')

    departureTurnLeg = TurnLeg(
        initialWayPoint=endOfClimbRampWayPoint,
        finalWayPoint=finalArrivalDescentSlopeWayPoint,
        initialHeadingDegrees=lastClimbSlopeLeg.getBearingTailHeadDegrees(),
        finalHeadingDegrees=initialLeg.getBearingTailHeadDegrees(),
        trueAirSpeedMetersSecond=takeOffVStallSpeedMetersSecond,
        altitudeAboveSeaLevelMeters=endOfClimbRampWayPoint.
        getAltitudeMeanSeaLevelMeters(),
        reverse=False)

    departureTurnLeg.buildTurnLeg()

    print(
        ' =========== add Turn Leg to the Departure Climb Slope ============== '
    )
    climbSlope.addGraph(departureTurnLeg)
    #climbSlope.createKmlOutputFile()

    lastVertex = climbSlope.getVertex(climbSlope.getNumberOfVertices() - 1)
    lastWayPoint = lastVertex.getWeight()
    def buildSimulatedArrivalPhase(self):

        print self.className + "=========== add final turn, descent and ground run ==================="
        arrivalGroundRun = GroundRunLeg(runway=self.arrivalRunway, aircraft=self.aircraft, airport=self.arrivalAirport)
        self.touchDownWayPoint = arrivalGroundRun.computeTouchDownWayPoint()
        print self.touchDownWayPoint
        """ distance from last fix to touch down """
        distanceToLastFixNautics = (
            self.touchDownWayPoint.getDistanceMetersTo(self.getLastWayPoint()) * Meter2NauticalMiles
        )

        print self.className + "===================== final 3 degrees descending glide slope ================"
        descentGlideSlope = DescentGlideSlope(
            runway=self.arrivalRunway,
            aircraft=self.aircraft,
            arrivalAirport=self.arrivalAirport,
            descentGlideSlopeDegrees=3.0,
        )
        """ if there is a fix nearer to 5 nautics of the touch-down then limit size of simulated glide slope """
        descentGlideSlopeSizeNautics = min(distanceToLastFixNautics / 2.0, 5.0)
        """ build simulated glide slope """
        descentGlideSlope.buildSimulatedGlideSlope(descentGlideSlopeSizeNautics)
        self.firstGlideSlopeWayPoint = descentGlideSlope.getVertex(v=0).getWeight()
        print self.className + ": top of arrival glide slope= {0}".format(self.firstGlideSlopeWayPoint)

        print self.className + " ================= need a turn leg to find the junction point the last way-point in the fix list to the top of the final glide slope"
        """
        initial heading is the orientation of the run-way
        """
        lastFixListWayPoint = self.wayPointsDict[self.fixList[-1]]
        initialHeadingDegrees = self.arrivalRunway.getTrueHeadingDegrees()

        lastTurnLeg = TurnLeg(
            initialWayPoint=self.firstGlideSlopeWayPoint,
            finalWayPoint=lastFixListWayPoint,
            initialHeadingDegrees=initialHeadingDegrees,
            aircraft=self.aircraft,
            reverse=True,
        )
        lastTurnLeg.buildNewSimulatedArrivalTurnLeg(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=0.0,
            distanceStillToFlyMeters=0.0,
            simulatedAltitudeSeaLevelMeters=self.firstGlideSlopeWayPoint.getAltitudeMeanSeaLevelMeters(),
            flightPathAngleDegrees=3.0,
            bankAngleDegrees=5.0,
        )
        descentGlideSlope.addGraph(lastTurnLeg)
        # print self.className + ': compute arrival phase length= {0:.2f} meters'.format(descentGlideSlope.getLengthMeters())
        # descentGlideSlope.createXlsxOutputFile()
        # descentGlideSlope.createKmlOutputFile()
        """ prepare next step """
        beginOfLastTurnLeg = lastTurnLeg.getVertex(v=0).getWeight()
        print self.className + ": begin of last turn= {0}".format(beginOfLastTurnLeg)

        """ add the three last way-points in the fix list """
        self.insert(position="end", wayPoint=beginOfLastTurnLeg)
        """ update the length of the flight path """
        self.distanceFromApproachToTouchDownMeters = descentGlideSlope.getLengthMeters()
        self.flightLengthMeters = self.computeLengthMeters() + descentGlideSlope.getLengthMeters()
        print self.className + ": updated flight path length= {0:.2f} nautics".format(
            self.flightLengthMeters * Meter2NauticalMiles
        )
        """ target approach fix is equal to the begin of the SIMULATED last turn leg """
        self.aircraft.setTargetApproachWayPoint(beginOfLastTurnLeg)
        self.aircraft.setArrivalRunwayTouchDownWayPoint(self.touchDownWayPoint)
        print self.className + ": fix list= {0}".format(self.fixList)
    def turnAndFly(self, tailWayPoint, headWayPoint, initialHeadingDegrees, headWayPointIndex):
        """ 
        execute a turn to align true heading and then fly a great circle 
        """
        print " ================== one Turn Leg for each fix in the list =============== "
        turnLeg = TurnLeg(
            initialWayPoint=tailWayPoint,
            finalWayPoint=headWayPoint,
            initialHeadingDegrees=initialHeadingDegrees,
            aircraft=self.aircraft,
            reverse=False,
        )

        distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
            currentPosition=tailWayPoint, fixListIndex=headWayPointIndex
        )
        print self.className + ": distance to last fix= {0} nautics".format(
            distanceToLastFixMeters * Meter2NauticalMiles
        )
        distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters()
        print self.className + ": still to fly= {0} nautics".format(distanceStillToFlyMeters * Meter2NauticalMiles)

        endOfSimulation = turnLeg.buildTurnLeg(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=tailWayPoint.getElapsedTimeSeconds(),
            distanceStillToFlyMeters=distanceStillToFlyMeters,
            distanceToLastFixMeters=distanceToLastFixMeters,
        )
        self.finalRoute.addGraph(turnLeg)

        if endOfSimulation == False:
            print " ==================== end of turn leg  ==================== "

            endOfTurnLegWayPoint = self.finalRoute.getLastVertex().getWeight()
            lastLeg = self.finalRoute.getLastEdge()
            print self.className + ": end of turn orientation= {0:.2f} degrees".format(
                lastLeg.getBearingTailHeadDegrees()
            )

            """==================== check if anticipated turn or fly by is applicable """
            anticipatedTurnWayPoint = None
            if (self.flightListIndex + 2) < len(self.fixList):
                """ still another fix in the list """
                firstAngleDegrees = endOfTurnLegWayPoint.getBearingDegreesTo(headWayPoint)
                secondAngleDegrees = headWayPoint.getBearingDegreesTo(
                    self.wayPointsDict[self.fixList[self.flightListIndex + 2]]
                )
                firstAngleRadians = math.radians(firstAngleDegrees)
                secondAngleRadians = math.radians(secondAngleDegrees)

                angleDifferenceDegrees = math.degrees(
                    math.atan2(
                        math.sin(secondAngleRadians - firstAngleRadians),
                        math.cos(secondAngleRadians - firstAngleRadians),
                    )
                )
                print self.className + ": difference= {0:.2f} degrees".format(angleDifferenceDegrees)

                tasMetersPerSecond = self.aircraft.getCurrentTrueAirSpeedMetersSecond()
                radiusOfTurnMeters = (tasMetersPerSecond * tasMetersPerSecond) / (9.81 * math.tan(math.radians(15.0)))

                anticipatedTurnStartMeters = radiusOfTurnMeters * math.tan(
                    math.radians((180.0 - abs(angleDifferenceDegrees)) / 2.0)
                )
                print self.className + ": anticipated turn start from end point= {0:.2f} meters".format(
                    anticipatedTurnStartMeters
                )

                if (
                    endOfTurnLegWayPoint.getDistanceMetersTo(headWayPoint) > (1.1 * anticipatedTurnStartMeters)
                    and abs(angleDifferenceDegrees) > 30.0
                ):
                    print self.className + ": Envisage anticipated Fly By turn !!!!!!!!!!!!!!!!!!!!!!!!!"
                    bearingDegrees = math.fmod(firstAngleDegrees + 180.0, 360.0)
                    anticipatedTurnWayPoint = headWayPoint.getWayPointAtDistanceBearing(
                        Name="Anticipated-Turn-" + headWayPoint.getName(),
                        DistanceMeters=anticipatedTurnStartMeters,
                        BearingDegrees=bearingDegrees,
                    )
                    headWayPoint = anticipatedTurnWayPoint

            print " ==================== great circle ======================== "
            greatCircle = GreatCircleRoute(
                initialWayPoint=endOfTurnLegWayPoint, finalWayPoint=headWayPoint, aircraft=self.aircraft
            )

            distanceToLastFixMeters = self.computeDistanceToLastFixMeters(
                currentPosition=endOfTurnLegWayPoint, fixListIndex=headWayPointIndex
            )
            print self.className + ": distance to last fix= {0} nautics".format(
                distanceToLastFixMeters * Meter2NauticalMiles
            )

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters()
            print self.className + ": still to fly= {0} nautics".format(distanceStillToFlyMeters * Meter2NauticalMiles)

            endOfSimulation = greatCircle.computeGreatCircle(
                deltaTimeSeconds=self.deltaTimeSeconds,
                elapsedTimeSeconds=endOfTurnLegWayPoint.getElapsedTimeSeconds(),
                distanceStillToFlyMeters=distanceStillToFlyMeters,
                distanceToLastFixMeters=distanceToLastFixMeters,
            )
            """ update final route """
            self.finalRoute.addGraph(greatCircle)

            print " ================== end of great circle ================== "

            finalWayPoint = self.finalRoute.getLastVertex().getWeight()
            # print self.className + ': current end way point= ' + str(finalWayPoint)

            lastLeg = self.finalRoute.getLastEdge()
            finalHeadingDegrees = lastLeg.getBearingTailHeadDegrees()
            # print self.className + ': last leg orientation= {0:.2f} degrees'.format(finalHeadingDegrees)

            distanceStillToFlyMeters = self.flightLengthMeters - self.finalRoute.getLengthMeters()
            print self.className + ": still to fly= {0:.2f} meters - still to fly= {1:.2f} nautics".format(
                distanceStillToFlyMeters, distanceStillToFlyMeters * Meter2NauticalMiles
            )
            """ print the way point that has been passed right now """
            self.printPassedWayPoint(finalWayPoint)
        """ return to caller """
        return endOfSimulation, finalHeadingDegrees, finalWayPoint.getElapsedTimeSeconds(), anticipatedTurnWayPoint
    def test_turn_leg(self):
        print('==================== Turn Leg ==================== ' +
              time.strftime("%c"))

        print('==================== aircraft found  ==================== ' +
              time.strftime("%c"))

        self.aircraft.dump()

        print('==================== Get Airport ==================== ' +
              time.strftime("%c"))
        airportsDB = AirportsDatabase()
        assert airportsDB.read()

        print(
            '==================== Get Arrival Airport ==================== ' +
            time.strftime("%c"))
        Lisbonne = airportsDB.getAirportFromICAOCode('LPPT')
        print(Lisbonne)

        print('====================  find the run-ways ==================== ' +
              time.strftime("%c"))
        runWaysDatabase = RunWayDataBase()
        if runWaysDatabase.read():
            print('runways DB correctly read')

        print('====================  take off run-way ==================== ' +
              time.strftime("%c"))
        arrivalRunway = runWaysDatabase.getFilteredRunWays(
            airportICAOcode='LPPT', runwayName='')
        print(arrivalRunway)

        print('==================== Ground run ==================== ' +
              time.strftime("%c"))
        groundRun = GroundRunLeg(runway=arrivalRunway,
                                 aircraft=self.aircraft,
                                 airport=Lisbonne)

        touchDownWayPoint = groundRun.computeTouchDownWayPoint()
        print(touchDownWayPoint)
        groundRun.buildDepartureGroundRun(deltaTimeSeconds=1.0,
                                          elapsedTimeSeconds=0.0,
                                          distanceStillToFlyMeters=0.0,
                                          distanceToLastFixMeters=0.0)
        print('==================== Climb Ramp ==================== ' +
              time.strftime("%c"))

        initialWayPoint = groundRun.getLastVertex().getWeight()

        descentGlideSlope = DescentGlideSlope(runway=arrivalRunway,
                                              aircraft=self.aircraft,
                                              arrivalAirport=Lisbonne,
                                              descentGlideSlopeDegrees=3.0)
        ''' if there is a fix nearer to 5 nautics of the touch-down then limit size of simulated glide slope '''

        descentGlideSlope.buildSimulatedGlideSlope(
            descentGlideSlopeSizeNautics=5.0)
        descentGlideSlope.createKmlOutputFile()

        firstGlideSlopeWayPoint = descentGlideSlope.getVertex(v=0).getWeight()

        print('==================== Climb Ramp ==================== ' +
              time.strftime("%c"))
        initialWayPoint = groundRun.getLastVertex().getWeight()

        print(' ================== turn leg start =============== ')
        wayPointsDb = WayPointsDatabase()
        assert (wayPointsDb.read())
        Exona = wayPointsDb.getWayPoint('EXONA')
        Rosal = wayPointsDb.getWayPoint('ROSAL')

        print(Rosal.getBearingDegreesTo(Exona))
        initialHeadingDegrees = arrivalRunway.getTrueHeadingDegrees()

        lastTurnLeg = TurnLeg(initialWayPoint=firstGlideSlopeWayPoint,
                              finalWayPoint=Exona,
                              initialHeadingDegrees=initialHeadingDegrees,
                              aircraft=self.aircraft,
                              reverse=True)
        deltaTimeSeconds = 1.0
        lastTurnLeg.buildNewSimulatedArrivalTurnLeg(
            deltaTimeSeconds=deltaTimeSeconds,
            elapsedTimeSeconds=0.0,
            distanceStillToFlyMeters=0.0,
            simulatedAltitudeSeaLevelMeters=firstGlideSlopeWayPoint.
            getAltitudeMeanSeaLevelMeters(),
            flightPathAngleDegrees=3.0)
        lastTurnLeg.createKmlOutputFile()
        descentGlideSlope.addGraph(lastTurnLeg)
        descentGlideSlope.createXlsxOutputFile()
        descentGlideSlope.createKmlOutputFile()

        print(' ================== turn leg end =============== ')
    def test_turn_leg_fly_by_waypoint(self):
        wayPointsDb = WayPointsDatabase()
        assert (wayPointsDb.read())
        # Exona = wayPointsDb.getWayPoint('EXONA')
        # Rosal = wayPointsDb.getWayPoint('ROSAL')
        # Santa = wayPointsDb.getWayPoint('SANTA')

        p1 = wayPointsDb.getWayPoint('LAMSO')
        p2 = wayPointsDb.getWayPoint('EVELI')
        # p2 = wayPointsDb.getWayPoint('BASNO')
        # p3 = wayPointsDb.getWayPoint('PAMPUS')
        # ret = wayPointsDb.insertWayPoint('ENKOS', "N31°40'58.50" + '"', "N31°40'58.50" + '"')
        # ret = wayPointsDb.insertWayPoint('ENKOS', "N52°40'41.26" + '"', "E5°14'35.75" + '"')
        # if wayPointsDb.hasWayPoint('ENKOS'):
        #     self.assertFalse(ret, 'insertion not done')
        #     exit(1)
        # else:
        #     self.assertTrue(ret, 'insertion correct')
        p3 = wayPointsDb.getWayPoint('ENKOS')

        print(p1)
        print(p2)
        print(p3)
        # print(p4)

        self.aircraft.aircraftCurrentConfiguration = 'cruise'

        self.aircraft.initStateVector(
            elapsedTimeSeconds=0.0,
            trueAirSpeedMetersSecond=70.0,
            airportFieldElevationAboveSeaLevelMeters=10000.0)

        self.aircraft.setTargetCruiseFlightLevel(
            RequestedFlightLevel=310, departureAirportAltitudeMSLmeters=0.0)

        greatCircle = GreatCircleRoute(initialWayPoint=p1,
                                       finalWayPoint=p2,
                                       aircraft=self.aircraft)

        distanceStillToFlyMeters = p1.getDistanceMetersTo(p2)
        greatCircle.computeGreatCircle(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=p1.getElapsedTimeSeconds(),
            distanceStillToFlyMeters=distanceStillToFlyMeters,
            distanceToLastFixMeters=distanceStillToFlyMeters)
        finalRoute = greatCircle

        initialHeadingDegrees = p1.getBearingDegreesTo(p2)
        turn_leg = TurnLeg(initialWayPoint=p2,
                           finalWayPoint=p3,
                           initialHeadingDegrees=initialHeadingDegrees,
                           aircraft=self.aircraft,
                           reverse=False)

        last_gc_vertex = finalRoute.getLastVertex().getWeight()
        distance_to_fly = last_gc_vertex.getDistanceMetersTo(p3)
        turn_leg.buildTurnLeg(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=last_gc_vertex.getElapsedTimeSeconds(),
            distanceStillToFlyMeters=distance_to_fly,
            distanceToLastFixMeters=distance_to_fly)
        finalRoute.addGraph(turn_leg)

        last_turn_leg_vertex = turn_leg.getLastVertex().getWeight()
        # last_turn_leg_vertex = p2
        greatCircle2 = GreatCircleRoute(initialWayPoint=last_turn_leg_vertex,
                                        finalWayPoint=p3,
                                        aircraft=self.aircraft)
        distanceStillToFlyMeters = last_turn_leg_vertex.getDistanceMetersTo(p3)
        greatCircle2.computeGreatCircle(
            deltaTimeSeconds=self.deltaTimeSeconds,
            elapsedTimeSeconds=last_turn_leg_vertex.getElapsedTimeSeconds(),
            distanceStillToFlyMeters=distanceStillToFlyMeters,
            distanceToLastFixMeters=distanceStillToFlyMeters)
        finalRoute.addGraph(greatCircle2)

        finalRoute.createKmlOutputFile()
        finalRoute.createXlsxOutputFile()
        self.aircraft.createStateVectorOutputFile(
            filePrefix='turn-leg-great-circle')
        aircraft = BadaAircraft(aircraftIcaoCode, 
                                      acBd.getAircraftPerformanceFile(aircraftIcaoCode),
                                      atmosphere,
                                      earth)
        aircraft.dump()
    
        takeOffMassKilograms = 64000.0
        aircraft.setAircraftMassKilograms(takeOffMassKilograms)
            
        RequestedFlightLevel = 310.0
        fieldElevationAboveSeaLevelMeters = 150.0
        aircraft.setTargetCruiseFlightLevel(RequestedFlightLevel, fieldElevationAboveSeaLevelMeters)
        tasMetersPerSecond = tasKnots * Knots2MetersPerSecond
        aircraft.initStateVector(elapsedTimeSeconds = 0.0, 
                                     trueAirSpeedMetersSecond = tasMetersPerSecond, 
                                     altitudeMeanSeaLevelMeters = 3000.0 * Meter2Feet, 
                                     deltaDistanceFlownMeters = 0.0)
        aircraft.setCruiseConfiguration(elapsedTimeSeconds = 0.0)
            
        turnLeg =  TurnLeg(  initialWayPoint  = departureAirport,
                                finalWayPoint    = arrivalAirport,
                                initialHeadingDegrees = 215.0,
                                finalHeadingDegrees = 180.0,
                                aircraft = aircraft,
                                reverse = False)
        
        distanceStillToFlyMeters = 700000.0
        turnLeg.buildTurnLeg(elapsedTimeSeconds = 0.0, distanceStillToFlyMeters = distanceStillToFlyMeters)
        turnLeg.createKmlOutputFile()
        turnLeg.createXlsxOutputFile()