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 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 setspeedforRTA(self, idx, torta, xtorta): #debug print("setspeedforRTA called, torta,xtorta =",torta,xtorta/nm) # Calculate required CAS to meet RTA # for aircraft nr. idx (scalar) if torta < -90. : # -999 signals there is no RTA defined in remainder of route return False deltime = torta-bs.sim.simt # Remaining time to next RTA [s] in simtime if deltime>0: # Still possible? trafax = abs(bs.traf.perf.acceleration()[idx]) gsrta = calcvrta(bs.traf.gs[idx], xtorta, deltime, trafax) # Subtract tail wind speed vector tailwind = (bs.traf.windnorth[idx]*bs.traf.gsnorth[idx] + bs.traf.windeast[idx]*bs.traf.gseast[idx]) / \ bs.traf.gs[idx]*bs.traf.gs[idx] # Convert to CAS rtacas = tas2cas(gsrta-tailwind,bs.traf.alt[idx]) # Performance limits on speed will be applied in traf.update if bs.traf.actwp.spdcon[idx]<0. and bs.traf.swvnavspd[idx]: bs.traf.actwp.spd[idx] = rtacas #print("setspeedforRTA: xtorta =",xtorta) return rtacas else: return False
def setspeedforRTA(self, idx, torta, xtorta): #print(bs.sim.simt,"setspeedforRTA: idx,torta,xtorta = ",idx,torta,xtorta) # Calculate required CAS to meet RTA # for aircraft nr. idx (scalar) if torta < -90.: # no RTA defined in remainder of route return False deltime = torta - bs.sim.simt # Remaining time to next RTA [s] in simtime #print("deltime =",deltime) if deltime > 0: # Still possible? # xtorta does not include speed constraint legs, and torta has been compensated for that gsrta = xtorta / deltime # Calculate along track ground speed #print("gsrta =",gsrta/kts) #print('torta, xtorta =',torta, xtorta/nm) # Subtract tail wind speed vector tailwind = (bs.traf.windnorth[idx]*bs.traf.gsnorth[idx] + bs.traf.windeast[idx]*bs.traf.gseast[idx]) / \ bs.traf.gs[idx]*bs.traf.gs[idx] #print("tailwind =",tailwind) #print("ETA wp =", tim2txt(bs.sim.simt+xtortaa / (bs.traf.gs[idx] + tailwind))) #print("RTA wp =", tim2txt(bs.sim.simt+xtorta / gsrta)) # Convert to CAS rtacas = tas2cas(gsrta - tailwind, bs.traf.alt[idx]) # Performance limits on speed will be applied in traf.update bs.traf.actwp.spd[idx] = rtacas #print("SetSpeedforRTA: rtacas =",rtacas/kts) return True else: return False
def creconfs(self, acid, actype, targetidx, dpsi, cpa, tlosh, dH=None, tlosv=None, spd=None): latref = self.lat[targetidx] # deg lonref = self.lon[targetidx] # deg altref = self.alt[targetidx] # m trkref = radians(self.trk[targetidx]) gsref = self.gs[targetidx] # m/s vsref = self.vs[targetidx] # m/s cpa = cpa * nm pzr = settings.asas_pzr * nm pzh = settings.asas_pzh * ft trk = trkref + radians(dpsi) gs = gsref if spd is None else spd if dH is None: acalt = altref acvs = 0.0 else: acalt = altref + dH tlosv = tlosh if tlosv is None else tlosv acvs = vsref - np.sign(dH) * (abs(dH) - pzh) / tlosv # Horizontal relative velocity vector gsn, gse = gs * cos(trk), gs * sin(trk) vreln, vrele = gsref * cos(trkref) - gsn, gsref * sin(trkref) - gse # Relative velocity magnitude vrel = sqrt(vreln * vreln + vrele * vrele) # Relative travel distance to closest point of approach drelcpa = tlosh * vrel + (0 if cpa > pzr else sqrt(pzr * pzr - cpa * cpa)) # Initial intruder distance dist = sqrt(drelcpa * drelcpa + cpa * cpa) # Rotation matrix diagonal and cross elements for distance vector rd = drelcpa / dist rx = cpa / dist # Rotate relative velocity vector to obtain intruder bearing brn = degrees(atan2(-rx * vreln + rd * vrele, rd * vreln + rx * vrele)) # Calculate intruder lat/lon aclat, aclon = geo.kwikpos(latref, lonref, brn, dist / nm) # convert groundspeed to CAS, and track to heading wn, we = self.wind.getdata(aclat, aclon, acalt) tasn, tase = gsn - wn, gse - we acspd = tas2cas(sqrt(tasn * tasn + tase * tase), acalt) achdg = degrees(atan2(tase, tasn)) # Create and, when necessary, set vertical speed self.create(1, actype, acalt, acspd, None, aclat, aclon, achdg, acid) self.ap.selaltcmd(len(self.lat) - 1, altref, acvs) self.vs[-1] = acvs
def creconfs(self, acid, actype, targetidx, dpsi, dcpa, tlosh, dH=None, tlosv=None, spd=None): ''' Create an aircraft in conflict with target aircraft. Arguments: - acid: callsign of new aircraft - actype: aircraft type of new aircraft - targetidx: id (callsign) of target aircraft - dpsi: Conflict angle (angle between tracks of ownship and intruder) (deg) - cpa: Predicted distance at closest point of approach (NM) - tlosh: Horizontal time to loss of separation ((hh:mm:)sec) - dH: Vertical distance (ft) - tlosv: Vertical time to loss of separation - spd: Speed of new aircraft (CAS/Mach, kts/-) ''' latref = self.lat[targetidx] # deg lonref = self.lon[targetidx] # deg altref = self.alt[targetidx] # m trkref = radians(self.trk[targetidx]) gsref = self.gs[targetidx] # m/s tasref = self.tas[targetidx] # m/s vsref = self.vs[targetidx] # m/s cpa = dcpa * nm pzr = bs.settings.asas_pzr * nm pzh = bs.settings.asas_pzh * ft trk = trkref + radians(dpsi) if dH is None: acalt = altref acvs = 0.0 else: acalt = altref + dH tlosv = tlosh if tlosv is None else tlosv acvs = vsref - np.sign(dH) * (abs(dH) - pzh) / tlosv if spd: # CAS or Mach provided: convert to groundspeed, assuming that # wind at intruder position is similar to wind at ownship position tas = tasref if spd is None else casormach2tas(spd, acalt) tasn, tase = tas * cos(trk), tas * sin(trk) wn, we = self.wind.getdata(latref, lonref, acalt) gsn, gse = tasn + wn, tase + we else: # Groundspeed is the same as ownship gsn, gse = gsref * cos(trk), gsref * sin(trk) # Horizontal relative velocity vector vreln, vrele = gsref * cos(trkref) - gsn, gsref * sin(trkref) - gse # Relative velocity magnitude vrel = sqrt(vreln * vreln + vrele * vrele) # Relative travel distance to closest point of approach drelcpa = tlosh * vrel + (0 if cpa > pzr else sqrt(pzr * pzr - cpa * cpa)) # Initial intruder distance dist = sqrt(drelcpa * drelcpa + cpa * cpa) # Rotation matrix diagonal and cross elements for distance vector rd = drelcpa / dist rx = cpa / dist # Rotate relative velocity vector to obtain intruder bearing brn = degrees(atan2(-rx * vreln + rd * vrele, rd * vreln + rx * vrele)) # Calculate intruder lat/lon aclat, aclon = geo.kwikpos(latref, lonref, brn, dist / nm) # convert groundspeed to CAS, and track to heading using actual # intruder position wn, we = self.wind.getdata(aclat, aclon, acalt) tasn, tase = gsn - wn, gse - we acspd = tas2cas(sqrt(tasn * tasn + tase * tase), acalt) achdg = degrees(atan2(tase, tasn)) # Create and, when necessary, set vertical speed self.cre(acid, actype, aclat, aclon, achdg, acalt, acspd) self.ap.selaltcmd(len(self.lat) - 1, altref, acvs) self.vs[-1] = acvs