def new_arrival_GND(self): acft_type = choice(self.parkable_aircraft_types) rwy = rnd_rwy([ rwy for rwy in env.airport_data.allRunways() if rwy.use_for_arrivals ], lambda rwy: rwy.acceptsAcftType(acft_type)) if rwy == None: return None turn_off_lists = l1, l2, l3, l4 = env.airport_data.ground_net.runwayTurnOffs( rwy, minroll=(rwy.length(dthr=True) * 2 / 3)) for lst in turn_off_lists: pop_all( lst, lambda t: not self.groundPositionFullySeparated( env.airport_data.ground_net.nodePosition(t[1]), acft_type)) if all(lst == [] for lst in turn_off_lists): return None else: turn_off_choice = choice(l1) if l1 != [] else (l2 + l3)[0] pos = env.airport_data.ground_net.nodePosition(turn_off_choice[1]) hdg = rwy.orientation() + turn_off_choice[3] params = SoloParams(Status(Status.TAXIING), pos, env.groundStdPressureAlt(pos), hdg, Speed(0)) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_ARR) pk_request = choice( env.airport_data.ground_net.parkingPositions(acftType=acft_type)) return self.mkAiAcft(acft_type, params, pk_request)
def new_departure_DEP(self, goal_point): acft_type = choice( self.parkable_aircraft_types if self.parkable_aircraft_types != [] else self.playable_aircraft_types) rwy = rnd_rwy([ rwy for rwy in env.airport_data.allRunways() if rwy.use_for_departures ], lambda rwy: rwy.acceptsAcftType(acft_type)) if rwy == None: return None thr = rwy.threshold() hdg = rwy.orientation() pos = thr.moved(hdg, settings.solo_TWR_range_dist) try: # Check for separation horiz_dist = [ pos.distanceTo(acft.params.position) for acft in self.controlled_traffic if acft.isOutboundGoal() ] if time_to_fly(min(horiz_dist), cruise_speed(acft_type)) < TTF_separation: return None except ValueError: pass # No departures in the sky yet alt = GS_alt(env.elevation(thr), rwy.param_FPA, pos.distanceTo(thr)) ias = restrict_speed_under_ceiling(cruise_speed(acft_type), alt, StdPressureAlt.fromFL(100)) params = SoloParams(Status(Status.AIRBORNE), pos, alt, hdg, ias) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_DEP) acft = self.mkAiAcft(acft_type, params, (goal_point, None)) acft.instructions.append( Instruction(Instruction.VECTOR_ALT, arg=settings.solo_initial_climb_reading)) return acft
def selectXpdrRange(self, row): if row != 0: name = self.xpdrRange_select.itemText(row) assignment_range = next(r for r in settings.XPDR_assignment_ranges if r != None and r.name == name) self.xpdrCode_edit.setValue( env.nextSquawkCodeAssignment(assignment_range)) self.xpdrRange_select.setCurrentIndex(0) self.xpdrCode_edit.setFocus()
def new_departure_GND(self, goal_point): acft_type = choice(self.parkable_aircraft_types) gn = env.airport_data.ground_net pk = [ p for p in gn.parkingPositions(acftType=acft_type) if self.groundPositionFullySeparated(gn.parkingPosition(p), acft_type) ] if pk == []: return None pkinfo = env.airport_data.ground_net.parkingPosInfo(choice(pk)) params = SoloParams(Status(Status.TAXIING), pkinfo[0], env.groundStdPressureAlt(pkinfo[0]), pkinfo[1], Speed(0)) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_DEP) return self.mkAiAcft(acft_type, params, (goal_point, None))
def new_departure_TWR(self, goal_point): acft_type = choice( self.parkable_aircraft_types if self.parkable_aircraft_types != [] else self.playable_aircraft_types) rwy = rnd_rwy([ rwy for rwy in env.airport_data.allRunways() if rwy.use_for_departures ], lambda rwy: rwy.acceptsAcftType(acft_type)) if rwy == None: return None hdg = rwy.orientation() + 60 pos = rwy.threshold(dthr=True).moved( hdg.opposite(), .04) # FUTURE use turn-offs backwards when ground net present params = SoloParams(Status(Status.READY, arg=rwy.name), pos, env.groundStdPressureAlt(pos), hdg, Speed(0)) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_DEP) return self.mkAiAcft(acft_type, params, (goal_point, None))
def new_arrival_TWR(self): acft_type = choice( self.parkable_aircraft_types if self.parkable_aircraft_types != [] else self.playable_aircraft_types) ils = random() >= settings.solo_ILSvsVisual_balance rwy_ok = lambda rwy: rwy.acceptsAcftType(acft_type) and (not ils or rwy .hasILS()) rwy = rnd_rwy([ rwy for rwy in env.airport_data.allRunways() if rwy.use_for_arrivals ], rwy_ok) if rwy == None: return None dthr = rwy.threshold(dthr=True) try: furthest = max([ dthr.distanceTo(acft.params.position) for acft in self.controlled_traffic if acft.isInboundGoal() ]) dist = max( furthest + uniform(1, 2) * distance_flown(TTF_separation, cruise_speed(acft_type)), settings.solo_TWR_range_dist) except ValueError: dist = settings.solo_TWR_range_dist / 2 if dist > min(settings.solo_TWR_range_dist * 1.5, settings.radar_range - 10): return None # to protect from creating aircraft out of radar range status = Status(Status.LANDING, arg=rwy.name) if ils else Status( Status.AIRBORNE) hdg = rwy.appCourse() alt = GS_alt(env.elevation(dthr), rwy.param_FPA, max(2, dist if ils else dist - 2)) params = SoloParams(status, env.radarPos().moved(hdg.opposite(), dist), alt, hdg, touch_down_speed(acft_type)) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_ARR) acft = self.mkAiAcft(acft_type, params, ils) acft.instructions.append( Instruction(Instruction.EXPECT_RWY, arg=rwy.name)) if ils: acft.instructions.append(Instruction(Instruction.CLEARED_APP)) return acft
def new_arrival_APP(self, entry_point): type_choice = self.parkable_aircraft_types if self.parkable_aircraft_types != [] else self.playable_aircraft_types # must be landable too rwy_choice = [ rwy for rwy in env.airport_data.allRunways() if rwy.use_for_arrivals ] if rwy_choice == []: rwy_choice = env.airport_data.allRunways() pop_all( type_choice, lambda t: all(not rwy.acceptsAcftType(t) for rwy in rwy_choice)) if type_choice == []: return None acft_type = choice(type_choice) ils = any(rwy.hasILS() for rwy in rwy_choice) and random() >= settings.solo_ILSvsVisual_balance if entry_point == None: hdg = Heading(randint(1, 360), True) pos = env.radarPos().moved( hdg.opposite(), uniform(.33 * settings.radar_range, .75 * settings.radar_range)) else: pos = entry_point.coordinates hdg = pos.headingTo(env.radarPos()) alt = StdPressureAlt.fromFL( 10 * randint(settings.solo_APP_ceiling_FL_min // 10, settings.solo_APP_ceiling_FL_max // 10)) if not self.airbornePositionFullySeparated(pos, alt): return None ias = restrict_speed_under_ceiling( cruise_speed(acft_type), alt, StdPressureAlt.fromFL(150)) # 5000-ft anticipation params = SoloParams(Status(Status.AIRBORNE), pos, alt, hdg, ias) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_ARR) return self.mkAiAcft(acft_type, params, ils)
def generateAircraftAndStrip(self): start_angle = uniform(0, 360) start_pos = env.radarPos().moved(Heading(start_angle, True), settings.solo_CTR_range_dist) end_pos = env.radarPos().moved( Heading(start_angle + 90 + uniform(1, 179), True), settings.solo_CTR_range_dist) transit_hdg = start_pos.headingTo(end_pos) dep_ad = world_navpoint_db.findClosest(env.radarPos().moved(transit_hdg.opposite(), \ uniform(1.2 * settings.map_range, 5000)), types=[Navpoint.AD]) dest_ad = world_navpoint_db.findClosest(env.radarPos().moved(transit_hdg, \ uniform(1.2 * settings.map_range, 5000)), types=[Navpoint.AD]) if env.pointOnMap(dep_ad.coordinates) or env.pointOnMap( dest_ad.coordinates): return None, None candidate_midpoints = [p for code in settings.solo_CTR_routing_points \ for p in env.navpoints.findAll(code, types=[Navpoint.NDB, Navpoint.VOR, Navpoint.FIX]) \ if start_pos.distanceTo(p.coordinates) < start_pos.distanceTo(end_pos)] midpoint = None if candidate_midpoints == [] else choice( candidate_midpoints) FLd10 = randint(settings.solo_CTR_floor_FL // 10, settings.solo_CTR_ceiling_FL // 10) if settings.solo_CTR_semi_circular_rule == SemiCircRule.E_W and (FLd10 % 2 == 0) != (transit_hdg.magneticAngle() >= 180) \ or settings.solo_CTR_semi_circular_rule == SemiCircRule.N_S and (FLd10 % 2 == 1) != (90 <= transit_hdg.magneticAngle() < 270): FLd10 += 1 if 10 * FLd10 > settings.solo_CTR_ceiling_FL: return None, None p_alt = StdPressureAlt.fromFL(10 * FLd10) if not self.airbornePositionFullySeparated(start_pos, p_alt): return None, None acft_type = choice(self.playable_aircraft_types) hdg = start_pos.headingTo(some(midpoint, dest_ad).coordinates) params = SoloParams(Status(Status.AIRBORNE), start_pos, p_alt, hdg, cruise_speed(acft_type)) params.XPDR_code = env.nextSquawkCodeAssignment(XPDR_range_IFR_transit) new_acft = self.mkAiAcft(acft_type, params, dest_ad) dist_key = lambda atc: env.ATCs.getATC(atc).position.distanceTo( start_pos) received_from = min(env.ATCs.knownATCs(), key=dist_key) strip = Strip() strip.writeDetail(FPL.CALLSIGN, new_acft.identifier) strip.writeDetail(FPL.ACFT_TYPE, new_acft.aircraft_type) strip.writeDetail(FPL.WTC, wake_turb_cat(new_acft.aircraft_type)) strip.writeDetail(FPL.FLIGHT_RULES, 'IFR') strip.writeDetail(FPL.ICAO_DEP, dep_ad.code) strip.writeDetail(FPL.ICAO_ARR, dest_ad.code) strip.writeDetail(FPL.CRUISE_ALT, env.readStdAlt(new_acft.params.altitude)) strip.writeDetail(assigned_altitude_detail, strip.lookup(FPL.CRUISE_ALT)) strip.writeDetail(assigned_SQ_detail, new_acft.params.XPDR_code) strip.writeDetail(received_from_detail, received_from) if midpoint != None: strip.insertRouteWaypoint(midpoint) new_acft.instructions.append( Instruction(Instruction.FOLLOW_ROUTE, arg=strip.lookup(parsed_route_detail).dup())) return new_acft, strip