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
Example #2
0
 def sendCpdlcMsg(self, callsign, msg):
     link = env.cpdlc.currentDataLink(callsign)
     if link == None:
         return
     if msg.type() == CpdlcMessage.ACK and link.msgCount() > 0:
         last_msg = link.lastMsg()
         if not last_msg.isFromMe() and last_msg.type() == CpdlcMessage.INSTR \
           and yesNo_question(self.gui, 'ACK after received INSTR', last_msg.contents(), 'Execute instruction?'):
             try:
                 instr = Instruction.fromEncodedStr(last_msg.contents())
                 self.instructAircraftByCallsign(callsign, instr)
             except ValueError:  # raised by Instruction.fromEncodedStr
                 if not yesNo_question(self.gui, 'CPDLC comm error', \
                   'Unable to decode instruction.', 'Send ACK and perform manually?'):
                     return  # cancel sending any message
             except Instruction.Error as err:  # raised by TeacherSessionManager.instructAircraftByCallsign
                 if not yesNo_question(self.gui, 'CPDLC instruction error', \
                   'Unable to perform instruction: %s' % err, 'Send ACK anyway?'):
                     return  # cancel sending any message
             else:  # no problem executing instruction
                 selection.writeStripAssignment(instr)
     if self.studentConnected() and link != None:
         link.appendMessage(msg)
         self.student.sendMessage(
             TeachingMsg(
                 TeachingMsg.CPDLC,
                 data=('%s\n%s%s' %
                       (callsign, CPDLC_message_cmd_prefix, msg.text()))))
 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
Example #4
0
	def sendInstruction_followRoute(self):
		strip = selection.strip
		if strip == None:
			QMessageBox.critical(self, 'Instruction error', 'No strip selected.')
		else:
			route = strip.lookup(parsed_route_detail)
			if route == None:
				QMessageBox.critical(self, 'Instruction error', 'No valid route on selected strip.')
			else:
				instr = Instruction(Instruction.FOLLOW_ROUTE, arg=route.dup())
				self.sendInstruction(instr)
 def sendCpdlcMsg(self, callsign, msg):
     link = env.cpdlc.currentDataLink(callsign)
     if link != None:
         link.appendMessage(msg)
         if msg.type(
         ) == CpdlcMessage.INSTR:  # other message types ignored (unimplemented in solo)
             try:
                 acft = next(
                     a for a in self.controlled_traffic if a.identifier ==
                     callsign)  # uncontrolled traffic is not in contact
                 acft.instruct([Instruction.fromEncodedStr(msg.contents())])
                 # FUTURE ingest before instruct to allow exception raised or (delayed?) WILCO msg before actually executing
             except StopIteration:  # ACFT not found or not connected
                 print('WARNING: Aircraft %s not found.' % callsign)
             except Instruction.Error as err:  # raised by ControlledAircraft.instruct
                 link.appendMessage(
                     CpdlcMessage(False,
                                  CpdlcMessage.REJECT,
                                  contents=str(err)))
             else:  # instruction sent and already accepted
                 link.appendMessage(CpdlcMessage(False, CpdlcMessage.ACK))
Example #6
0
 def ackButtonClicked(self):
     if self.data_link_model.msgCount() > 0:
         last_msg = self.data_link_model.lastMsg()
         if not last_msg.isFromMe() and last_msg.type(
         ) == CpdlcMessage.REQUEST:
             try:
                 instr = Instruction.fromEncodedStr(last_msg.contents())
             except ValueError:
                 QMessageBox.critical(
                     self, 'CPDLC comm error',
                     'Unable to decode request. Mismatching program versions?'
                 )
             else:
                 selection.writeStripAssignment(instr)
                 msg = CpdlcMessage(True,
                                    CpdlcMessage.INSTR,
                                    contents=instr.encodeToStr())
                 settings.session_manager.sendCpdlcMsg(
                     self.data_link_model.acftCallsign(), msg)
             return
     msg = CpdlcMessage(True, CpdlcMessage.ACK)
     settings.session_manager.sendCpdlcMsg(
         self.data_link_model.acftCallsign(), msg)
Example #7
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)))
Example #8
0
	def sendInstruction_hold(self):
		right_turns = self.hold_turn_select.currentText() == 'right'
		self.sendInstruction(Instruction(Instruction.HOLD, arg=(self.navpoint_edit.text(), right_turns)))
Example #9
0
	def sendInstruction_DCT(self):
		self.sendInstruction(Instruction(Instruction.VECTOR_DCT, arg=self.navpoint_edit.text()))
Example #10
0
	def sendInstruction_cancelApproach(self):
		self.sendInstruction(Instruction(Instruction.CANCEL_APP))
Example #11
0
	def sendInstruction_clearToLand(self):
		self.sendInstruction(Instruction(Instruction.CLEARED_TO_LAND))
Example #12
0
	def sendInstruction_clearedApproach(self):
		self.sendInstruction(Instruction(Instruction.CLEARED_APP))
    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
Example #14
0
 def handoverInstructionTo(self, atc):
     try:
         frq = self.getATC(atc).frequency
     except KeyError:
         frq = None
     return Instruction(Instruction.HAND_OVER, arg=(atc, frq))
Example #15
0
	def sendInstruction_lineUp(self):
		self.sendInstruction(Instruction(Instruction.LINE_UP))
Example #16
0
	def sendInstruction_holdPosition(self):
		self.sendInstruction(Instruction(Instruction.HOLD_POSITION))
Example #17
0
	def sendInstruction_expectDepartureRunway(self):
		self.sendInstruction(Instruction(Instruction.EXPECT_RWY, arg=self.reportReadyRWY_select.currentText()))
Example #18
0
	def sendInstruction_sayIntentions(self):
		self.sendInstruction(Instruction(Instruction.SAY_INTENTIONS))
Example #19
0
	def sendInstruction_speedYourDiscretion(self):
		self.sendInstruction(Instruction(Instruction.CANCEL_VECTOR_SPD))
Example #20
0
	def sendInstruction_takeOff(self):
		self.sendInstruction(Instruction(Instruction.CLEARED_TKOF))
Example #21
0
	def sendInstruction_interceptLocaliser(self):
		self.sendInstruction(Instruction(Instruction.INTERCEPT_LOC))
Example #22
0
	def sendInstruction_expectArrivalRunway(self):
		self.sendInstruction(Instruction(Instruction.EXPECT_RWY, arg=self.expectArrRWY_select.currentText()))
Example #23
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