def test_dest(start): dest = 'EHAM' if start: stack.stack("CRE KLM10 B747 52 4 000 FL100 250") stack.stack("KLM10 DEST %s"%dest) else: return traf.ap.dest[0] == dest
def drawapprwy(apt,rwy,rwylat,rwylon,rwyhdg): # Draw approach ILS arrow Lapp = 7. # [nm] length of approach path drawn phi = 5. # [deg] angle of half the arrow # Calculate arrow (T = Threshold runway): # /------------- L (left) # /-----------/ / # T -------------------------------------- A (approach) # \-----------\ \ # \--------------R (right) # applat,applon = kwikpos(rwylat,rwylon,(rwyhdg+180)%360.,Lapp) rightlat,rightlon = kwikpos(rwylat,rwylon,(rwyhdg+180-phi)%360,Lapp*1.1) leftlat,leftlon = kwikpos(rwylat,rwylon,(rwyhdg+180+phi)%360,Lapp*1.1) # Make arguments for POLYLINE command T = str(rwylat)+","+str(rwylon) A = str(applat)+","+str(applon) L = str(leftlat)+","+str(leftlon) R = str(rightlat)+","+str(rightlon) stack.stack("POLYLINE "+apt+rwy+"-A,"+",".join([T,A,L,T,R,A])) return apt+rwy+"-A"
def test_orig(start): orig = 'EHAM' if start: stack.stack("CRE KLM10 B747 52 4 000 FL100 250") stack.stack("KLM10 ORIG %s"%orig) else: return traf.ap.orig[0] == orig
def event(self, eventname, eventdata, sender_rte): #print('Node {} received {} data from {}'.format(self.node_id, eventname, sender_id)) print('SIM EVT: {0} {1}'.format(eventname, eventdata)) # Keep track of event processing event_processed = False if eventname == b'STACKCMD': # We received a single stack command. Add it to the existing stack stack.stack(eventdata, sender_rte) event_processed = True elif eventname == b'BATCH': # We are in a batch simulation, and received an entire scenario. Assign it to the stack. self.reset() stack.set_scendata(eventdata['scentime'], eventdata['scencmd']) self.op() event_processed = True elif eventname == b'QUIT': # BlueSky is quitting self.quit() elif eventname == b'GETSIMSTATE': # Send list of stack functions available in this sim to gui at start stackdict = {cmd: val[0][len(cmd) + 1:] for cmd, val in stack.cmddict.items()} shapes = [shape.raw for shape in areafilter.areas.values()] simstate = dict(pan=bs.scr.def_pan, zoom=bs.scr.def_zoom, stackcmds=stackdict, shapes=shapes) self.send_event(b'SIMSTATE', simstate, target=sender_rte) else: # This is either an unknown event or a gui event. event_processed = bs.scr.event(eventname, eventdata, sender_rte) return event_processed
def update(): global commandnames, fnumber, teststart, timer if fnumber < len(commandnames): # form function name func = "test_"+ commandnames[fnumber].lower() timer = sim.simt # if function exists if func in globals().keys(): # run the test and get result result = globals()[func](teststart) teststart = False if result != None: stack.stack("ECHO "+commandnames[fnumber]+" DOES %sWORK" % ("" if result else "NOT ") ) # Prepare for next test function fnumber += 1 teststart = True # reset traffic to get rid of unnecessary crap traf.reset() else: # if function does not exist - keep looping fnumber += 1 #stack.stack("ECHO "+func+" DOES NOT EXIST") else: stack.stack("RESET") stack.stack("PAUSE") stack.stack("ECHO FINISHED PERFORMING STACKCHECK") stack.stack("PLUGIN REMOVE STACKCHECK")
def drawdeprwy(apt,rwy,rwylat,rwylon,rwyhdg): # Draw approach ILS arrow Ldep = 5. # [nm] length of approach path drawn phi = 3. # [deg] angle of half the arrow # Calculate arrow (T = Threshold runway): # L (left) # / # D ------------------------------------- T (approach) # \ # R (right) # deplat,deplon = kwikpos(rwylat,rwylon,rwyhdg%360.,Ldep*1.1) rightlat,rightlon = kwikpos(rwylat,rwylon,(rwyhdg+phi)%360,Ldep) leftlat,leftlon = kwikpos(rwylat,rwylon,(rwyhdg-phi)%360,Ldep) # Make arguments for POLYLINE command T = str(rwylat)+","+str(rwylon) D = str(deplat)+","+str(deplon) L = str(leftlat)+","+str(leftlon) R = str(rightlat)+","+str(rightlon) stack.stack("POLYLINE " + apt + rwy + "-D," + ",".join([R,D,L,D,T])) return apt + rwy + "-D"
def drawrwy(aptname,cmdargs,aptlat,aptlon,drawfunction): rwnames = [] for rwy in cmdargs: if rwy[0] == "R": success, rwyposobj = txt2pos(aptname + "/" + rwy, aptlat, aptlon) else: success, rwyposobj = txt2pos(aptname + "/RW" + rwy, aptlat, aptlon) if not success: success,rwyposobj = txt2pos(aptname,aptlat,aptlon) if success: rwydigits = rwy.lstrip("RWY").lstrip("RW") # Look up runwayhdg try: rwyhdg = navdb.rwythresholds[aptname][rwydigits][2] except: try: rwyhdg = navdb.rwythresholds[aptname][rwydigits.lstrip("0")][2] except: rwyhdg = 10.*int(rwydigits.rstrip("LCR").lstrip("0")) rwnames.append(drawfunction(aptname, rwy, rwyposobj.lat, rwyposobj.lon, rwyhdg)) else: # Use airport lat,lon en given heading stack.stack("ECHO TARFGEN RUNWAY "+aptname+"/"+rwy+" NOT FOUND") return rwnames
def toggle(self, flag=None): if flag: self.connected = True stack.stack('OP') return True, 'Connecting to OpenSky' else: self.connected = False return True, 'Stopping the requests'
def setspd(self,cmdargs): if len(cmdargs)==1: spd = txt2spd(cmdargs[0]) self.startspdmin = spd self.startapdmax = spd elif len(cmdargs)>1: spd0,spd1 = txt2spd(cmdargs[0]),txt2spd(cmdargs[1]) self.startspdmin = min(spd0,spd1) self.startspdmax = max(spd0,spd1) else: stack.stack("ECHO "+self.name+" SPD "+str(self.startaltmin)+" "+str(self.startaltmax))
def setalt(self,cmdargs): if len(cmdargs)==1: alt = txt2alt(cmdargs[0]) self.startaltmin = alt self.startaltmax = alt elif len(cmdargs)>1: alt0,alt1 = txt2alt(cmdargs[0]),txt2alt(cmdargs[1]) self.startaltmin = min(alt0,alt1) self.startaltmax = max(alt0,alt1) else: stack.stack("ECHO "+self.name+" ALT "+str(self.startaltmin)+" "+str(self.startaltmax))
def test_spd(start): global starttime, timer timelimit = 60. if start: stack.stack("CRE KLM10 B747 52 4 000 59 250") stack.stack("KLM10 SPD 300") starttime = timer else: closeenough = 295 *kts <= traf.cas[0] < 305*kts if timer-starttime > timelimit or closeenough: return closeenough
def remove_outdated_ac(self): """House keeping, remove old entries (offline > 100s)""" for addr, ac in list(self.acpool.items()): if 'ts' in ac: # threshold, remove ac after 90 seconds of no-seen if (int(time.time()) - ac['ts']) > 100: del self.acpool[addr] # remove from sim traffic if 'callsign' in ac: stack.stack('DEL %s' % ac['callsign']) return
def test_alt(start): global starttime, timer timelimit = 60. fl = 100 if start: stack.stack("CRE KLM10 B747 52 4 000 FL99 250") stack.stack("KLM10 ALT FL%s" %fl) starttime = timer else: closeenough = (fl*100 - 10) * ft <= traf.alt[0] < (fl*100 + 10) * ft if (timer - starttime) > timelimit or closeenough: return closeenough
def test_hdg(start): global starttime, timer timelimit = 70. # seconds new_heading = 170 if start: stack.stack("CRE KLM10 B747 52 4 000 FL100 250") stack.stack("KLM10 HDG %s"%new_heading) starttime = timer else: closeenough = (new_heading - 1) <= traf.hdg[0] < (new_heading + 1) if (timer - starttime) > timelimit or closeenough: return closeenough
def create(self, *args): if len(args) == 0: pass if len(args) == 4: self.lat0, self.lon0, self.lat1, self.lon1 = args self.year, self.month, self.day = bs.sim.utc.year, bs.sim.utc.month, bs.sim.utc.day self.hour = bs.sim.utc.hour elif len(args) == 8: self.lat0, self.lon0, self.lat1, self.lon1, \ self.year, self.month, self.day, self.hour = args # round hour to 3 hours, check if it is a +3h prediction self.hour = round(self.hour / 3) * 3 if self.hour in [3, 9, 15, 21]: self.hour = self.hour - 3 pred = 3 else: pred = 0 txt = "Loading wind field for %s-%s-%s %s:00..." % (self.year, self.month, self.day, self.hour) bs.scr.echo("%s" % txt) grb = self.fetch_grb(self.year, self.month, self.day, self.hour, pred) if grb is None: return False, "Wind data not exist in area [%d, %d], [%d, %d]. " \ % (self.lat0, self.lat1, self.lon0, self.lon1) \ + "time: %04d-%02d-%02d %02d:00" \ % (self.year, self.month, self.day, self.hour) # first clear exisiting wind field stack.stack('DEL wind') # add new wind field data = self.extract_wind(grb, self.lat0, self.lon0, self.lat1, self.lon1) df = pd.DataFrame(data.T, columns=['lat','lon','alt','vx','vy']) df['dir'] = np.degrees(np.arctan2(df.vx, df.vy)) df['spd'] = np.sqrt(df.vx**2 + df.vy**2) for (lat, lon), d in df.groupby(['lat', 'lon']): cmd = "WIND %d,%d," % (lat, lon) for idx, r in d.iterrows(): cmd += "%d,%d,%d," % (r.alt, r.dir, r.spd) stack.stack(cmd) return True, "Wind field update in area [%d, %d], [%d, %d]. " \ % (self.lat0, self.lat1, self.lon0, self.lon1) \ + "time: %04d-%02d-%02d %02d:00" \ % (self.year, self.month, self.day, self.hour)
def test_addwpt(start): global starttime, timer timelimit = 120 if start: # Create a waypoint which does not lie on the aircraft path stack.stack("CRE KLM10 B747 52 4 000 FL99 150") stack.stack("KLM10 ADDWPT 52 4.1") starttime = timer else: # When the aircraft reaches the waypoint, return success _, d = geo.qdrdist(52,4.1,traf.lat[0],traf.lon[0]) closeenough = d < 0.2 # d is measured in nm if timer-starttime>timelimit or closeenough: return closeenough
def stack_all_commands(self): """create and stack command""" params = ('lat', 'lon', 'alt', 'speed', 'heading', 'callsign') for i, d in list(self.acpool.items()): # check if all needed keys are in dict if set(params).issubset(d): acid = d['callsign'] # check is aircraft is already beening displayed if(traf.id2idx(acid) < 0): mdl = self.default_ac_mdl v = aero.tas2cas(d['speed'], d['alt'] * aero.ft) cmdstr = 'CRE %s, %s, %f, %f, %f, %d, %d' % \ (acid, mdl, d['lat'], d['lon'], d['heading'], d['alt'], v) stack.stack(cmdstr) else: cmdstr = 'MOVE %s, %f, %f, %d' % \ (acid, d['lat'], d['lon'], d['alt']) stack.stack(cmdstr) cmdstr = 'HDG %s, %f' % (acid, d['heading']) stack.stack(cmdstr) v_cas = aero.tas2cas(d['speed'], d['alt'] * aero.ft) cmdstr = 'SPD %s, %f' % (acid, v_cas) stack.stack(cmdstr) return
def toggle(self, flag=None): if flag is None: if self.isConnected(): return True, 'Connected to %s on port %s' % (settings.modeS_host, settings.modeS_port) else: return True, 'Not connected' elif flag: self.connectToHost(settings.modeS_host, settings.modeS_port) stack.stack('OP') return True, 'Connecting to %s on port %s' % (settings.modeS_host, settings.modeS_port) else: self.disconnectFromHost() return True
def sethdg(self,cmdargs): if len(cmdargs)==1: hdg = float(cmdargs[0]) self.starthdgmin = hdg self.starthdgmax = hdg elif len(cmdargs)>1: hdg0,hdg1 = float(cmdargs[0]),float(cmdargs[1]) hdg0,hdg1 = min(hdg0,hdg1),max(hdg0,hdg1) if hdg1-hdg0>180.: hdg0,hdg1 = hdg1-360,hdg0 self.starthdgmin = hdg0 self.starthdgmax = hdg1 else: stack.stack("ECHO "+self.name+" HDG "+str(self.starthdgmin)+" "+str(self.starthdgmax))
def stack_all_commands(self): """create and stack command""" params = ('lat', 'lon', 'alt', 'speed', 'heading', 'callsign') for i, d in self.acpool.items(): # check if all needed keys are in dict if set(params).issubset(d): acid = d['callsign'] # check is aircraft is already beening displayed if(traf.id2idx(acid) < 0): mdl = self.default_ac_mdl v = aero.tas2cas(d['speed'], d['alt'] * aero.ft) cmdstr = 'CRE %s, %s, %f, %f, %f, %d, %d' % \ (acid, mdl, d['lat'], d['lon'], d['heading'], d['alt'], v) stack.stack(cmdstr) else: cmdstr = 'MOVE %s, %f, %f, %d' % \ (acid, d['lat'], d['lon'], d['alt']) stack.stack(cmdstr) cmdstr = 'HDG %s, %f' % (acid, d['heading']) stack.stack(cmdstr) v_cas = aero.tas2cas(d['speed'], d['alt'] * aero.ft) cmdstr = 'SPD %s, %f' % (acid, v_cas) stack.stack(cmdstr) return
def perform_action(self, i, action): if action < 3: traf_alt = int(traf.alt[i] / ft) new_alt = int(round((traf_alt + ACTIONS[action]))) alt = max(CONSTRAINTS["alt"]["min"], min(CONSTRAINTS["alt"]["max"], new_alt)) # print(traf_alt, alt) stack.stack("{} alt {}".format(traf.id[i], alt)) elif action == 4: traf_alt = traf.alt[i] / ft new_alt = int(round((traf_alt)))
def test_wind(start): global starttime, timer timelimit = 20 if start: # Create a very strong headwind cas = 250 tas = vcas2tas(cas*kts,10000*ft)/kts stack.stack("CRE KLM10 B747 52 4 000 FL100 "+str(int(cas))) # Mind that wind is defined in the direction that it is coming from stack.stack("WIND 52 4 FL100 000 "+str(int(tas))) starttime = timer elif timer-starttime>timelimit: # If the aircraft did not move _, d = geo.qdrdist(52,4,traf.lat[0],traf.lon[0]) return d < 0.1 # d is measured in nm
def initilise(self): coords = None string = f'POLY {self.name}' origin = [] for i, point in enumerate(self.points): if i == 0: origin = [point["lat"], point["lon"]] coords = [] string += f' {point["lat"]},{point["lon"]}' coords = np.append(coords, [point["lat"], point["lon"]]) coords = np.append(coords, [origin]) # areafilter.defineArea(areaname=self.name, # areatype='POLY', coordinates=np.array(coords)) stack(string)
def test_eng(start): """ at a moment the engine change DOES result in performance coefficient change in accordance with a new engine, but the engine id/type is not changed """ global starttime, timer timelimit = 5. # seconds if start: stack.stack("CRE KLM10 B747 52 4 000 FL100 250") starttime = timer # elif timer - starttime < timelimit: # print(traf.perf.engines) # print("eng type before change", traf.perf.etype[0]) # stack.stack("ENG KLM10 RB211-22B") # print("eng type after change", traf.perf.etype[0]) else: return False
def _next(self): self.ensembles = traf.wind.ens if self.current_scn > len(self.ic)-1: # if end of scns?) if self.current_ens < len(self.ensembles): self.current_ens = self.current_ens + 1 print(self.current_ens) stack.stack('load_wind {} {}'.format(self.current_ens, self.nc)) self.current_scn = 0 self._next() else: # done, store data and go home df = pd.DataFrame(columns=['id', 'time', 'fuel'], data=self.results_list) pickle.dump(df, open('output/results.p', 'wb')) else: # switch to the next scn file stack.stack('IC batch/{}'.format(self.ic[self.current_scn])) self.current_scn = self.current_scn + 1 self.takeoff = False
def act5(self): # Compute 15 degree turn left waypoint. # Use current speed to compute waypoint. dqdr = 15 latA = traf.lat[self.acidx] lonA = traf.lon[self.acidx] turnrad = traf.tas[self.acidx]**2 / (np.maximum(0.01, np.tan(traf.bank[self.acidx])) * g0) # [m] #Turn right so add bearing # qdr = traf.qdr[self.acidx] + 90 latR, lonR = qdrpos(latA, lonA, traf.hdg[self.acidx] - 90, turnrad/nm) # [deg, deg] # Rotate vector latB, lonB = qdrpos(latR, lonR, traf.hdg[self.acidx] + 90 - dqdr, turnrad/nm) # [deg, deg] cmd = "{} BEFORE {} ADDWPT '{},{}'".format(traf.id[self.acidx], traf.ap.route[0].wpname[-2], latB, lonB) stack.stack(cmd)
def wrapcreate(acid=None, actype=None, aclat=None, aclon=None, achdg=None, acalt=None, acspd=None): stack.stack("CRE " + ",".join([ acid, actype, str(aclat), str(aclon), str(achdg), str(acalt / ft), str(acspd / kts) ])) return
def resolve(): # Assign reward for previous state-action if buffer.REWARD_PENDING: buffer.assign_reward(get_reward_for_action()) # Choose action for current time-step state = get_state() q_values = atc_net.forward(state) action = get_action(q_values) # Store S, A in buffer (R will be observed later) buffer.add_state_action(state, action) # Execute action new_heading = traf.hdg[traf.id2idx('SELF')] + float(actions_enum[action]) stack.stack(f"HDG SELF {new_heading}")
def action_command(self, action): for i in range(len(self.idx)): stack.stack('HDG {} {}'.format(self.idx[i], action[i])) if len(self.idx)!=0: obs = self.observation[0] if type(self.observation) == list else self.observation if (len(obs.shape)==2): obs = np.expand_dims(obs, axis=0) # dist = obs[0][:, :, 4]*self.dist_scale dist = np.asarray(self.dist) #(obs[:,:,4]+1)/2 * self.dist_scale dist_lim = 10 # print(np.where(np.abs(dist-dist_lim/2)<dist_lim/2)) dist_idx = np.where(np.abs(dist-dist_lim/2)<dist_lim/2)[0] for idx in dist_idx: stack.stack('SPD {} 200'.format(self.idx[idx]))
def test_move(start): # set new values for a MOVE command new_lat, new_lon = 52, 8 new_alt = 200 # FL new_hdg = 180 # degrees new_spd = 300 # CAS in knots if start: stack.stack("CRE KLM10 B747 52 4 000 FL100 250") stack.stack("MOVE KLM10 52 8 FL200 180 300") else: # check whether variables are within the reasonable ranges from the set values close_enough_lat = new_lat - 0.1 <= traf.lat[0] <= new_lat + 0.1 close_enough_lon = new_lon - 0.1 <= traf.lon[0] <= new_lon + 0.1 close_enough_hdg = new_hdg - 1 <= traf.hdg[0] <= new_hdg + 1 close_enough_alt = new_alt * 100 * ft - 10 <= traf.alt[0] <= new_alt * 100 * ft + 10 close_enough_spd = new_spd * kts - 5 <= traf.cas[0] <= new_spd * kts + 5 return close_enough_lat and close_enough_lon and close_enough_hdg and close_enough_alt and close_enough_spd
def test_del(start): global starttime, timer if start: stack.stack("CRE KLM10 B747 52 4 000 59 250") stack.stack("CRE KLM11 B747 53 4 000 59 250") stack.stack("CRE KLM12 B747 54 4 000 59 250") starttime = timer elif traf.ntraf==3 and timer-starttime<5: stack.stack("DEL KLM10") else: return traf.ntraf==2
def event(self, eventname, eventdata, sender_rte): print(f'# Sim event: {eventname}') # Keep track of event processing event_processed = False if eventname == b'STACKCMD': # We received a single stack command. Add it to the existing stack stack.stack(eventdata, sender_rte) event_processed = True elif eventname == b'STEP': # Step 1 DTMULT's worth of time steps self.op() for i in range(int(self.dtmult / self.simdt)): self.step(True) self.pause() self.send_event(b'STEP', data=b'Ok') elif eventname == b'BATCH': # We are in a batch simulation, and received an entire scenario. Assign it to the stack. self.reset() stack.set_scendata(eventdata['scentime'], eventdata['scencmd']) self.op() event_processed = True elif eventname == b'QUIT': # BlueSky is quitting self.quit() elif eventname == b'GETSIMSTATE': # Send list of stack functions available in this sim to gui at start stackdict = {cmd: val[0][len(cmd) + 1:] for cmd, val in stack.cmddict.items()} shapes = [shape.raw for shape in areafilter.areas.values()] simstate = dict(pan=bs.scr.def_pan, zoom=bs.scr.def_zoom, stackcmds=stackdict, shapes=shapes) self.send_event(b'SIMSTATE', simstate, target=sender_rte) else: # This is either an unknown event or a gui event. event_processed = bs.scr.event(eventname, eventdata, sender_rte) return event_processed
def reset(self): self.done = np.array([False]) self.los_pairs = [] self.done = [] self.episode += 1 self.prev_traf = 0 self.observation = np.zeros((1,self.state_size)) self.done = np.array([False]) self.idx = [] self.los_pairs = [] self.step_num = 0 if not CONF.train_bool: scenarios = list(os.walk('./scenario/Bart/test/')) if (self.episode - int(CONF.load_ep)) == len(scenarios[0][-1]): exit() self.scn = scenarios[0][-1][self.episode-int(CONF.load_ep)] print('episode', self.episode-int(CONF.load_ep)) stack.stack('open ./scenario/Bart/test/{}'.format(self.scn)) # if env.episode<100: # scenarios = list(os.walk('./scenario/Bart/multi/easy/')) # self.scn = random.choice(scenarios[0][-1]) # stack.stack('open ./scenario/Bart/multi/easy/{}'.format(self.scn)) # # elif env.episode<250: # scenarios = list(os.walk('./scenario/Bart/multi/medium/')) # self.scn = random.choice(scenarios[0][-1]) # stack.stack('open ./scenario/Bart/multi/medium/{}'.format(self.scn)) # # else: # scenarios = list(os.walk('./scenario/Bart/multi/hard/')) # self.scn = random.choice(scenarios[0][-1]) # stack.stack('open ./scenario/Bart/multi/hard/{}'.format(self.scn)) else: scenarios = list(os.walk('./scenario/Bart/formations/')) self.scn = random.choice(scenarios[0][-1]) stack.stack('open ./scenario/Bart/formations/{}'.format(self.scn))
def init_plugin(): global fnumber, commandnames, teststart # Run the time stack.stack("OP") stack.stack("FF") # Reset the traffic simulation traf.reset() commandnames = list(stack.cmddict.keys()) # Make a list of testing functions fnumber = 0 teststart = True # Configuration parameters config = { # The name of your plugin 'plugin_name': 'STACKCHECK', # The type of this plugin. For now, only simulation plugins are possible. 'plugin_type': 'sim', 'update': update, 'preupdate': preupdate } stackfunctions = { # The command name for your function 'MYFUN': [ # A short usage string. This will be printed if you type HELP <name> in the BlueSky console 'MYFUN ON/OFF', # A list of the argument types your function accepts. For a description of this, see ... '[onoff]', # The name of your function in this plugin myfun, # a longer help text of your function. 'Print something to the bluesky console based on the flag passed to MYFUN.'] } # init_plugin() should always return these two dicts. return config, stackfunctions
def step(self): self.step_num += 1 self.prev_observation = self.observation self.observation = self.generate_observation() # Check termination conditions # self.los_pairs = detect_los(traf, traf, traf.asas.R, traf.asas.dh) # Add in 9999999 for vertical protection zone to ignore vertical separation self.los_pairs = detect_los(traf, traf, traf.asas.R, 9999999) self.check_reached() self.generate_reward() # print('rew', self.reward) done = True if self.done.all() == True else False done_idx = np.where(self.done == True)[0] for idx in done_idx: stack.stack("DEL {}".format(traf.id[idx])) # There is a mismatch between the aircraft size in the observation returned for the replay memory and the # observation required to select actions when an aircraft is deleted. Therefore two separate observations must # be used. replay_observation = self.observation if type(self.observation)==list: self.observation[0] = np.delete(self.observation[0], done_idx, 0) if self.observation[0].shape[0]==0: self.observation[1] = np.delete(self.observation[1], np.arange(self.observation[1].shape[0]), 0) else: mask = np.ones(self.observation[1].shape, dtype=np.bool) for idx in done_idx: mask[idx, :, :] = 0 if idx == 0 and mask.shape[1]==0: mask[:,:,:] = 0 else: mask[:, idx, :] = 0 self.observation[1] = self.observation[1][mask].reshape((traf.ntraf - len(done_idx), traf.ntraf - len(done_idx), self.shared_state_size)) else: self.observation = np.delete(self.observation, done_idx, 0) self.dist = np.delete(self.dist, done_idx) self.qdr = np.delete(self.qdr, done_idx) self.idx = np.delete(traf.id, done_idx) return self.prev_observation, self.reward, replay_observation, done
def test_mcre(start): ac_type = 'B747' alt = 100 # FL spd = 250 # CAS in knots ades = 'EHAM' # airport of destination is not checked yet if start: stack.stack("MCRE 11") elif traf.ntraf == 11: traf.reset() stack.stack("MCRE 5 %s FL%s %s %s" % (ac_type, alt, spd, ades)) else: close_enough_alt = np.logical_and(traf.alt <= (alt * 100 * ft + 10), traf.alt >= (alt * 100 * ft - 10)) close_enough_spd = np.logical_and(traf.cas <= (spd * kts + 10), traf.cas >= (spd * kts - 10)) return (traf.ntraf == 5 and len(traf.type)==5 and np.all(close_enough_alt) and np.all(close_enough_spd))
def speed(self, ac_id, ac_target_speed): # Check whether Vmax is exceeded, if so replace it with Vmax # print(ac_id) # print(traf.id[ac_id]) # index = self.idx2id(ac_id) # print(index) # This is the target altitude of the next waypoint # print(traf.ap.route[ac_id].wpalt[traf.ap.route[ac_id].iactwp]) # This is the ac type # print(traf.type[ac_id]) # Now find the maximum velocity of the ac type corresponding at that altitude # print(traf.perf.vmo) # print('The maximum operating mach number is: ', traf.perf.mmo) # print(traf.tas) # print('Vmax is: ', traf.perf.asas.vmax) # Either pick the speed which is put in or the max operating speed ac_speed = min(traf.perf.mmo[ac_id], ac_target_speed) # print('\nThe target speed is: ', ac_target_speed) # print('The max speed is: ', traf.perf.mmo[ac_id]) # print('The selected speed is: ', ac_speed) stack.stack(f'SPD {traf.id[ac_id]} {ac_speed}')
def geofence(name: 'txt', top: float, bottom: float, *coordinates: float): ''' Create a new geofence from the stack. Arguments: - name: The name of the new geofence - top: The top of the geofence in feet. - bottom: The bottom of the geofence in feet. - coordinates: three or more lat/lon coordinates in degrees. ''' # Add first coordinate to list of coordinates to close border n = len(coordinates) if (coordinates[0], coordinates[1]) is not (coordinates[n - 2], coordinates[n - 1]): coordinates += (coordinates[0], coordinates[1]) # Create geofence and plot in map Geofence.geofences[name] = Geofence(name, coordinates, top, bottom) stack.stack( f"POLY {name},{','.join([str(coord) for coord in coordinates])}") return True, f'Created geofence {name}'
def drawrwy(aptname,cmdargs,aptlat,aptlon,drawfunction): rwnames = [] for rwy in cmdargs: if rwy[0] == "R": success, rwyposobj = txt2pos(aptname + "/" + rwy, aptlat, aptlon) else: success, rwyposobj = txt2pos(aptname + "/RW" + rwy, aptlat, aptlon) if success: rwydigits = rwy.lstrip("RWY").lstrip("RW") # Look up threshold position try: rwyhdg = navdb.rwythresholds[aptname][rwydigits][2] except: stack.stack("ECHO TRAFGEN RWY ERROR " + aptname + "/" + rwy + " NOT FOUND") rwnames.append(drawfunction(aptname, rwy, rwyposobj.lat, rwyposobj.lon, rwyhdg)) else: stack.stack("ECHO TRAFGEN RWY ERROR " + aptname + "/" + rwy + " NOT FOUND") return rwnames
def draw_routes(self): for x in self.departure: ap = self.departure[x] for connection in ap["connection"]: node = self.nodes[connection] stack( f'LINE {ap["id"]}{node["id"]} {ap["lat"]},{ap["lon"]} {node["lat"]},{node["lon"]}' ) for x in self.nodes: nd = self.nodes[x] for connection in nd["connection"]: try: node = self.nodes[connection] stack( f'LINE {nd["id"]}{node["id"]} {nd["lat"]},{nd["lon"]} {node["lat"]},{node["lon"]}' ) except: print(f"No node: {connection}") for x in self.arrival: nd = self.arrival[x] for connection in nd["connection"]: try: node = self.nodes[connection] stack( f'LINE {nd["id"]}{node["id"]} {nd["lat"]},{nd["lon"]} {node["lat"]},{node["lon"]}' ) except: print(f"No node: {connection}")
def getnextwp(self): """Go to next waypoint and return data""" if self.flag_landed_runway: # when landing, LNAV is switched off lnavon = False # no further waypoint nextqdr = -999. # and the aircraft just needs a fixed heading to # remain on the runway # syntax: HDG acid,hdg (deg,True) name = self.wpname[self.iactwp] if "RWY" in name: rwykey = name[8:] # if it is only RW else: rwykey = name[7:] wphdg = bs.navdb.rwythresholds[name[:4]][rwykey][2] # keep constant runway heading stack.stack("HDG " + str(bs.traf.id[self.iac]) + " " + str(wphdg)) # start decelerating stack.stack("DELAY " + "10 " + "SPD " + str(bs.traf.id[self.iac]) + " " + "10") # delete aircraft stack.stack("DELAY " + "42 " + "DEL " + str(bs.traf.id[self.iac])) return self.wplat[self.iactwp],self.wplon[self.iactwp], \ self.wpalt[self.iactwp],self.wpspd[self.iactwp], \ self.wpxtoalt[self.iactwp],self.wptoalt[self.iactwp],\ lnavon,self.wpflyby[self.iactwp], nextqdr lnavon = self.iactwp +1 < self.nwp if lnavon: self.iactwp += 1 nextqdr = self.getnextqdr() # in case that there is a runway, the aircraft should remain on it # instead of deviating to the airport centre # When there is a destination: current = runway, next = Dest # Else: current = runway and this is also the last waypoint if (self.wptype[self.iactwp] == 5 and self.wpname[self.iactwp] == self.wpname[-1]) or \ (self.wptype[self.iactwp] == 5 and self.wptype[self.iactwp + 1] == 3): self.flag_landed_runway = True # print ("getnextwp:",self.wpname[self.iactwp]) return self.wplat[self.iactwp],self.wplon[self.iactwp], \ self.wpalt[self.iactwp],self.wpspd[self.iactwp], \ self.wpxtoalt[self.iactwp],self.wptoalt[self.iactwp],\ lnavon,self.wpflyby[self.iactwp], nextqdr
def event(self, eventname, eventdata, sender_rte): #print('Node {} received {} data from {}'.format(self.node_id, eventname, sender_id)) print('SIM EVT: {0} {1}'.format(eventname, eventdata)) # Keep track of event processing event_processed = False if eventname == b'STACKCMD': # We received a single stack command. Add it to the existing stack stack.stack(eventdata, sender_rte) event_processed = True elif eventname == b'BATCH': # We are in a batch simulation, and received an entire scenario. Assign it to the stack. self.reset() stack.set_scendata(eventdata['scentime'], eventdata['scencmd']) self.op() event_processed = True elif eventname == b'QUIT': # BlueSky is quitting self.quit() elif eventname == b'GETSIMSTATE': # Send list of stack functions available in this sim to gui at start stackdict = { cmd: val[0][len(cmd) + 1:] for cmd, val in stack.cmddict.items() } shapes = [shape.raw for shape in areafilter.areas.values()] simstate = dict(pan=bs.scr.def_pan, zoom=bs.scr.def_zoom, stackcmds=stackdict, shapes=shapes) self.send_event(b'SIMSTATE', simstate, target=sender_rte) else: # This is either an unknown event or a gui event. event_processed = bs.scr.event(eventname, eventdata, sender_rte) return event_processed
def reset(): # Contest global variables global ctrlat,ctrlon,radius,dtsegment,drains,sources,rwsdep,rwsarr # Set default parameters for spawning circle swcircle = False ctrlat = 52.6 # [deg] ctrlon = 5.4 # [deg] radius = 230.0 # [nm] # Draw circle stack.stack("CIRCLE SPAWN," + str(ctrlat) + "," + str(ctrlon) + "," + str(radius)) # Average generation interval in [s] per segment dtsegment = 12 * [1.0] # drains: dictionary of drains sources = dict([]) drains = dict([]) return
def event(self, event): # Keep track of event processing event_processed = False if event.type() == StackTextEventType: # We received a single stack command. Add it to the existing stack stack.stack(event.cmdtext, event.sender_id) event_processed = True elif event.type() == BatchEventType: # We are in a batch simulation, and received an entire scenario. Assign it to the stack. self.reset() stack.set_scendata(event.scentime, event.scencmd) self.start() event_processed = True elif event.type() == SimQuitEventType: # BlueSky is quitting self.quit() else: # This is either an unknown event or a gui event. event_processed = bs.scr.event(event) return event_processed
def create_ac(self, path): callsign = self.iata + str(self.total) self.routes.update({callsign: path[:]}) node = path.pop(0) node_coord = self.network.get_coords(node) ac_type = random.choice(self.types) s_lat, s_lon = node_coord[0], node_coord[1] hdg = self.network.get_heading( node_coord, self.network.get_coords(path[0])) alt = np.random.randint(self.min_alt, self.max_alt) spd = np.random.randint(self.min_spd, self.max_spd) stack("CRE {} {} {},{} {} {} {}".format( callsign, ac_type, s_lat, s_lon, hdg, alt, spd)) while path: node = path.pop(0) node_coord = self.network.get_coords(node) stack("ADDWPT {} {},{}".format( callsign, node_coord[0], node_coord[1])) self.active += 1 self.total += 1
def test_after(start): global starttime, timer timelimit = 240 lowertimelimit = 120 if start: # Create a waypoint which does not lie on the aircraft path # And create a next waypoint to reach after that stack.stack("CRE KLM10 B747 52 4 000 FL99 150") stack.stack("DEFWPT TESTWP 52 4.1") stack.stack("KLM10 ADDWPT TESTWP") stack.stack("KLM10 AFTER TESTWP ADDWPT 51.9 4.1") starttime = timer else: # When the aircraft reaches the waypoint, return success _, d = geo.qdrdist(51.9,4.1,traf.lat[0],traf.lon[0]) closeenough = d < 0.2 # d is measured in nm if timer-starttime>timelimit or closeenough: return closeenough and timer-starttime>lowertimelimit
def test_vs(start): global starttime, timer timelimit = 10. # seconds new_vs = 2000 # fpm init_alt, new_alt = 100, 200 if start: # Create an aircraft that should perform a vertical manoever stack.stack("CRE KLM10 B747 52 4 000 FL%s 250"%init_alt) stack.stack("KLM10 ALT FL%s"%new_alt) stack.stack("KLM10 VS %s" % new_vs) starttime = timer else: # Check if the aircraft adopted the new vs closeenough = (new_vs * fpm - 10) <= traf.vs[0] < (new_vs * fpm + 10) if (timer - starttime) > timelimit or closeenough: return closeenough