def normalise_all(self, state, terminal_ac, g_dists, dist_matrix): normal_states = self.normalise_state(state, terminal_ac, g_dists) normal_context = [] start_ids, end_ids = self.get_all_nodes() max_agents = 0 for _id in traf.id: if terminal_ac[traf.id2idx(_id)] > 0 or len( self.traffic_manager.active_sectors[traf.id2idx( _id)]) <= 0: continue new_context = self.normalise_context(_id, terminal_ac, dist_matrix, start_ids, end_ids) max_agents = max(max_agents, len(new_context)) if len(normal_context) == 0: normal_context = new_context else: normal_context = np.append( keras.preprocessing.sequence.pad_sequences( normal_context, max_agents, dtype='float32'), keras.preprocessing.sequence.pad_sequences( new_context, max_agents, dtype='float32'), axis=0) if len(normal_context) == 0: normal_context = np.array([0, 0, 0, 0, 0, 0, 0]).reshape(1, 1, 7) # print(normal_states.shape, normal_context.shape) return normal_states, normal_context
def get_state(): """ Get current state of simulation :return: torch.Tensor (Input for the neural network, containing enough information to render the problem Markov) """ self = traf.id2idx('SELF') enemy = traf.id2idx('ENEMY') self_hdg = traf.hdg[self] enemy_hdg = traf.hdg[enemy] rel_hdg = make_angle_convex(enemy_hdg - self_hdg) qdr, dist = _qdrdist(traf.lat[self], traf.lon[self], traf.lat[enemy], traf.lon[enemy]) qdr = make_angle_convex(qdr) return tensor([make_angle_convex(qdr + self_hdg), dist, rel_hdg])
def checkPairInside(self, ac1, ac2): ''' Check which pairs are inside the logging area ''' # Retrieve traffic indices of conflict pairs idx1 = traf.id2idx(ac1) idx2 = traf.id2idx(ac2) # Bool array indicating which conflicts are inside # -- Current implementation: if at least 1 of 2 aircraft is inside pairinside = np.logical_or(self.currinside[idx1], self.currinside[idx2]) # Return return pairinside
def update_reslos(self): # Update timer self.duration += settings.simdt # Retrieve traf idx idx1 = traf.id2idx(self.ac1) idx2 = traf.id2idx(self.ac2) # Retrieve lat, lon coordinates of traffic lat1, lon1 = traf.lat[idx1], traf.lon[idx1] lat2, lon2 = traf.lat[idx2], traf.lon[idx2] # Compute current distance between aircraft and save dist = kwikdist(lat1, lon1, lat2, lon2) * nm #distance in meters self.distance = np.append(self.distance, dist)
def log(self): apple = len(traf.id) limit = 5 # datalogger.update() if apple > 0: # print('Fuelflows are: {} at {}'.format(traf.perf.fuelflow, str(sim.utc.strftime("%H:%M:%S")))) self.counter += np.ones(apple) * np.logical_and( traf.alt < 1, True) # _and , traf.M<0.007 # datalogger.save2() if np.size((np.nonzero(self.counter > limit))) > 0: delcounter = np.delete(traf.id2idx(traf.id), np.nonzero(self.counter < limit)) if len(range(0, len(delcounter))) > 0: for i in range(0, len(delcounter)): delcounter[i] = int(delcounter[i]) self.deltime[delcounter[i]] = str( sim.utc.strftime("%d-%b-%Y %H:%M:%S")) else: delcounter[0] = int(delcounter[0]) self.deltime[0] = str( sim.utc.strftime("%d-%b-%Y %H:%M:%S")) # Print some stuff self.fuelused = self.initmass - traf.perf.mass datalogger.talko(delcounter) # Save some stuff traf.resultstosave = datalogger.save(traf.resultstosave, delcounter) traf.delete(delcounter) pass
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 get_data(self, traf, callsign): hdg = None alt = None vs = None tas = None idx = traf.id2idx(callsign) hdg = traf.trk[idx] alt = traf.alt[idx] vs = traf.vs[idx] tas = traf.tas[idx] if not self.initilized: self.minalt = alt self.maxalt = alt self.minvs = vs self.maxvs = vs self.maxtas = tas self.initilized = True else: self.minalt = min(self.minalt, alt) self.maxalt = max(self.maxalt, alt) self.minvs = min(self.minvs, vs) self.maxvs = max(self.maxvs, vs) self.maxtas = max(self.maxtas, tas) return self.normalise_ac([hdg, alt, vs, tas, 0])
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 preupdate(): global obs, reset_bool, connected, prev_obs, first_time, final_obs, done, delete_dict if connected: obs = calc_state() if first_time: done = dict.fromkeys(obs.keys()) delete_dict = dict.fromkeys(obs.keys(), False) final_obs = dict.fromkeys(obs.keys()) first_time = False action = client_mc.get_action(eid, obs) # print(action) for idx_mc, action in action.items(): # print('Action ', str(action[0]), 'at idx_mc ', idx_mc) # print('Before action HDG: ' + str(traf.hdg[0])) if action == 0: action_hdg = -25 elif action == 1: action_hdg = -12 elif action == 2: action_hdg = 0 elif action == 3: action_hdg = 12 else: action_hdg = 25 action_tot = obs[idx_mc][2] + action_hdg traf.ap.selhdgcmd(traf.id2idx(idx_mc), action_tot) prev_obs = obs
def update(self): if self.enable: for ac in self.acid_activate: idx = traf.id2idx(ac) self.data[ac].append([ sim.simt, traf.lat[idx], traf.lon[idx], traf.alt[idx], traf.hdg[idx], traf.gs[idx], traf.M[idx], traf.tas[idx], traf.perf.mass ])
def update(): global first_time, done, delete_dict, done_count if first_time: done = dict.fromkeys(traf.id) delete_dict = dict.fromkeys(traf.id, False) first_time = False for id in traf.id: if id not in done: done[id] = False if id not in delete_dict: delete_dict[id] = False dest_lat_lon = [(52.6, 4.73), (52.3, 4.36), (52.33, 5.19), (51.52, 5.33), (51.8, 5.06), (51.82, 5.75), (52.30, 6.0)] # dest_lat_lon[-dest] if done.keys(): for agent_id in done.keys(): # Initialize reward to 0. done[agent_id] = False # First check if goal area is reached idx = traf.id2idx(agent_id) dest = traf.dest_temp[idx] dest_lat, dest_lon = dest_lat_lon[-dest] dist = geo.kwikdist(traf.lat[idx], traf.lon[idx], dest_lat, dest_lon) if dist <= 5: done[agent_id] = True done_count += 1 for agent_id in done.keys(): if agent_id in delete_dict: if done[agent_id] and not delete_dict[agent_id]: traf.delete(traf.id2idx(agent_id)) print('Deleted ', agent_id) delete_dict[agent_id] = True save_metrics() if done_count >= 125: sim.reset() return
def dist_goal(_id): global ac_routes global positions _id = traf.id2idx(_id) olat = traf.lat[_id] olon = traf.lon[_id] ilat, ilon = traf.ap.route[_id].wplat[0], traf.ap.route[_id].wplon[0] dist = geo.latlondist(olat, olon, ilat, ilon) / geo.nm return dist
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 get_goal_dist(_id, traffic, routes): idx = traf.id2idx(_id) route = traffic.routes[_id] wpt = get_next_node(_id, traffic, routes) remaining_dist = 0 remaining_dist += get_dist([traf.lat[idx], traf.lon[idx]], routes.get_coords(route[wpt])) for i in range(wpt, len(route) - 1): remaining_dist += get_dist(routes.get_coords(route[wpt]), routes.get_coords(route[wpt + 1])) wpt += 1 return remaining_dist
def get_next_node(_id, traffic, routes): idx = traf.id2idx(_id) active_waypoint = [traf.actwp.lat[idx], traf.actwp.lon[idx]] route = traffic.routes[_id] wpt = 0 best_dist = 10e+25 for i in range(1, len(route)): wpt_coords = routes.get_coords(route[i]) dist = get_dist(active_waypoint, wpt_coords) if dist < best_dist: best_dist = dist wpt = i return wpt
def get_n_nodes(_id, traffic, routes, n=3): idx = traf.id2idx(_id) route = traffic.routes[_id] next_nodes = np.zeros(3) next_node = get_next_node(_id, traffic, routes) coords = routes.get_coords(route[next_node]) next_nodes[0] = next_node / (len(routes.idx_array) - 1) dist = get_dist([traf.lat[idx], traf.lon[idx]], coords) for i in range(1, n): if (next_node + 1) < len(route): next_node += 1 next_nodes[i] = next_node / (len(routes.idx_array) - 1) else: next_nodes[i] = next_node / (len(routes.idx_array) - 1) return next_nodes, dist
def dist_update(self): if self.existed <= self.max_ac: for k in range(len(self.spawn_queue)): # Get aircraft as well as current position and start position callsign = self.last_spawned[k] idx = traf.id2idx(callsign) lat, lon = traf.lat[idx], traf.lon[idx] s_lat, s_lon, _, _, _ = self.routes[self.on_route[callsign]] ac = (lat, lon) start = (s_lat, s_lon) # Get the distance from the starting position in nm distance = dist.distance(ac, start).nm if distance >= self.spawn_queue[k]: self.spawn_ac(self.routes[k], k) if self.verbose: print(self.on_route) self.spawn_queue[k] = random.choices(self.distances, k=1)[0]
def update(): global reward, idx_mc, reset_bool, connected, obs, prev_obs, done_count, final_obs, done, delete_dict if connected: # Bluesky first timestep starts with update step, so use the reset_bool to determine wheter a reset has occured or not. Then create environment agents. if reset_bool: #Randomize starting location depending on boundaries in settings. aclat = np.random.rand(settings.n_ac) * (settings.max_lat - settings.min_lat) + settings.min_lat aclon = np.random.rand(settings.n_ac) * (settings.max_lon - settings.min_lon) + settings.min_lon achdg = np.random.randint(1, 360, settings.n_ac) acalt = np.ones(settings.n_ac) * 7620 # acspd = np.ones(settings.n_ac) * 300 print('Created ', str(settings.n_ac), ' random aircraft, resetted!') traf.create(n=settings.n_ac, aclat=aclat, aclon=aclon, achdg=achdg, #360 * np.random.rand(1) acspd=150, acalt=acalt, actype='B777')#settings.acspd) reset_bool = False return # print('After action HDG: ' + str(traf.hdg[0])) obs = calc_state() reward, done = calc_reward() for agent_id in done.keys(): if done[agent_id] and not delete_dict[agent_id]: traf.delete(traf.id2idx(agent_id)) print('Deleted ', agent_id) done_count += 1 final_obs[agent_id] = obs[agent_id] delete_dict[agent_id] = True idx_mc += 1 client_mc.log_returns(eid, reward, done, info=[]) if idx_mc == 500 or done_count == settings.n_ac: for agent_id in done.keys(): if not done[agent_id]: final_obs[agent_id] = obs[agent_id] print('total reward', reward) print('Done with Episode: ', eid) client_mc.end_episode(eid, final_obs) sim.reset()
def get_context_data(self, traf, callsign): _id = traf.id2idx(callsign) dist_matrix = self.get_dist_matrix(_id, traf)[_id] dist_matrix = np.array(dist_matrix).flatten() closest = self.get_closest(traf, _id) context = [] for element in closest: idx, dist = element hdg = traf.trk[idx] alt = traf.alt[idx] vs = traf.vs[idx] tas = traf.tas[idx] context.append([hdg, alt, vs, tas, dist]) if len(context) > 0: for i, val in enumerate(context): context[i] = self.normalise_ac(context[i], is_context=True) return context
def update_data(self): if self.limtype == 'gsmin': value = self.limval - traf.gs[traf.id2idx(self.acid)] elif self.limtype == 'gsmax': value = traf.gs[traf.id2idx(self.acid)] - self.limval elif self.limtype == 'trkmin': value = degto180(self.limval - traf.trk[traf.id2idx(self.acid)]) elif self.limtype == 'trkmax': value = degto180(traf.trk[traf.id2idx(self.acid)] - self.limval) elif self.limtype == 'vsmin': value = self.limval - traf.vs[traf.id2idx(self.acid)] elif self.limtype == 'vsmax': value = traf.vs[traf.id2idx(self.acid)] - self.limval # Append new value to breachvals self.breachvals = np.append(self.breachvals, value)
def get_terminal(self, nearest_ac, g_dists): terminal_ac = np.zeros(len(traf.id), dtype=int) terminal_id = [] # Loop through all aircraft for i in range(len(traf.id)): # Terminal state 0 = not terminal, 1 = collision, 2 = success T = 0 # Only care about aircraft in a sector if len(self.traffic_manager.active_sectors[i]) > 0: close_ac = nearest_ac[i] n_ac_data = (close_ac[0], close_ac[1]) # Get the terminal state T = self.agent.terminal(i, n_ac_data, g_dists[i]) # Only care about terminal aircraft if not T == 0: # Update collision aircraft if T == 1: terminal_ac[i] = 1 terminal_ac[traf.id2idx(close_ac[2])] = 1 elif not terminal_ac[i] == 1: terminal_ac[i] = 2 _id = traf.id[i] self.memory.store(_id, self.last_observation[_id], self.previous_action[_id], nearest_ac[i], T) for i in range(len(terminal_ac)): if terminal_ac[i] > 0: terminal_id.append([traf.id[i], terminal_ac[i]]) return terminal_ac, terminal_id
def update(self): self.sectorsd = np.zeros(len(self.sectors)) self.sectorconv = np.zeros(len(self.sectors)) self.sectoreff = [] if not traf.ntraf or not self.sectors: return # Check convergence using CD with large RPZ and tlook confpairs, lospairs, inconf, tcpamax, qdr, dist, dcpa, tcpa, tLOS = \ traf.asas.cd.detect(traf, traf, 20 * nm, traf.asas.dh, 3600) if confpairs: own, intr = zip(*confpairs) ownidx = traf.id2idx(own) mask = traf.alt[ownidx] > 70 * ft ownidx = np.array(ownidx)[mask] dcpa = np.array(dcpa)[mask] tcpa = np.array(tcpa)[mask] else: ownidx = np.array([]) sendeff = False for idx, (sector, previnside) in enumerate(zip(self.sectors, self.acinside)): inside = areafilter.checkInside(sector, traf.lat, traf.lon, traf.alt) sectoreff = [] # Detect aircraft leaving and entering the sector previds = set(previnside.acid) ids = set(np.array(traf.id)[inside]) arrived = list(ids - previds) left = previds - ids # Split left aircraft in deleted and not deleted left_intraf = left.intersection(traf.id) left_del = list(left - left_intraf) left_intraf = list(left_intraf) arridx = traf.id2idx(arrived) leftidx = traf.id2idx(left_intraf) # Retrieve the current distance flown for arriving and leaving aircraft arrdist = traf.distflown[arridx] arrlat = traf.lat[arridx] arrlon = traf.lon[arridx] leftlat, leftlon, leftdist = self.delac.get(left_del) leftlat = np.append(leftlat, traf.lat[leftidx]) leftlon = np.append(leftlon, traf.lon[leftidx]) leftdist = np.append(leftdist, traf.distflown[leftidx]) leftlat0, leftlon0, leftdist0 = previnside.get(left_del + left_intraf) self.delac.delete(left_del) if len(left) > 0: q, d = geo.qdrdist(leftlat0, leftlon0, leftlat, leftlon) # Exclude aircraft where origin = destination mask = d > 10 sectoreff = list((leftdist[mask] - leftdist0[mask]) / d[mask] / nm) names = np.array(left_del + left_intraf)[mask] for name, eff in zip(names, sectoreff): self.feff.write('{}, {}, {}\n'.format(sim.simt, name, eff)) sendeff = True # print('{} aircraft left sector {}, distance flown (acid:dist):'.format(len(left), sector)) # for a, d0, d1, e in zip(left, leftdist0, leftdist, sectoreff): # print('Aircraft {} flew {} meters (eff = {})'.format(a, round(d1-d0), e)) # Update inside data for this sector previnside.delete(left) previnside.extend(arrived, arrlat, arrlon, arrdist) self.sectoreff.append(sectoreff) self.sectorsd[idx] = np.count_nonzero(inside) insidx = np.where(np.logical_and(inside, inconf)) pairsinside = np.isin(ownidx, insidx) if len(pairsinside): tnorm = np.array(tcpa)[pairsinside] / 300.0 dcpanorm = np.array(dcpa)[pairsinside] / (5.0 * nm) self.sectorconv[idx] = np.sum( np.sqrt(2.0 / tnorm * tnorm + dcpanorm * dcpanorm)) else: self.sectorconv[idx] = 0 self.fconv.write('{}, {}\n'.format(sim.simt, self.sectorconv[idx])) self.fsd.write('{}, {}\n'.format(sim.simt, self.sectorsd[idx])) if sendeff: self.effplot.send()
def update(): global positions global max_ac global agent global spawn_queue global times global active_ac global total_ac global ac_routes global update_timer global success_counter global collision_counter global previous_observation global previous_action global observation global no_states if total_ac < max_ac: if total_ac == 0: for i in range(len(positions)): spawn_ac(total_ac, positions[i]) ac_routes[total_ac] = i total_ac += 1 active_ac += 1 else: for k in range(len(spawn_queue)): if update_timer == spawn_queue[k]: spawn_ac(total_ac, positions[k]) ac_routes[total_ac] = k total_ac += 1 active_ac += 1 spawn_queue[k] = update_timer + random.choices(times, k=1)[0] if total_ac == max_ac: break terminal_ac = np.zeros(len(traf.id), dtype=int) for i in range(len(traf.id)): T_state, T_type = agent.update(traf, i, ac_routes) call_sig = traf.id[i] if T_state == True: stack.stack('DEL {}'.format(call_sig)) active_ac -= 1 if T_type == 1: collision_counter += 1 if T_type == 2: success_counter += 1 terminal_ac[i] = 1 try: agent.store( previous_observation[call_sig], previous_action[call_sig], [ np.zeros(previous_observation[call_sig][0].shape), (previous_observation[call_sig][1].shape) ], traf, call_sig, ac_routes, T_type) except Exception as e: print(f'ERROR: {e}') del previous_observation[call_sig] if active_ac == 0 and max_ac == total_ac: reset() return if active_ac == 0 and total_ac != max_ac: update_timer += 1 return if not len(traf.id) == 0: next_action = {} state = np.zeros((len(traf.id), 5)) non_T_ids = np.array(traf.id)[terminal_ac != 1] indexes = np.array([int(x[4:]) for x in traf.id]) route = ac_routes[indexes] state[:, 0] = traf.lat state[:, 1] = traf.lon state[:, 2] = traf.alt state[:, 3] = route state[:, 4] = traf.vs normal_state, context = get_normals_states(state, traf, ac_routes, next_action, no_states, terminal_ac, agent, previous_observation, observation) if len(context) == 0: update_timer += 1 return policy, values = agent.act(normal_state, context) # if (episode_counter + 1) % 20 == 0: # print(policy) for j in range(len(non_T_ids)): id_ = non_T_ids[j] if not id_ in previous_observation.keys(): previous_observation[id_] = [normal_state[j], context[j]] if not id_ in observation.keys() and id_ in previous_action.keys(): observation[id_] = [normal_state[j], context[j]] agent.store(previous_observation[id_], previous_action[id_], observation[id_], traf, id_, ac_routes) previous_observation[id_] = observation[id_] del observation[id_] action = np.random.choice(agent.no_actions, 1, p=policy[j].flatten())[0] index = traf.id2idx(id_) new_alt = agent.alts[action] stack.stack('ALT {}, {}'.format(id_, new_alt)) next_action[id_] = action previous_action = next_action update_timer += 1
def update(self, dt): ''' Update flight efficiency metrics 2D and 3D distance [m], and work done (force*distance) [J] ''' if self.active: resultantspd = np.sqrt(traf.gs * traf.gs + traf.vs * traf.vs) self.distance2D += dt * traf.gs self.distance3D += dt * resultantspd # Find out which aircraft are currently inside the experiment area, and # determine which aircraft need to be deleted. insdel = areafilter.checkInside(self.delarea, traf.lat, traf.lon, traf.alt) insexp = insdel if not self.exparea else \ areafilter.checkInside(self.exparea, traf.lat, traf.lon, traf.alt) # Find all aircraft that were inside in the previous timestep, but no # longer are in the current timestep delidx = np.where( np.array(self.insdel) * (np.array(insdel) == False))[0] self.insdel = insdel # Count new conflicts where at least one of the aircraft is inside # the experiment area # Store statistics for all new conflict pairs # Conflict pairs detected in the current timestep that were not yet present in the previous timestep confpairs_new = list(set(traf.cd.confpairs) - self.prevconfpairs) if confpairs_new: # If necessary: select conflict geometry parameters for new conflicts # idxdict = dict((v, i) for i, v in enumerate(traf.cd.confpairs)) # idxnew = [idxdict.get(i) for i in confpairs_new] # dcpa_new = np.asarray(traf.cd.dcpa)[idxnew] # tcpa_new = np.asarray(traf.cd.tcpa)[idxnew] # tLOS_new = np.asarray(traf.cd.tLOS)[idxnew] # qdr_new = np.asarray(traf.cd.qdr)[idxnew] # dist_new = np.asarray(traf.cd.dist)[idxnew] newconf_unique = {frozenset(pair) for pair in confpairs_new} ac1, ac2 = zip(*newconf_unique) idx1 = traf.id2idx(ac1) idx2 = traf.id2idx(ac2) newconf_inside = np.logical_or(insexp[idx1], insexp[idx2]) nnewconf_exp = np.count_nonzero(newconf_inside) if nnewconf_exp: self.confinside_all += nnewconf_exp self.conflog.log(self.confinside_all) self.prevconfpairs = set(traf.cd.confpairs) # Register distance values upon entry of experiment area newentries = np.logical_not(self.insexp) * insexp self.dstart2D[newentries] = self.distance2D[newentries] self.dstart3D[newentries] = self.distance3D[newentries] self.workstart[newentries] = traf.work[newentries] self.entrytime[newentries] = sim.simt # Log flight statistics when exiting experiment area exits = np.logical_and(self.insexp, np.logical_not(insexp)) # Update insexp self.insexp = insexp if np.any(exits): self.flst.log( np.array(traf.id)[exits], self.create_time[exits], sim.simt - self.entrytime[exits], (self.distance2D[exits] - self.dstart2D[exits]) / nm, (self.distance3D[exits] - self.dstart3D[exits]) / nm, (traf.work[exits] - self.workstart[exits]) * 1e-6, traf.lat[exits], traf.lon[exits], traf.alt[exits] / ft, traf.tas[exits] / kts, traf.vs[exits] / fpm, traf.hdg[exits], traf.cr.active[exits], traf.aporasas.alt[exits] / ft, traf.aporasas.tas[exits] / kts, traf.aporasas.vs[exits] / fpm, traf.aporasas.hdg[exits]) # delete all aicraft in self.delidx if len(delidx) > 0: traf.delete(delidx) # Autodelete for descending with swTaxi: if not self.swtaxi: delidxalt = np.where((self.oldalt >= self.swtaxialt) * (traf.alt < self.swtaxialt))[0] self.oldalt = traf.alt if len(delidxalt) > 0: traf.delete(list(delidxalt))
def change_destination(acid, destt): traf.dest_temp[traf.id2idx(acid)] = destt
def normalise_context(self, _id, terminal_ac, dist_matrix, start_ids, end_ids): context = [] idx = traf.id2idx(_id) distances = dist_matrix[:, idx] this_sectors = self.traffic_manager.active_sectors[idx] this_lat, this_lon = traf.lat[idx], traf.lon[idx] for i in range(len(distances)): # Ignore current aircraft if i == idx: continue if terminal_ac[i] > 0 or len( self.traffic_manager.active_sectors[i]) <= 0: continue sectors = self.traffic_manager.active_sectors[i] # Only care if the ac in a matching sector flag = False for x in sectors: if x in this_sectors: flag = True if not flag: continue dist = get_dist([this_lat, this_lon], [traf.lat[i], traf.lon[i]]) # Only care about visible distance aircraft if dist > 40: continue spd = traf.tas[i] alt = traf.alt[i] trk = traf.trk[i] vs = traf.vs[i] start_id = start_ids[i] end_id = end_ids[i] self.dist[1] = max(self.dist[1], dist) self.spd[1] = max(self.spd[1], spd) self.vs[1] = max(self.vs[1], vs) dist = dist / self.dist[1] spd = spd / self.spd[1] trk = trk / self.trk[1] alt = ((alt/ft)-CONSTRAINTS["alt"]["min"]) / \ (CONSTRAINTS["alt"]["max"]-CONSTRAINTS["alt"]["min"]) vs = 0 if not vs == 0: vs = vs / self.vs[1] n_nodes, dist2next = get_n_nodes(traf.id[i], self.traffic_manager, self.route_manager) self.dist[1] = max(self.dist[1], dist2next) dist2next = dist2next / self.dist[1] if len(context) == 0: context = np.array([ spd, alt, trk, vs, dist, dist2next, n_nodes[0], n_nodes[1], n_nodes[2] ]).reshape(1, 1, 9) else: context = np.append(context, np.array([ spd, alt, trk, vs, dist, dist2next, n_nodes[0], n_nodes[1], n_nodes[2] ]).reshape(1, 1, 9), axis=1) if len(context) == 0: context = np.zeros(9).reshape(1, 1, 9) return context
def log(self): apple = len(traf.id) limit = 30 # datalogger.update() if apple > 0: # print(traf.id) # print(self.counter) # print('apple is', apple) # print(traf.alt) # print(traf.M) # print(traf.perf.mass) # print(self.initmass) # print(np.logical_and(traf.alt<1, traf.M<0.002)) self.counter += np.ones(apple) * np.logical_and( traf.alt < 1, traf.M < 0.007) if np.size((np.nonzero(self.counter > limit))) > 0: delcounter = np.delete(traf.id2idx(traf.id), np.nonzero(self.counter < limit)) #print(delcounter) # print(self.deltime) if len(range(0, len(delcounter))) > 0: for i in range(0, len(delcounter)): delcounter[i] = int(delcounter[i]) self.deltime[delcounter[i]] = str( sim.utc.strftime("%d-%b-%Y %H:%M:%S")) else: delcounter[0] = int(delcounter[0]) self.deltime[0] = str( sim.utc.strftime("%d-%b-%Y %H:%M:%S")) # print(delcounter) # print(traf.id) # print(traf.counter) # print(self.initmass) # print(self.inittime) # print(self.deltime) # print(self.fuelused) # Print some stuff self.fuelused = self.initmass - traf.perf.mass # print('after assignment') # print(self.deltime) datalogger.talko(delcounter) # Save some stuff try: results2 = traf.resultstosave # print('delcounter according to save fnc!') # print(delcounter) traf.resultstosave = datalogger.save(results2, delcounter) except: test = pd.DataFrame(columns=[ 'AC ID', 'Actual Departure Time', 'Arrival Time', 'Fuel Consumed' ]) traf.resultstosave = datalogger.save(test, delcounter) del test # Clear the to-be-deleted AC #self.counter = np.delete(self.counter, delcounter) # self.fuelused = np.delete(self.fuelused, delcounter) # self.initmass = np.delete(self.initmass, delcounter) # for i in delcounter: # self.deltime.pop(delcounter[i]) # self.inittime.pop(delcounter[i]) # = np.delete(self.deltime, delcounter) # self.inittime = np.delete(self.inittime, delcounter) #print(traf.resultstosave) #print('deleting aircrafts now :)') traf.delete(delcounter) # self.counter = np.delete(self.counter, delcounter) del delcounter pass
def update(): global recording, prevconfpairs, confframe, delframe, resos, reso_index, ntrafframe, first_ntrafframe, first_confframe, locframe, first_locframe, first_delframe, first_logger, headings, densities, heading_index, density_index, reso, superfirst, i stack.stack('FF') if superfirst: superfirst = False stack.stack('PLUGIN MVPSPD') stack.stack('PLUGIN MVPSPDFTR') stack.stack('PLUGIN MVPVREL') stack.stack('PLUGIN MVPVRELFTR') stack.stack('ASAS ON') stack.stack('CDMETHOD CStateBased') stack.stack('RESO '+resos[reso_index]) stack.stack('PCALL '+'Wouter_MTM/'+str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'.SCN') stack.stack('FF') if traf.ntraf > 0 and not recording: # Voor low density case. recording = True else: pass tlist_id = [x for x in traf.id if x[0] == 'T'] tlist_idx = traf.id2idx(tlist_id) if first_ntrafframe: ntrafframe = np.array([sim.simt, traf.ntraf]) first_ntrafframe = False else: ntrafframe = np.vstack((ntrafframe, np.array([sim.simt, traf.ntraf]))) if first_locframe: locframe = np.array([sim.simt, traf.lat, traf.lon]) first_locframe = False else: if sim.simt % 5*60 < 1: locframe = np.vstack((locframe, np.array([sim.simt, traf.lat, traf.lon]))) else: pass if recording: # Omgekeerd Statement, de not moet eigenlijk weg. confpairs, lospairs, inconf, tcpamax, qdr, dist, dcpa, tcpa, tLOS = \ StateBased.detect(StateBased, traf, traf, bs.traf.cd.rpz, bs.traf.cd.hpz, bs.traf.cd.dtlookahead) #newgscapped = ConflictResolution.resolve(traf.asas,traf) if len([x for x in confpairs if x not in prevconfpairs]) > 0: newcomers = [confpairs.index(i) for i in confpairs if i not in prevconfpairs] for n in newcomers: confname = confpairs[n] ac1 = confname[0] ac2 = confname[1] ac1idx = traf.id2idx(ac1) ac2idx = traf.id2idx(ac2) bearing = qdr[n] distance = dist[n] distancecpa = dcpa[n] timecpa = tcpa[n] timeLOS = tLOS[n] initialtas = traf.tas[ac1idx] initialhdg = traf.hdg[ac1idx] initialtasi = traf.tas[ac2idx] initialhdgi = traf.hdg[ac2idx] latitude = traf.lat[ac1idx] longitude = traf.lon[ac1idx] latitudei = traf.lat[ac2idx] longitudei = traf.lon[ac2idx] if first_confframe: confframe = np.array([sim.simt, confname, ac1idx, ac1, bearing, distance, distancecpa, timecpa, timeLOS, initialtas, initialhdg, initialtasi, initialhdgi, latitude, longitude, latitudei, longitudei]) first_confframe = False else: confframe = np.vstack((confframe, np.array([sim.simt, confname, ac1idx, ac1, bearing, distance, distancecpa, timecpa, timeLOS, initialtas, initialhdg, initialtasi, initialhdgi, latitude, longitude, latitudei, longitudei]))) prevconfpairs = confpairs if sim.simt > 3.5*3600 and not first_confframe and not first_delframe: # Moet 4 ofzo zijn if not os.path.exists('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index])): os.makedirs('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index]), exist_ok=True) #pd.DataFrame(confframe).to_csv(str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'_'+reso+'_ResultsDF.csv', sep=';') pd.DataFrame(confframe).to_csv('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index])+'/'+str(i)+'-'+resos[reso_index]+'-confframe.csv' ,sep=';') #pd.DataFrame(delframe).to_csv(str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'_'+reso+'_Results-DelsDF.csv', sep=';') pd.DataFrame(delframe).to_csv('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index])+'/'+str(i)+'-'+resos[reso_index]+'-delframe.csv' ,sep=';') #pd.DataFrame(ntrafframe).to_csv(str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'_'+reso+'_Results-ntrafDF.csv', sep=';') pd.DataFrame(ntrafframe).to_csv('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index])+'/'+str(i)+'-'+resos[reso_index]+'-ntrafframe.csv' ,sep=';') #pd.DataFrame(locframe).to_csv(str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'_'+reso+'_Results-locsDF.csv', sep=';') pd.DataFrame(locframe).to_csv('/BSData2/Dens'+str(densities[density_index])+'/Head'+str(headings[heading_index])+'/'+str(i)+'-'+resos[reso_index]+'-locframe.csv' ,sep=';') #stack.stack('HOLD') stack.stack('RESET') reso_index += 1 c = False if reso_index > (len(resos) - 1): reso_index = 0 i += 1 if i > 10: #10 i = 1 heading_index += 1 if heading_index > 9: #9 heading_index = 0 density_index += 1 if density_index > 0: #9 stack.stack('HOLD') print('complete') c = True if not c: stack.stack('CDMETHOD CStateBased') stack.stack('RESO '+resos[reso_index]) stack.stack('PCALL '+'Wouter_MTM/'+str(headings[heading_index])+'_'+str(densities[density_index])+'_'+str(i)+'.SCN') stack.stack('FF') else: stack.stack('HOLD') first_confframe = True first_delframe = True first_ntrafframe = True recording = False for aircraft in traf.id: if traf.actwp.lon[traf.id2idx(aircraft)] > 10: if first_delframe: delframe = np.array([sim.simt, aircraft, traf.lat[traf.id2idx(aircraft)], traf.lon[traf.id2idx(aircraft)], traf.distflown[traf.id2idx(aircraft)]]) first_delframe = False else: delframe = np.vstack((delframe, np.array([sim.simt, aircraft, traf.lat[traf.id2idx(aircraft)], traf.lon[traf.id2idx(aircraft)], traf.distflown[traf.id2idx(aircraft)]]))) traf.delete(traf.id2idx(aircraft)) else: pass
def update(self, dt): ''' Update flight efficiency metrics 2D and 3D distance [m], and work done (force*distance) [J] ''' if self.active: resultantspd = np.sqrt(traf.gs * traf.gs + traf.vs * traf.vs) self.distance2D += dt * traf.gs self.distance3D += dt * resultantspd self.work += (traf.perf.thrust * dt * resultantspd) # Find out which aircraft are currently inside the experiment area, and # determine which aircraft need to be deleted. insdel = areafilter.checkInside(self.delarea, traf.lat, traf.lon, traf.alt) insexp = insdel if not self.exparea else \ areafilter.checkInside(self.exparea, traf.lat, traf.lon, traf.alt) # Find all aircraft that were inside in the previous timestep, but no # longer are in the current timestep delidx = np.where( np.array(self.insdel) * (np.array(insdel) == False))[0] self.insdel = insdel # Count new conflicts where at least one of the aircraft is inside # the experiment area if traf.asas.confpairs_new: newconf_unique = { frozenset(pair) for pair in traf.asas.confpairs_new } ac1, ac2 = zip(*newconf_unique) idx1 = traf.id2idx(ac1) idx2 = traf.id2idx(ac2) newconf_inside = np.logical_or(insexp[idx1], insexp[idx2]) nnewconf_exp = np.count_nonzero(newconf_inside) if nnewconf_exp: self.confinside_all += nnewconf_exp self.conflog.log(self.confinside_all) # Register distance values upon entry of experiment area newentries = np.logical_not(self.insexp) * insexp self.dstart2D[newentries] = self.distance2D[newentries] self.dstart3D[newentries] = self.distance3D[newentries] self.workstart[newentries] = self.work[newentries] self.entrytime[newentries] = sim.simt # Log flight statistics when exiting experiment area exits = self.insexp * np.logical_not(insexp) if np.any(exits): self.flst.log( np.array(traf.id)[exits], self.create_time[exits], sim.simt - self.entrytime[exits], self.dstart2D[exits] - self.distance2D[exits], self.dstart3D[exits] - self.distance3D[exits], self.workstart[exits] - self.work[exits], traf.lat[exits], traf.lon[exits], traf.alt[exits], traf.tas[exits], traf.vs[exits], traf.hdg[exits], traf.asas.active[exits], traf.pilot.alt[exits], traf.pilot.tas[exits], traf.pilot.vs[exits], traf.pilot.hdg[exits]) # delete all aicraft in self.delidx if len(delidx) > 0: traf.delete(delidx) # Autodelete for descending with swTaxi: if not self.swtaxi: delidxalt = np.where((self.oldalt >= self.swtaxialt) * (traf.alt < self.swtaxialt))[0] self.oldalt = traf.alt if len(delidxalt) > 0: traf.delete(list(delidxalt))
def applygeovec(): # Apply each geovector for areaname, vec in geovecs.items(): if areafilter.hasArea(areaname): swinside = areafilter.checkInside(areaname, traf.lat, traf.lon, traf.alt) insids = set(np.array(traf.id)[swinside]) newids = insids - vec.previnside delids = vec.previnside - insids # Store LNAV/VNAV status of new aircraft for acid in newids: idx = traf.id2idx(acid) vec.prevstatus[acid] = [traf.swlnav[idx], traf.swvnav[idx]] # Revert aircraft who have exited the geovectored area to their original status for acid in delids: idx = traf.id2idx(acid) if idx >= 0: traf.swlnav[idx], traf.swvnav[idx] = vec.prevstatus.pop( acid) vec.previnside = insids # -----Ground speed limiting # For now assume no wind: so use tas as gs if vec.gsmin is not None: casmin = vtas2cas(np.ones(traf.ntraf) * vec.gsmin, traf.alt) usemin = traf.selspd < casmin traf.selspd[swinside & usemin] = casmin[swinside & usemin] traf.swvnav[swinside & usemin] = False if vec.gsmax is not None: casmax = vtas2cas(np.ones(traf.ntraf) * vec.gsmax, traf.alt) usemax = traf.selspd > casmax traf.selspd[swinside & usemax] = casmax[swinside & usemax] traf.swvnav[swinside & usemax] = False #------ Limit Track(so hdg) # Max track interval is 180 degrees to avoid ambiguity of what is inside the interval if None not in [vec.trkmin, vec.trkmax]: # Use degto180 to avodi problems for e.g interval [350,30] usemin = swinside & (degto180(traf.trk - vec.trkmin) < 0 ) # Left of minimum usemax = swinside & (degto180(traf.trk - vec.trkmax) > 0 ) # Right of maximum traf.swlnav[swinside & (usemin | usemax)] = False traf.ap.trk[swinside & usemin] = vec.trkmin traf.ap.trk[swinside & usemax] = vec.trkmax # -----Ground speed limiting # For now assume no wind: so use tas as gs if vec.vsmin is not None: traf.selvs[swinside & (traf.vs < vec.vsmin)] = vec.vsmin traf.swvnav[swinside & (traf.vs < vec.vsmin)] = False # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs < vec.vsmin)] = traf.alt[swinside & (traf.vs < vec.vsmin)] + \ np.sign(vec.vsmin)*200.*ft if vec.vsmax is not None: traf.selvs[swinside & (traf.vs > vec.vsmax)] = vec.vsmax traf.swvnav[swinside & (traf.vs < vec.vsmax)] = False # Activate V/S mode by using a slightly higher altitude than current values traf.selalt[swinside & (traf.vs > vec.vsmax)] = traf.alt[swinside & (traf.vs > vec.vsmax)] + \ np.sign(vec.vsmax)*200.*ft return
def update(self): if not self.connected: return # t1 = time.time() if settings.opensky_ownonly: states = self.get_states(ownonly=True) if states is None: return else: # Get states from OpenSky. If all states fails try getting own states only. states = self.get_states() if states is None: if self.authenticated: states = self.get_states(ownonly=True) if states is None: return # Current time curtime = time.time() # States contents: icao24, acid, orig, time_pos, last_contact, lon, lat, geo_alt, on_gnd, \ spd, hdg, vspd, sensors, baro_alt, squawk, spi, pos_src = states[:17] # Relevant params as numpy arrays lat = np.array(lat, dtype=np.float64) lon = np.array(lon, dtype=np.float64) alt = np.array(baro_alt, dtype=np.float64) hdg = np.array(hdg, dtype=np.float64) vspd = np.array(vspd, dtype=np.float64) spd = np.array(spd, dtype=np.float64) acid = np.array([i.strip() for i in acid], dtype=np.str_) icao24 = np.array(icao24, dtype=np.str_) idx = np.array(traf.id2idx(acid)) # Split between already existing and new aircraft newac = idx == -1 other = np.logical_not(newac) # Filter out invalid entries valid = np.logical_not(np.logical_or.reduce( [np.isnan(x) for x in [lat, lon, alt, hdg, vspd, spd]])) newac = np.logical_and(newac, valid) other = np.logical_and(other, valid) n_new = np.count_nonzero(newac) n_oth = np.count_nonzero(other) # t2 = time.time() # Create new aircraft if n_new: actype = [actypes.get(str(i), 'B744') for i in icao24[newac]] traf.create(n_new, actype, alt[newac], spd[newac], None, lat[newac], lon[newac], hdg[newac], acid[newac]) self.my_ac[-n_new:] = True # t3 = time.time() # Update the rest if n_oth: traf.move(idx[other], lat[other], lon[other], alt[other], hdg[other], \ spd[other], vspd[other]) self.upd_time[idx[other]] = curtime # t4 = time.time() # remove aircraft with no message for less than 1 minute # opensky already filters delidx = np.where(np.logical_and(self.my_ac, curtime - self.upd_time > 10))[0] if len(delidx) > 0: traf.delete(delidx)
def update(self): self.sectorsd = np.zeros(len(self.sectors)) self.sectorconv = np.zeros(len(self.sectors)) self.sectoreff = [] if not traf.ntraf or not self.sectors: return # Check convergence using CD with large RPZ and tlook confpairs, lospairs, inconf, tcpamax, qdr, dist, dcpa, tcpa, tLOS = \ traf.asas.cd.detect(traf, traf, 20 * nm, traf.asas.dh, 3600) if confpairs: own, intr = zip(*confpairs) ownidx = traf.id2idx(own) mask = traf.alt[ownidx] > 70 * ft ownidx = np.array(ownidx)[mask] dcpa = np.array(dcpa)[mask] tcpa = np.array(tcpa)[mask] else: ownidx = np.array([]) sendeff = False for idx, (sector, previnside) in enumerate(zip(self.sectors, self.acinside)): inside = areafilter.checkInside(sector, traf.lat, traf.lon, traf.alt) sectoreff = [] # Detect aircraft leaving and entering the sector previds = set(previnside.acid) ids = set(np.array(traf.id)[inside]) arrived = list(ids - previds) left = previds - ids # Split left aircraft in deleted and not deleted left_intraf = left.intersection(traf.id) left_del = list(left - left_intraf) left_intraf = list(left_intraf) arridx = traf.id2idx(arrived) leftidx = traf.id2idx(left_intraf) # Retrieve the current distance flown for arriving and leaving aircraft arrdist = traf.distflown[arridx] arrlat = traf.lat[arridx] arrlon = traf.lon[arridx] leftlat, leftlon, leftdist = self.delac.get(left_del) leftlat = np.append(leftlat, traf.lat[leftidx]) leftlon = np.append(leftlon, traf.lon[leftidx]) leftdist = np.append(leftdist, traf.distflown[leftidx]) leftlat0, leftlon0, leftdist0 = previnside.get(left_del + left_intraf) self.delac.delete(left_del) if len(left) > 0: q, d = geo.qdrdist(leftlat0, leftlon0, leftlat, leftlon) # Exclude aircraft where origin = destination mask = d > 10 sectoreff = list( (leftdist[mask] - leftdist0[mask]) / d[mask] / nm) names = np.array(left_del + left_intraf)[mask] for name, eff in zip(names, sectoreff): self.feff.write('{}, {}, {}\n'.format(sim.simt, name, eff)) sendeff = True # print('{} aircraft left sector {}, distance flown (acid:dist):'.format(len(left), sector)) # for a, d0, d1, e in zip(left, leftdist0, leftdist, sectoreff): # print('Aircraft {} flew {} meters (eff = {})'.format(a, round(d1-d0), e)) # Update inside data for this sector previnside.delete(left) previnside.extend(arrived, arrlat, arrlon, arrdist) self.sectoreff.append(sectoreff) self.sectorsd[idx] = np.count_nonzero(inside) insidx = np.where(np.logical_and(inside, inconf)) pairsinside = np.isin(ownidx, insidx) if len(pairsinside): tnorm = np.array(tcpa)[pairsinside] / 300.0 dcpanorm = np.array(dcpa)[pairsinside] / (5.0 * nm) self.sectorconv[idx] = np.sum( np.sqrt(2.0 / tnorm * tnorm + dcpanorm * dcpanorm)) else: self.sectorconv[idx] = 0 self.fconv.write('{}, {}\n'.format(sim.simt, self.sectorconv[idx])) self.fsd.write('{}, {}\n'.format(sim.simt, self.sectorsd[idx])) if sendeff: self.effplot.send()
def update(self): if not self.connected: return # t1 = time.time() # Get states from OpenSky. If all states fails try getting own states only. states = self.get_states() if states is None: if self.authenticated: states = self.get_states(ownonly=True) if states is None: return # Current time curtime = time.time() # States contents: icao24, acid, orig, time_pos, last_contact, lon, lat, geo_alt, on_gnd, \ spd, hdg, vspd, sensors, baro_alt, squawk, spi, pos_src = states[:17] # Relevant params as numpy arrays lat = np.array(lat, dtype=np.float64) lon = np.array(lon, dtype=np.float64) alt = np.array(baro_alt, dtype=np.float64) hdg = np.array(hdg, dtype=np.float64) vspd = np.array(vspd, dtype=np.float64) spd = np.array(spd, dtype=np.float64) acid = np.array([i.strip() for i in acid], dtype=np.str_) icao24 = np.array(icao24, dtype=np.str_) idx = np.array(traf.id2idx(acid)) # Split between already existing and new aircraft newac = idx == -1 other = np.logical_not(newac) # Filter out invalid entries valid = np.logical_not(np.logical_or.reduce( [np.isnan(x) for x in [lat, lon, alt, hdg, vspd, spd]])) newac = np.logical_and(newac, valid) other = np.logical_and(other, valid) n_new = np.count_nonzero(newac) n_oth = np.count_nonzero(other) # t2 = time.time() # Create new aircraft if n_new: actype = [actypes.get(str(i), 'B744') for i in icao24[newac]] traf.create(n_new, actype, alt[newac], spd[newac], None, lat[newac], lon[newac], hdg[newac], acid[newac]) self.my_ac[-n_new:] = True # t3 = time.time() # Update the rest if n_oth: traf.move(idx[other], lat[other], lon[other], alt[other], hdg[other], \ spd[other], vspd[other]) self.upd_time[idx[other]] = curtime # t4 = time.time() # remove aircraft with no message for less than 1 minute # opensky already filters delidx = np.where(np.logical_and(self.my_ac, curtime - self.upd_time > 10))[0] if len(delidx) > 0: traf.delete(delidx)