Esempio n. 1
0
 def __init__(self, parent=None):
     QWidget.__init__(self, parent)
     self.setupUi(self)
     if env.airport_data != None:
         self.runway_select.addItems(
             [r.name for r in env.airport_data.allRunways(sortByName=True)])
     self.setEnabled(False)
     self.target_acft = None
     self.tracker = TelnetSessionThreader(
         self,
         self.lookAtTargetAircraft_commands,
         loopInterval=tracker_interval)
     signals.towerViewProcessToggled.connect(self.setEnabled)
     signals.towerViewProcessToggled.connect(self.tracker.stop)
     signals.sessionEnded.connect(self.tracker.stop)
     signals.mainWindowClosing.connect(self.tracker.stop)
     self.lookAtAircraft_OK_button.clicked.connect(
         self.lookAtSelectedAircraft)
     self.lookAtRunway_OK_button.clicked.connect(self.lookAtRunway)
     self.lookNorth_button.clicked.connect(
         lambda: self.lookInDirection(Heading(360, true_panel_directions)))
     self.lookSouth_button.clicked.connect(
         lambda: self.lookInDirection(Heading(180, true_panel_directions)))
     self.lookEast_button.clicked.connect(
         lambda: self.lookInDirection(Heading(90, true_panel_directions)))
     self.lookWest_button.clicked.connect(
         lambda: self.lookInDirection(Heading(270, true_panel_directions)))
     self.useBinoculars_button.clicked.connect(lambda: self.setFOV(
         initial_FOV / self.binocularsFactor_edit.value()))
     self.dropBinoculars_button.clicked.connect(
         lambda: self.setFOV(initial_FOV))
Esempio n. 2
0
    def windVariability(self):
        '''
		returns wind variability (Heading, Heading) if present, None otherwise
		'''
        match = wind_hdgvrb_regexp.search(self.METAR_string)
        if match:
            return Heading(int(match.group(1)),
                           False), Heading(int(match.group(2)), False)
        return None
 def spawnNewUncontrolledAircraft(self):
     rndpos = env.radarPos().moved(Heading(randint(1, 360), True),
                                   uniform(10, .8 * settings.radar_range))
     rndalt = StdPressureAlt(randint(1, 10) * 1000)
     if self.airbornePositionFullySeparated(rndpos, rndalt):
         acft_type = choice(self.uncontrolled_aircraft_types)
         params = SoloParams(Status(Status.AIRBORNE), rndpos, rndalt,
                             Heading(randint(1, 360), True),
                             cruise_speed(acft_type))
         params.XPDR_code = settings.uncontrolled_VFR_XPDR_code
         new_acft = self.mkAiAcft(acft_type, params, goal=None)
         if new_acft != None:
             self.uncontrolled_traffic.append(new_acft)
Esempio n. 4
0
    def mainWind(self):
        '''
		Returns a (heading, speed, gusts, unit) tuple, where:
		- heading & speed values are:
			- None, 0: wind is calm
			- None, int: wind is VRB
			- Heading, int: wind has dominant direction
		- and:
			- gusts is None or int speed
			- unit is either 'kt' or 'm/s', following that used in the METAR
		'''
        match = wind_regexp.search(self.METAR_string)
        if match:
            if match.group('gusts') == None:
                gusts = None
            else:
                gusts = int(match.group('gusts'))
            unit = {'KT': 'kt', 'MPS': 'm/s'}[match.group('unit')]
            if match.group('speed_vrb') == None:  # got dominant direction
                wind_speed = int(match.group('speed_nrm'))
                return (Heading(int(match.group('hdg')), True)
                        if wind_speed != 0 else None), wind_speed, gusts, unit
            else:  # wind is VRB
                return None, int(match.group('speed_vrb')), gusts, unit
        return None
def str2detail(dstr, vstr):
    try:
        d = int(
            dstr
        )  # CAUTION this assumes there is no str detail key that looks like an int
    except ValueError:
        d = dstr
    if d in [FPL.CALLSIGN, FPL.ACFT_TYPE, FPL.WTC, FPL.ICAO_DEP, FPL.ICAO_ARR, FPL.ICAO_ALT, \
      FPL.CRUISE_ALT, FPL.ROUTE, FPL.COMMENTS, FPL.FLIGHT_RULES, assigned_altitude_detail]: # str
        v = vstr
    elif d in [FPL.SOULS, assigned_SQ_detail]:  # int
        v = int(vstr)
    elif d in [FPL.TAS, assigned_speed_detail]:  # Speed
        v = Speed(int(vstr))
    elif d == FPL.TIME_OF_DEP:  # datetime
        year, month, day, hour, minute = vstr.split()
        v = datetime(year=int(year),
                     month=int(month),
                     day=int(day),
                     hour=int(hour),
                     minute=int(minute),
                     tzinfo=timezone.utc)
    elif d == FPL.EET:  # timedelta
        v = timedelta(seconds=int(vstr))
    elif d == assigned_heading_detail:  # Heading
        v = Heading(int(vstr), False)
    else:
        raise ValueError('Unknown key for detail conversion: %s' % dstr)
    return d, v
    def headingTo(self, other):
        '''
		this gives the heading of route from self to other, using cartesian approx. of both radar coords
		'''
        dx = other.x() - self.x()
        dy = other.y() - self.y()
        theta = atan2(dx, dy)
        return Heading(degrees(pi - theta), True)
 def start(self, traffic_count):  # overrides (but calls) parent's
     p = lambda d: env.radarPos().moved(Heading(d, True), 1.5 * settings.
                                        map_range)
     env.ATCs.updateATC('N', p(360), 'North', None)
     env.ATCs.updateATC('S', p(180), 'South', None)
     env.ATCs.updateATC('E', p(90), 'East', None)
     env.ATCs.updateATC('W', p(270), 'West', None)
     SoloSessionManager.start(self, traffic_count)
def get_airport_data(icao):
    result = AirportData()
    result.navpoint = world_navpoint_db.findAirfield(icao)

    # START WITH SIMPLE ONE-LINERS
    with open_airport_file(icao) as f:
        for line in f:
            row_type = line_code(line)

            if is_xplane_airport_header(line):  # HEADER LINE; get elevation
                tokens = line.split(maxsplit=2)
                result.field_elevation = float(tokens[1])

            elif row_type == 100:  # RUNWAY
                tokens = line.split()
                width = float(tokens[1])
                surface = int(tokens[2])
                name, lat, lon, disp_thr = tokens[8:12]
                rwy1 = DirRunway(name, EarthCoords(float(lat), float(lon)),
                                 float(disp_thr))
                name, lat, lon, disp_thr = tokens[17:21]
                rwy2 = DirRunway(name, EarthCoords(float(lat), float(lon)),
                                 float(disp_thr))
                result.addPhysicalRunway(width, surface, rwy1, rwy2)

            elif row_type == 102:  # HELIPAD
                tokens = line.split()
                row_code, name, lat, lon, ori, l, w, surface = tokens[:8]
                centre = EarthCoords(float(lat), float(lon))
                result.helipads.append(
                    Helipad(name, centre, int(surface), float(l), float(w),
                            Heading(float(ori), True)))

            elif row_type == 14:  # VIEWPOINT (NOTE: ATC-pie allows for more than one, though X-plane specifies one or zero)
                row_code, lat, lon, height, ignore, name = line.split(
                    maxsplit=5)
                result.viewpoints.append(
                    (EarthCoords(float(lat),
                                 float(lon)), float(height), name.strip()))

            elif row_type == 19:  # WINDSOCK
                row_code, lat, lon, ignore_rest_of_line = line.split(
                    maxsplit=3)
                result.windsocks.append(EarthCoords(float(lat), float(lon)))

            elif row_type == 1302:  # METADATA RECORD
                tokens = line.split()
                if len(tokens) == 3 and tokens[1] == 'transition_alt':
                    result.transition_altitude = int(tokens[2])

    # NOW COMPLEX MULTI-LINE READS
    result.ground_net = get_ground_network(icao)

    return result
    def headingTo(self, other):
        '''
		this gives the initial heading of route from self to other
		that follows the shortest path (on great circle, i.e. as the crow flies)
		'''
        lat1 = radians(self.lat)
        lat2 = radians(other.lat)
        dlon = radians(other.lon - self.lon)
        theta = atan2(
            sin(dlon) * cos(lat2),
            cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon))
        return Heading(degrees(theta), True)
def import_ILS_capabilities(airport_data):
    with open_data_file_fallback(custom_navaid_file,
                                 fallback_navaid_file) as f:
        for line in f:
            # all lines with ILS codes [4..9] have similar structure:
            tokens = line.split(maxsplit=10)
            if not (len(tokens) == 11 and tokens[0] in '456789'):
                continue
            row_code, lat, lon, elev, frq, rng, qdm, ignore, ad, rwy, last_to_strip = tokens
            if ad == airport_data.navpoint.code:
                try:
                    drwy = airport_data.runway(rwy)
                    coords = EarthCoords(float(lat), float(lon))
                except KeyError:  # unknown RWY
                    print('Unknown RWY %s or bad LOC spec' % rwy)
                else:  # we are interested in the line spec
                    if row_code in ['4', '5']:  # LOC
                        drwy.ILS_cat = last_to_strip.strip()
                        drwy.LOC_freq = '%s.%s' % (frq[:3], frq[3:])
                        drwy.LOC_bearing = Heading(float(qdm), True)
                        drwy.LOC_range = drwy.threshold(dthr=True).distanceTo(
                            coords.moved(drwy.LOC_bearing.opposite(),
                                         float(rng)))
                    elif row_code == '6':  # GS (angle prefixes the bearing)
                        try:
                            iqdm = qdm.index('.') - 3
                        except ValueError:
                            iqdm = len(qdm) - 3
                        fpa_degrees = int(qdm[:iqdm]) / 100
                        drwy.param_FPA = 100 * tan(radians(fpa_degrees))
                        drwy.GS_range = drwy.threshold(dthr=True).distanceTo(
                            coords.moved(
                                Heading(float(qdm[iqdm:]), True).opposite(),
                                float(rng)))
                    elif row_code == '7':  # OM
                        drwy.OM_pos = coords
                    elif row_code == '8':  # MM
                        drwy.MM_pos = coords
                    elif row_code == '9':  # IM
                        drwy.IM_pos = coords
def open_ad_positions_file():
    try:
        return open(custom_ad_pos_file, encoding='utf8')
    except FileNotFoundError:  # No custom airfield position file found; fall back on extracted X-plane inventory.
        try:
            return open(extracted_ad_pos_file, encoding='utf8')
        except FileNotFoundError:  # Airport positions not extracted yet; build file from packaged X-plane world file.
            with open(fallback_world_apt_dat_file, encoding='iso-8859-15'
                      ) as f:  # WARNING: X-plane data encoded in ISO-8859-15
                with open(extracted_ad_pos_file, 'w', encoding='utf8') as exf:
                    line = f.readline()
                    ad_count = 0
                    while line != '':  # not EOF
                        if is_xplane_airport_header(line):
                            row_code, ignore1, ignore2, ignore3, icao_code, long_name = line.split(
                                maxsplit=5)
                            if icao_code.isalpha(
                            ):  # Ignoring airports with numbers in them---to many of them, hardly ever useful
                                # we are inside the airport section looking for its coordinates
                                coords = None
                                line = f.readline()
                                while line != '' and not is_xplane_airport_header(
                                        line):
                                    if line_code(
                                            line
                                    ) == 14:  # X-plane viewpoint, unconditionally used as coords
                                        row_code, lat, lon, ignore_rest_of_line = line.split(
                                            maxsplit=3)
                                        coords = EarthCoords(
                                            float(lat), float(lon))
                                    elif coords == None and line_code(
                                            line
                                    ) == 100:  # falls back near a RWY end if no viewpoint for AD
                                        tokens = line.split()
                                        coords = EarthCoords(
                                            float(tokens[9]),
                                            float(tokens[10])).moved(
                                                Heading(360, True), .15)
                                    line = f.readline()
                                if coords != None:  # Airfields with unknown world coordinates are ignored
                                    exf.write('%s %s %s\n' %
                                              (icao_code, coords.toString(),
                                               long_name.strip()))
                                    ad_count += 1
                            else:
                                line = f.readline()
                        else:
                            line = f.readline()
                    # Terminate with the footer to mark a finished process
                    exf.write('%d\n' % ad_count)
            # Now file should exist
            return open(extracted_ad_pos_file, encoding='utf8')
Esempio n. 12
0
 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 get_ground_network(icao):
    with open_airport_file(icao) as f:
        ground_net = GroundNetwork()
        source_edges = [
        ]  # GroundNetwork pretty labelling breaks if we add duplicate edges
        line = f.readline()
        line_number = 1
        while line != '':  # not EOF
            if line_code(line) == 1201:  # TWY node
                tokens = line.strip().split(maxsplit=5)
                lat, lon, ignore, nid = tokens[1:5]
                ground_net.addNode(nid, EarthCoords(float(lat), float(lon)))
            elif line_code(line) == 1202:  # TWY edge
                tokens = line.strip().split(maxsplit=5)
                v1, v2 = tokens[1:3]
                twy_name = rwy_spec = None
                if len(tokens) == 6:
                    if tokens[4] == 'runway':
                        rwy_spec = tokens[5].rstrip()
                    elif tokens[4].startswith(
                            'taxiway'
                    ):  # can be suffixed with "_X" to specify wing span
                        twy_name = tokens[5].rstrip()
                if {v1, v2} in source_edges:
                    print(
                        'WARNING: Ignoring duplicate ground route edge (%s, %s) in airport data file.'
                        % (v1, v2))
                else:
                    source_edges.append({v1, v2})
                    try:
                        ground_net.addEdge(v1, v2, rwy_spec, twy_name)
                    except KeyError:
                        print('Line %d: Invalid node for taxiway edge spec' %
                              line_number)
            elif line_code(line) == 1300:  # parking_position
                tokens = line.strip().split(maxsplit=6)
                if len(tokens) == 7:
                    lat, lon, hdg, typ, who, pkid = tokens[1:7]
                    if typ in ['gate', 'hangar', 'tie-down']:
                        pos = EarthCoords(float(lat), float(lon))
                        cats = [] if who == 'all' else who.split('|')
                        ground_net.addParkingPosition(
                            pkid, pos, Heading(float(hdg), True), typ, cats)
                else:
                    print('Line %d: Invalid parking position spec' %
                          line_number)
            line = f.readline()  # for new loop (more TWYs)
            line_number += 1
        return ground_net
Esempio n. 14
0
def rnd_rwy(choose_from, condition):
    '''
	Picks a runway from the first arg list (or any by wind if empty), satisfying the given condition.
	'''
    if choose_from == []:  # Choose any from current wind
        w = env.primaryWeather()
        main_wind = w.mainWind() if w != None else None
        main_wind_hdg = main_wind[0] if main_wind != None else Heading(
            360, True)
        choose_from = [
            rwy for rwy in env.airport_data.allRunways()
            if abs(main_wind_hdg.diff(rwy.orientation())) <= 90
        ]
    choose_from = [rwy for rwy in choose_from if condition(rwy)]
    return None if choose_from == [] else choice(choose_from)
Esempio n. 15
0
 def saveChangesAndClose(self):
     SharedDetailSheet.saveChangesAndClose(self)
     ## Assigned stuff
     # Squawk code
     if self.assignSquawkCode.isChecked():
         self.set_detail(assigned_SQ_detail, self.xpdrCode_select.getSQ())
     else:
         self.set_detail(assigned_SQ_detail, None)
     # Heading
     if self.assignHeading.isChecked():
         self.set_detail(assigned_heading_detail,
                         Heading(self.assignedHeading_edit.value(), False))
     else:
         self.set_detail(assigned_heading_detail, None)
     # Altitude/FL
     if self.assignAltitude.isChecked():
         reading = self.assignedAltitude_edit.text()
         try:  # try reformating
             self.set_detail(assigned_altitude_detail,
                             StdPressureAlt.reformatReading(reading))
         except ValueError:
             self.set_detail(assigned_altitude_detail, reading)
     else:
         self.set_detail(assigned_altitude_detail, None)
     # Speed
     if self.assignSpeed.isChecked():
         self.set_detail(assigned_speed_detail,
                         Speed(self.assignedSpeed_edit.value()))
     else:
         self.set_detail(assigned_speed_detail, None)
     # DONE with details
     if self.strip.linkedFPL() == None:
         if self.linkFPL_tickBox.isChecked():
             if self.FPL_link_on_save == None:
                 signals.newLinkedFPLrequest.emit(self.strip)
             else:
                 self.strip.linkFPL(self.FPL_link_on_save)
     else:  # a flight plan is already linked
         if self.pushToFPL_tickBox.isChecked():
             self.strip.pushToFPL()
     self.accept()
def read_point_spec(specstr, db):
    mvlst = specstr.split('>')
    pbase = mvlst.pop(0)
    try:
        if ',' in pbase and '~' not in pbase:
            result = EarthCoords.fromString(pbase)
        else:
            result = navpointFromSpec(pbase, db).coordinates
    except NavpointError:
        raise ValueError(
            'No navpoint for "%s" or navpoint not unique (consider using `~\' operator)'
            % pbase)
    else:
        while mvlst != []:
            mv = mvlst.pop(0).split(',')
            if len(mv) == 2:
                radial = Heading(float(mv[0]), True)
                distance = float(mv[1])
                result = result.moved(radial, distance)
            else:
                raise ValueError('Bad use of `>\' in point spec "%s"' %
                                 specstr)
        return result
Esempio n. 17
0
def interpret_string(string):
    tokens = string.split()
    named_runways = pop_named_runways(tokens)
    rwy_to_expect = ' '.join(named_runways)

    ## Callsign recognition
    ialnum, alnumtk = find_tokens(is_alphanum_token, tokens, 0, False)
    addressee_tokens = []
    for i in range(ialnum + len(alnumtk)):
        addressee_tokens.append(tokens.pop(0))

    ## Instruction list
    recognised_instructions = []

    # Instruction.CANCEL_APP
    try:
        try:
            i = tokens.index('go-around')
            j = i + 1
        except ValueError:
            i = tokens.index('cancel')  # cf. "cancel approach"
            j = i + 2
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: cancel app', tokens)
        recognised_instructions.append(
            Instruction(Instruction.CANCEL_APP, voiceData={}))
        del tokens[i:j]

    # Instruction.EXPECT_RWY
    try:
        i = tokens.index('expect')
    except ValueError:
        pass
    else:
        # 'j' below is last index to remove once instr is recognised; runway tokens are already removed
        j_max = min(len(tokens), i + 3)
        j = next((j for j in range(i + 1, j_max)
                  if tokens[j] not in ['ils', 'visual', 'approach']), j_max)
        app = next((b for t, b in [('ils', True), ('visual', False)]
                    if t in tokens[i + 1:j + 1]), None)
        SR_log('RECOGNISED: rwy/app', rwy_to_expect, app, tokens)
        recognised_instructions.append(
            Instruction(Instruction.EXPECT_RWY,
                        arg=rwy_to_expect,
                        voiceData={'app': app}))
        del tokens[i:j + 1]

    # Instruction.VECTOR_HDG
    try:
        try:
            i = tokens.index('turn')
        except ValueError:
            i = tokens.index('heading')
    except ValueError:
        pass
    else:
        try:
            ni, ntk = find_num_tokens(tokens, i + 1)
            hdg = convert_num_tokens(ntk)
        except ValueError as err:
            SR_log('Please report bug with heading instruction: %s' % err,
                   tokens)
        else:
            SR_log('RECOGNISED: hdg', hdg, tokens)
            recognised_instructions.append(
                Instruction(Instruction.VECTOR_HDG,
                            arg=Heading(hdg, False),
                            voiceData={}))
            del tokens[i:ni + len(ntk)]

    # Instruction.VECTOR_ALT
    try:
        ifl = tokens.index('flight-level')  # "flight level"
    except ValueError:  # try altitude
        th = hu = None
        try:
            ith = tokens.index('thousand')
            nith, thtk = find_num_tokens(tokens, ith - 1, bwd=True)
            del tokens[nith:ith + 1]
            SR_log('Tokens left after "thousand":', tokens)
            th = convert_num_tokens(thtk)  # STYLE catch a fail here?
        except ValueError:
            pass
        try:
            ihu = tokens.index('hundred')
            nihu, hutk = find_num_tokens(tokens, ihu - 1, bwd=True)
            del tokens[nihu:ihu + 1]
            SR_log('Tokens left after "hundred":', tokens)
            hu = convert_num_tokens(hutk)  # STYLE catch a fail here?
        except ValueError:
            pass
        if th != None or hu != None:  # got altitude
            alt = 1000 * some(th, 0) + 100 * some(hu, 0)
            SR_log('RECOGNISED: alt', alt)
            recognised_instructions.append(
                Instruction(Instruction.VECTOR_ALT,
                            arg=('%d ft' % alt),
                            voiceData={}))
    else:  # got FL
        try:
            nifl, fltk = find_num_tokens(tokens, ifl + 1)
            fl = convert_num_tokens(fltk)
        except ValueError as err:
            SR_log('Please report bug with FL instruction: %s' % err, tokens)
        else:
            SR_log('RECOGNISED: FL', fl, tokens)
            recognised_instructions.append(
                Instruction(Instruction.VECTOR_ALT,
                            arg=('FL%03d' % fl),
                            voiceData={}))
            del tokens[ifl:nifl + len(fltk)]

    # Instruction.VECTOR_SPD
    try:
        i = tokens.index('speed')
    except ValueError:
        pass
    else:
        if tokens[i + 1:i + 3] == ['your', 'discretion']:
            SR_log('RECOGNISED: cancel spd')
            recognised_instructions.append(
                Instruction(Instruction.CANCEL_VECTOR_SPD, voiceData={}))
            del tokens[i:i + 3]
        else:
            try:
                ni, ntk = find_num_tokens(tokens, i + 1)
                spd = convert_num_tokens(ntk)
            except ValueError as err:
                SR_log('Please report bug with speed instruction: %s' % err,
                       tokens)
            else:
                SR_log('RECOGNISED: spd', spd, tokens)
                recognised_instructions.append(
                    Instruction(Instruction.VECTOR_SPD,
                                arg=Speed(spd),
                                voiceData={}))
                del tokens[i:ni + len(ntk)]

    # Instruction.SQUAWK
    try:
        i = tokens.index('squawk')
    except ValueError:
        pass
    else:
        sq = [digit_tokens[tokens[k]] for k in range(i + 1, i + 5)]
        sq_code = 8 * 8 * 8 * sq[0] + 8 * 8 * sq[1] + 8 * sq[2] + sq[3]
        SR_log('RECOGNISED: sq', sq_code, tokens)
        recognised_instructions.append(
            Instruction(Instruction.SQUAWK, arg=sq_code, voiceData={}))
        del tokens[i:i + 5]

    # Instruction.HAND_OVER
    try:
        i = tokens.index('contact')
    except ValueError:
        pass
    else:
        try:
            atc = atc_tokens[tokens[i + 1]]
        except (KeyError, IndexError) as err:
            SR_log('Please report bug with h/o instruction: %s' % err, tokens)
        else:
            SR_log('RECOGNISED: handover', tokens)
            recognised_instructions.append(
                Instruction(Instruction.HAND_OVER,
                            arg=(atc, None),
                            voiceData={}))
            del tokens[i:i + 2]

    # Instruction.INTERCEPT_LOC
    try:
        iloc = tokens.index('localiser')
        i, tk = find_tokens('intercept'.__eq__, tokens, iloc - 1, True)
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: loc', tokens)
        recognised_instructions.append(
            Instruction(Instruction.INTERCEPT_LOC,
                        voiceData={'rwy': rwy_to_expect}))
        del tokens[i:iloc + 1]

    # Instruction.CLEARED_APP
    try:
        try:
            iapp = tokens.index(
                'approach'
            )  # WARNING "approach" also appears in CANCEL_APP, EXPECT_RWY and HAND_OVER, but should be removed by now
        except ValueError:
            iapp = tokens.index(
                'ils'
            )  # WARNING "ils" also appears in EXPECT_RWY, but should be removed by now
        i, tk1_ignore = find_tokens('cleared'.__eq__, tokens, iapp - 1, True)
    except ValueError:
        pass
    else:
        app = next((b for t, b in [('ils', True), ('visual', False)]
                    if t in tokens[i + 1:iapp + 1]), None)
        SR_log('RECOGNISED: app', app, tokens)
        recognised_instructions.append(
            Instruction(Instruction.CLEARED_APP,
                        voiceData={
                            'rwy': rwy_to_expect,
                            'app': app
                        }))
        del tokens[i:iapp + 1]

    # Instruction.LINE_UP
    try:
        i = tokens.index('wait')
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: luw', tokens)
        recognised_instructions.append(
            Instruction(Instruction.LINE_UP, voiceData={'rwy': rwy_to_expect}))
        del tokens[i - 2:i + 1]

    # Instruction.CLEARED_TKOF
    try:
        i = tokens.index('take-off')
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: cto', tokens)
        recognised_instructions.append(
            Instruction(Instruction.CLEARED_TKOF,
                        voiceData={'rwy': rwy_to_expect}))
        del tokens[i - 2:i + 1]

    # Instruction.CLEARED_TO_LAND
    try:
        i = tokens.index('land')
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: ctl', tokens)
        recognised_instructions.append(
            Instruction(Instruction.CLEARED_TO_LAND,
                        voiceData={'rwy': rwy_to_expect}))
        del tokens[i - 2:i + 1]

    # Instruction.SAY_INTENTIONS
    try:
        i = tokens.index('intentions')
    except ValueError:
        pass
    else:
        SR_log('RECOGNISED: intentions?', tokens)
        recognised_instructions.append(
            Instruction(Instruction.SAY_INTENTIONS, voiceData={}))
        del tokens[i - 1:i + 1]

    # Instruction.VECTOR_DCT
    try:
        i = tokens.index('proceed')
    except ValueError:
        pass
    else:
        try:
            pi, ptk = find_tokens(is_navpoint_token, tokens, i + 1, False)
            point = convert_navpoint_tokens(ptk)
        except ValueError as err:
            SR_log('Please report bug with DCT instruction: %s' % err, tokens)
        else:
            SR_log('RECOGNISED: dct', point, tokens)
            recognised_instructions.append(
                Instruction(Instruction.VECTOR_DCT, arg=point, voiceData={}))
            del tokens[i:pi + len(ptk)]

    # Instruction.HOLD, Instruction.HOLD_POSITION
    try:
        i = tokens.index('hold')
    except ValueError:
        pass
    else:
        if i + 1 < len(tokens) and tokens[i + 1] == 'position':
            SR_log('RECOGNISED: hold-position', tokens)
            recognised_instructions.append(
                Instruction(Instruction.HOLD_POSITION, voiceData={}))
            del tokens[i:i + 2]
        else:
            try:
                pi, ptk = find_tokens(is_navpoint_token, tokens, i + 1, False)
                point = convert_navpoint_tokens(ptk)
            except ValueError as err:
                SR_log('Please report bug with hold instruction: %s' % err,
                       tokens)
            else:
                j = pi + len(ptk)
                if j < len(tokens) and tokens[j] in ['left', 'right']:
                    turns = tokens[j] == 'right'
                    j += 2
                else:
                    turns = True
                SR_log('RECOGNISED: hold', point, tokens)
                recognised_instructions.append(
                    Instruction(Instruction.HOLD,
                                arg=(point, turns),
                                voiceData={}))
                del tokens[i:j]

    return addressee_tokens, recognised_instructions
Esempio n. 18
0
	def sendInstruction_interceptNav(self):
		heading = Heading(self.intercept_heading_edit.value(), False)
		self.sendInstruction(Instruction(Instruction.INTERCEPT_NAV, arg=(self.navpoint_edit.text(), heading)))
Esempio n. 19
0
    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