def smarterEndPosition(posn_begin, posn_end): # instead of targeting arrival airport, target a closer pt just inside the arrival area (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end ) = posn_end dist_begin_end = gcUtils.gcDistNMile( (lat_begin,lon_begin), (lat_end,lon_end) ) dist_end_smarterend = min(ARRIVAL_RADIUS, dist_begin_end) * ARRIVAL_RADIUS_SHRINKAGE lat_smarter, lon_smarter = gcUtils.gcPtAtDistance( (lat_end,lon_end), (lat_begin,lon_begin), dist_end_smarterend, gcUtils.EARTH_RADIUS_NM ) alt_smarter = ARRIVAL_ALTITUDE posn_smarterend = (lat_smarter, lon_smarter, alt_smarter) return posn_smarterend
def directDescend(posn_begin, posn_end, npts, flightModel): (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end) = posn_end #assert alt_begin >= alt_end dist = gcUtils.gcDistNMile((lat_begin, lon_begin), (lat_end, lon_end)) slope = (alt_begin - alt_end) / dist flightModel.setCustomDescentSlope(slope) return moveAirplane(posn_begin, posn_end, npts, flightModel.customDescentAlt, flightModel.airspeed, altMinMax=(alt_end, alt_begin))
def intersectPosition(posn_begin, slope_begin, posn_end, slope_end): # finds intersection position of 2 lines in the GC path plane between 2 points (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end) = posn_end dist_begin_to_end = gcUtils.gcDistNMile((lat_begin, lon_begin), (lat_end, lon_end)) intercept_begin = alt_begin - slope_begin * dist_begin_to_end intercept_end = alt_end - slope_end * 0.0 dist_intersect, alt_intersect = lineLineIntersectionPt( slope_begin, intercept_begin, slope_end, intercept_end) dist_from_begin = dist_intersect dist_from_end = dist_begin_to_end - dist_from_begin lat_intersect, lon_intersect = gcUtils.gcPtAtDistance( (lat_begin, lon_begin), (lat_end, lon_end), dist_from_end, gcUtils.EARTH_RADIUS_NM) return (lat_intersect, lon_intersect, alt_intersect)
def classifyZone(posn_begin, posn_end, flightModel): # classify current position into one of 4 zones; useful for picking a flightpath (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end) = posn_end dist_to_end = gcUtils.gcDistNMile((lat_begin, lon_begin), (lat_end, lon_end)) cruise_alt = flightModel.cruiseIntercept direct_descent_slope = float(alt_begin - alt_end) / dist_to_end if direct_descent_slope > abs(flightModel.descentSlope): return 'near-high' # short-range, high-altitude (over/near airport) elif alt_begin > cruise_alt: return 'far-high' # long-range, high-altitude elif cruisePossible(posn_begin, posn_end, flightModel): return 'far-low' # long-range, low-altitude else: return 'near-low' # short-range, low-altitude (no cruise leg)
def positionCruiseEnd(posn_begin, posn_end, flightModel): # Returns the position directly above the airport (posn_end) if # the plane cruised there from the current position (posn_begin) # at *cruise* altitude (not the current altitude) # Note: plane may climb slowly, reflecting optimal cruise altitude # varies as plane burns off fuel and gets lighter. # Why do we need this point? It's useful for defining a line (cruise path) # that intersects a ascent/descent line from the current position. # That intersection is where the plane should start cruising. (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end) = posn_end dist_begin = gcUtils.gcDistNMile((lat_begin, lon_begin), (lat_end, lon_end)) dist_end = 0.0 # dist to endpoint is 0 when at endpoint alt_cruise = flightModel.cruiseIntercept alt_end = flightModel.cruiseAlt(alt_cruise, dist_begin, dist_end) return (lat_end, lon_end, alt_end)
def moveAirplane(posn_begin, posn_end, npts, altVsDistModel, airspeedVsAltModel, altMinMax=None): # create intermediate position waypoints between two other waypoints # print "moveAirplane:", posn_begin, "-->", posn_end (lat_begin, lon_begin, alt_begin) = posn_begin (lat_end, lon_end, alt_end) = posn_end dist_begin = gcUtils.gcDistNMile((lat_begin, lon_begin), (lat_end, lon_end)) if dist_begin < WAYPOINT_ARRIVAL_RADIUS: return noWaypoints(posn_begin, posn_end, npts, flightModel=None) pts = gcUtils.gcIntermediate((lat_begin, lon_begin), (lat_end, lon_end), npts) # tricky: zip(*pts) unzips intermediate points with format # [(lat1,lon1),(lat2,lon2),...] into (lat1, lat2...), (lon1, lon2...) lats, lons = zip(*pts) dists = [ dist_begin * (1. - frac) for frac in gcUtils.intermediateFracs(npts) ] alts = [altVsDistModel(alt_begin, dist_begin, d) for d in dists] if altMinMax: altMin, altMax = min(altMinMax), max(altMinMax) alts = [max(altMin, min(altMax, alt)) for alt in alts] airspeeds = [airspeedVsAltModel(alt) for alt in alts] lats = tuple(lats) + (lat_end, ) lons = tuple(lons) + (lon_end, ) alts = tuple(alts) + (alt_end, ) airspeeds = tuple(airspeeds) + (airspeedVsAltModel(alt_end), ) waypoints = { 'LatitudeDegrees': lats, 'LongitudeDegrees': lons, 'AltitudeFeet': alts, 'AirspeedKnots': airspeeds } return waypoints