def setrunways(self,cmdargs): self.runways = [] self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] self.rwytotime = [] for runwayname in cmdargs: if runwayname[0] == "R": success, rwyposobj = txt2pos(self.name + "/" + runwayname, self.lat, self.lon) else: success,rwyposobj = txt2pos(self.name+"/RW"+runwayname,self.lat,self.lon) if success: self.runways.append(runwayname) self.rwylat.append(rwyposobj.lat) self.rwylon.append(rwyposobj.lon) rwyname = runwayname.upper().lstrip('RWY') #try: if True: self.rwyhdg.append(navdb.rwythresholds[self.name][rwyname][2]) #if self.name=="EHAM": #S print("runway added with hdg:",self.rwyhdg[-1]) #except: # success = False self.rwyline.append(0) self.rwytotime.append(-999.)
def setrunways(self,cmdargs): self.runways = [] self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] self.rwytotime = [] for runwayname in cmdargs: if runwayname[0] == "R": success, rwyposobj = txt2pos(self.name + "/" + runwayname, self.lat, self.lon) else: success,rwyposobj = txt2pos(self.name+"/RW"+runwayname,self.lat,self.lon) if success: self.runways.append(runwayname) self.rwylat.append(rwyposobj.lat) self.rwylon.append(rwyposobj.lon) rwyname = runwayname.upper().lstrip('RWY') #try: if True: self.rwyhdg.append(navdb.rwythresholds[self.name][rwyname][2]) #if self.name=="EHAM": #S print("runway added with hdg:",self.rwyhdg[-1]) #except: # success = False self.rwyline.append(0) self.rwytotime.append(-999.) else: self.runways.append(runwayname) self.rwylat.append(self.lat) self.rwylon.append(self.lon) rwydigits = runwayname.lstrip("RWY").rstrip("LCR") self.rwyhdg.append(10. * int(rwydigits.rstrip("LCR").lstrip("0"))) self.rwyline.append(0) self.rwytotime.append(-999.)
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 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 setorig(self, acidx: 'acid', wpname: 'wpt' = None): ''' ORIG acid, latlon/airport Set origin of aircraft. ''' if wpname is None: return True, 'ORIG ' + bs.traf.id[acidx] + ': ' + self.orig[acidx] route = self.route[acidx] apidx = bs.navdb.getaptidx(wpname) if apidx < 0: if bs.traf.ap.route[acidx].nwp > 0: reflat = bs.traf.ap.route[acidx].wplat[-1] reflon = bs.traf.ap.route[acidx].wplon[-1] else: reflat = bs.traf.lat[acidx] reflon = bs.traf.lon[acidx] success, posobj = txt2pos(wpname, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, ("ORIG: Position " + wpname + " not found.") else: lat = bs.navdb.aptlat[apidx] lon = bs.navdb.aptlon[apidx] # Origin: bookkeeping only for now, store in route as origin self.orig[acidx] = wpname iwp = route.addwpt(acidx, self.orig[acidx], route.orig, lat, lon, 0.0, bs.traf.cas[acidx]) if iwp < 0: return False, (self.orig[acidx] + " not found.")
def setrunways(self,cmdargs): self.runways = [] self.rwylat = [] self.rwylon = [] self.rwyhdg = [] for runwayname in cmdargs: if runwayname[0] == "R": success, rwyposobj = txt2pos(self.name + "/" + runwayname, self.lat, self.lon) else: success,rwyposobj = txt2pos(self.name+"/RW"+runwayname,self.lat,self.lon) if success: self.runways.append(runwayname) self.rwylat.append(rwyposobj.lat) self.rwylon.append(rwyposobj.lon) rwyname = runwayname.upper().lstrip('RWY').lstrip("RW") try: self.rwyhdg.append(navdb.rwythresholds[self.name][rwyname][2]) except: success = False
def setrunways(self,cmdargs): self.runways = [] self.rwylat = [] self.rwylon = [] self.rwyhdg = [] for runwayname in cmdargs: if runwayname[0] == "R": success, rwyposobj = txt2pos(self.name + "/" + runwayname, self.lat, self.lon) else: success,rwyposobj = txt2pos(self.name+"/RW"+runwayname,self.lat,self.lon) if success: self.runways.append(runwayname) self.rwylat.append(rwyposobj.lat) self.rwylon.append(rwyposobj.lon) rwyname = runwayname.upper().lstrip('RWY').lstrip("RW") try: self.rwyhdg.append(navdb.rwythresholds[self.name][rwyname][2]) except: success = False
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 setdest(self, acidx: 'acid', wpname: 'wpt' = None): ''' DEST acid, latlon/airport Set destination of aircraft, aircraft wil fly to this airport. ''' if wpname is None: return True, 'DEST ' + bs.traf.id[acidx] + ': ' + self.dest[acidx] route = self.route[acidx] apidx = bs.navdb.getaptidx(wpname) if apidx < 0: if bs.traf.ap.route[acidx].nwp > 0: reflat = bs.traf.ap.route[acidx].wplat[-1] reflon = bs.traf.ap.route[acidx].wplon[-1] else: reflat = bs.traf.lat[acidx] reflon = bs.traf.lon[acidx] success, posobj = txt2pos(wpname, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, "DEST: Position " + wpname + " not found." else: lat = bs.navdb.aptlat[apidx] lon = bs.navdb.aptlon[apidx] self.dest[acidx] = wpname iwp = route.addwpt(acidx, self.dest[acidx], route.dest, lat, lon, 0.0, bs.traf.cas[acidx]) # If only waypoint: activate if (iwp == 0) or (self.orig[acidx] != "" and route.nwp == 2): bs.traf.actwp.lat[acidx] = route.wplat[iwp] bs.traf.actwp.lon[acidx] = route.wplon[iwp] bs.traf.actwp.nextaltco[acidx] = route.wpalt[iwp] bs.traf.actwp.spd[acidx] = route.wpspd[iwp] bs.traf.swlnav[acidx] = True bs.traf.swvnav[acidx] = True route.iactwp = iwp route.direct(acidx, route.wpname[iwp]) # If not found, say so elif iwp < 0: return False, ('DEST position' + self.dest[acidx] + " not found.")
def addorig(self,cmdargs): # Add origin with a given aircraft types origname = cmdargs[0] try: freq = int(cmdargs[1]) except: freq = 1 # Get a/c types frequency list, if given origactypes = [] if len(cmdargs) > 2: # also types are given for this origin for c in cmdargs[2:]: if c.count(":") > 0: actype, typefreq = c.split(":") else: actype = c typefreq = "1" for f in range(int(typefreq)): origactypes.append(actype) if not origname[:4]=="SEGM": success,posobj = txt2pos(origname,self.lat,self.lon) if success: incirc = incircle(posobj.lat, posobj.lon) if posobj.type == "rwy": for i in range(freq): self.orig.append(origname) self.origlat.append(posobj.lat) self.origlon.append(posobj.lon) self.orighdg.append(None) self.origtype.append(posobj.type) self.origactypes.append(origactypes) self.origincirc.append(incirc) else: for i in range(freq): self.orig.append(origname) self.origlat.append(posobj.lat) self.origlon.append(posobj.lon) self.orighdg.append(None) self.origtype.append(posobj.type) self.origactypes.append(origactypes) self.origincirc.append(incirc) else: for i in range(freq): name = "SEGM" + str(int(random.random() * 360.)) lat, lon, hdg = getseg(name) self.orig.append(name) self.origlat.append(lat) self.origlon.append(lon) self.orighdg.append(None) self.origtype.append("seg") self.origactypes.append(origactypes) self.origincirc.append(False) else: # Segment as origin, bearing from center = heading lat,lon,hdg = getseg(origname) self.orig.append(origname) self.origlat.append(lat) self.origlon.append(lon) self.orighdg.append(hdg) self.origtype.append("seg") self.origactypes.append(origactypes) self.origincirc.append(incircle(lat,lon)) return True
def __init__(self,name,cmd,cmdargs): self.name = name.upper() self.tupdate = sim.simt-999. self.flow = 0 self.incircle = True self.segdir = None # Segment direction in degrees # Is location a circle segment? if self.name[:4]=="SEGM": self.type = "seg" self.lat,self.lon,brg = getseg(self.name) # For SEGMnnn to SEGMnnn for crossing flights optional pass else: success, posobj = txt2pos(name,ctrlat,ctrlon) if success: # for runway type, get heading as default optional argument for command line if posobj.type == "rwy": aptname, rwyname = name.split('/RW') rwyname = rwyname.lstrip('Y') try: rwyhdg = navdb.rwythresholds[aptname][rwyname][2] except: rwyhdg = None pass else: rwyhdg = None self.lat,self.lon = posobj.lat, posobj.lon self.type = posobj.type # If outside circle change lat,lon to edge of circle self.incircle = incircle(self.lat,self.lon) if not self.incircle: self.type = "seg" self.segdir,dist = qdrdist(ctrlat,ctrlon,posobj.lat,posobj.lon) segname = "SEGM"+str(int(round(self.segdir))) self.lat,self.lon,hdg = getseg(segname) else: print("ERROR: trafgen class Drain called for "+name+". Position not found") self.lat,self.lon = 0.0,0.0 # Aircraft types self.actypes = ["*"] # Runways self.runways = [] # name self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] # number of aircraft waiting in line #Origins self.orig = [] self.origlat = [] self.origlon = [] self.origtype = [] # "apt","wpt","seg" self.orighdg = [] # if orig is a runway (for flights within FIR) or circle segment (drain outside FIR) self.origactypes = [] # Types for this originations ([]=use defaults for this drain) self.origincirc = [] # Limits on start values alt,spd,hdg self.startaltmin = None self.startaltmax = None self.startspdmin = None self.startspdmax = None self.starthdgmin = None self.starthdgmax = None #Names of drawing objects runways self.polys = [] return
def update(self,gain): # Time step update of source # Get time step dt = sim.simt - self.tupdate self.tupdate = sim.simt # Time for a new aircraft? if dt>0.0: # Calculate probability of a geberate occurring with flow chances = 1.0-gain*self.flow*dt/3600. #flow is in a/c per hour=360 seconds if random.random() >= chances: # Runways defined? => use runway lines (queues) if len(self.runways)>0: # We do not yet need to create an aircraft gennow = False # Find shortest line and put it in isel = random.randint(0,len(self.runways)-1) self.rwyline[isel] = self.rwyline[isel] + 1 else: # Yes we do need to generate one now gennow = True else: gennow = False # Check for generating aircraft # First check runways for a/c already in line: txt = "" for i in range(len(self.runways)): # Runway vacated and there is one waiting? if sim.simt-self.rwytotime[i]>self.dtakeoff and self.rwyline[i]>0: #if self.name == "EHAM": # print(sim.simt, self.runways[i], self.rwytotime[i]) self.rwytotime[i] = sim.simt self.rwyline[i] = self.rwyline[i]-1 # Choose and aicraft type, check for distance if len(self.dest)>0: idest = int(random.random() * len(self.dest)) else: idest = -1 if idest>=0: acid = randacname(self.name,self.dest[idest]) if self.desttype[idest]=="seg" or self.dest[idest][:4]=="SEGM": lat,lon,hdg = getseg(self.dest[idest]) else: success,posobj = txt2pos(self.dest[idest],ctrlat,ctrlon) lat,lon = posobj.lat,posobj.lon distroute = latlondist(self.lat,self.lon,lat,lon)/nm else: acid = randacname(self.name, self.name) if self.destactypes[idest] == []: actype = random.choice(self.actypes) actype = checkactype(actype, distroute, self.actypes) else: actype = random.choice(self.destactypes[idest]) stack.stack("CRE "+",".join([acid, actype, str(self.rwylat[i]),str(self.rwylon[i]),str(self.rwyhdg[i]), "0.0","0.0"])) #wplat,wplon = kwikpos(self.rwylat[i],self.rwylon[i],self.rwyhdg[i],5.0*nm) #stack.stack(acid + " ADDWPT ",wplat," ",wplon) #stack.stack(acid+"LNAV ON") if idest>=0: if self.dest[idest][:4] != "SEGM": stack.stack(acid + " DEST " + self.dest[idest]) else: stack.stack(acid + " DEST " + str(self.destlat[idest]) + " " + str(self.destlon[idest])) if self.name[:4] != "SEGM": stack.stack(acid + " ORIG " + self.name) else: stack.stack(acid + " ORIG " + str(self.lat) + " " + str(self.lon)) stack.stack(acid + " SPD 250") stack.stack(acid + " ALT FL100") stack.stack(acid + " HDG " + str(self.rwyhdg[i])) stack.stack(acid+" LNAV OFF") # Not runway, then define instantly at position with random heading or in case of segment inward heading if gennow: if not self.incircle: lat,lon = kwikpos(ctrlat,ctrlon,self.segdir,radius) hdg = self.segdir-180 elif self.type=="seg": lat,lon,brg = getseg(self.name) hdg = (brg+180)%360 elif self.type=="rwy": lat,lon = self.lat,self.lon hdg = self.hdg # Runway heading else: hdg = random.random()*360. if self.startaltmin and self.startaltmax: alt = random.randint(int(self.startaltmin), int(self.startaltmax)) else: alt = random.randint(200, 300) * 100 * ft if self.startspdmin and self.startspdmax: spd = random.randint(int(self.startspdmin), int(self.startspdmax)) else: spd = random.randint(250, 350) alttxt, spdtxt = "FL" + str(int(round(alt / (100 * ft)))), str(spd) # Add destination if len(self.dest)>0: idest = int(random.random() * len(self.dest)) acid = randacname(self.name,self.dest[idest]) else: acid = randacname(self.name,self.name) idest = -1 stack.stack("CRE " + ",".join([acid, random.choice(self.actypes), str(self.lat), str(self.lon), str(int(hdg%360)), alttxt,spdtxt])) if idest>=0: if self.dest[idest][:4] != "SEGM": stack.stack(acid + " DEST " + self.dest[idest]) else: stack.stack(acid + " DEST " + str(self.destlat[idest])+" "+str(self.destlon[idest])) if self.name[:4] != "SEGM": stack.stack(acid + " ORIG " + self.name) else: stack.stack(acid + " ORIG " + str(self.lat)+" "+str(self.lon)) if alttxt=="0" and spdtxt =="0": stack.stack(acid+" SPD 250") stack.stack(acid+" ALT FL100") else: if idest>=0: if self.desttype[idest] == "seg": lat, lon, hdg = getseg(self.dest[idest]) brg, dist = kwikqdrdist(self.lat, self.lon, lat, lon) stack.stack(acid + " HDG " + str(brg)) else: stack.stack(acid + " LNAV ON")
def __init__(self,name,cmd,cmdargs): self.name = name.upper() self.tupdate = sim.simt-999. self.flow = 0 self.incircle = True self.segdir = None # Segment direction in degrees self.hdg = None # When runway is used as separate airport # Is location a circle segment? if swcircle and self.name[:4]=="SEGM": self.type = "seg" self.lat,self.lon,brg = getseg(self.name) pass else: success, posobj = txt2pos(name,ctrlat,ctrlon) if success: # for runway type, get heading as default optional argument for command line if posobj.type == "rwy": aptname, rwyname = name.split('/RW') rwyname = rwyname.lstrip('Y') try: self.hdg = navdb.rwythresholds[aptname][rwyname][2] except: self.hdg = None pass else: rwyhdg = None self.lat,self.lon = posobj.lat, posobj.lon self.type = posobj.type # If outside circle change lat,lon to edge of circle self.incircle = incircle(self.lat,self.lon) if not self.incircle: self.type = "seg" self.segdir,dist = qdrdist(ctrlat,ctrlon,posobj.lat,posobj.lon) segname = "SEGM"+str(int(round(self.segdir))) self.lat,self.lon,hdg = getseg(segname) else: print("ERROR: trafgen class Source called for "+name+". Position not found") self.lat,self.lon = 0.0,0.0 # Aircraft types self.actypes = ["*"] # Runways self.runways = [] # name self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] # number of aircraft waiting in line self.rwytotime = [] # time of last takeoff self.dtakeoff = 90. # sec take-off interval on one runway, default 90 sec # Destinations self.dest = [] self.destlat = [] self.destlon = [] self.desttype = [] # "apt","wpt","seg" self.desthdg = [] # if dest is a runway (for flights within FIR) or circle segment (source outside FIR) self.destactypes = [] # Types for this destinations ([]=use defaults for this source) #Names of drawing objects runways self.polys = [] # Names of current runway polygons to remove when runways change # Start values self.startaltmin = -999. # [ft] minimum starting altitude self.startaltmax = -999. # [ft] maximum starting altitude self.startspdmin = -999. # [m/s] minimum starting speed self.startspdmax = -999. # [m/s] maximum starting speed self.starthdgmin = -999. # [deg] Valid values -360 - 360 degrees (to also have an interval possible around 360) self.starthdgmax = -999. # [deg] Valid values -360 - 360 degrees (to also have an interval possible around 360) return
def setdestorig(self, cmd, idx, *args): if len(args) == 0: if cmd == 'DEST': return True, 'DEST ' + bs.traf.id[idx] + ': ' + self.dest[idx] else: return True, 'ORIG ' + bs.traf.id[idx] + ': ' + self.orig[idx] if idx < 0 or idx >= bs.traf.ntraf: return False, cmd + ": Aircraft does not exist." route = self.route[idx] name = args[0] apidx = bs.navdb.getaptidx(name) if apidx < 0: if cmd == "DEST" and bs.traf.ap.route[idx].nwp > 0: reflat = bs.traf.ap.route[idx].wplat[-1] reflon = bs.traf.ap.route[idx].wplon[-1] else: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, (cmd + ": Position " + name + " not found.") else: lat = bs.navdb.aptlat[apidx] lon = bs.navdb.aptlon[apidx] if cmd == "DEST": self.dest[idx] = name iwp = route.addwpt(idx, self.dest[idx], route.dest, lat, lon, 0.0, bs.traf.cas[idx]) # If only waypoint: activate if (iwp == 0) or (self.orig[idx] != "" and route.nwp == 2): bs.traf.actwp.lat[idx] = route.wplat[iwp] bs.traf.actwp.lon[idx] = route.wplon[iwp] bs.traf.actwp.nextaltco[idx] = route.wpalt[iwp] bs.traf.actwp.spd[idx] = route.wpspd[iwp] bs.traf.swlnav[idx] = True bs.traf.swvnav[idx] = True route.iactwp = iwp route.direct(idx, route.wpname[iwp]) # If not found, say so elif iwp < 0: return False, ('DEST' + self.dest[idx] + " not found.") # Origin: bookkeeping only for now, store in route as origin else: self.orig[idx] = name apidx = bs.navdb.getaptidx(name) if apidx < 0: if cmd == "ORIG" and bs.traf.ap.route[idx].nwp > 0: reflat = bs.traf.ap.route[idx].wplat[0] reflon = bs.traf.ap.route[idx].wplon[0] else: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, (cmd + ": Orig " + name + " not found.") iwp = route.addwpt(idx, self.orig[idx], route.orig, lat, lon, 0.0, bs.traf.cas[idx]) if iwp < 0: return False, (self.orig[idx] + " not found.")
def addwptStack(self, idx, *args): # args: all arguments of addwpt """ADDWPT acid, (wpname/lat,lon),[alt],[spd],[afterwp],[beforewp]""" # print "addwptStack:",args # Check FLYBY or FLYOVER switch, instead of adding a waypoint if len(args) == 1: isflyby = args[0].replace('-', '') if isflyby == "FLYBY": self.swflyby = True return True elif isflyby == "FLYOVER": self.swflyby = False return True # Convert to positions name = args[0].upper().strip() # Choose reference position ot look up VOR and waypoints # First waypoint: own position if self.nwp == 0: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] # Or last waypoint before destination else: if self.wptype[-1] != Route.dest or self.nwp == 1: reflat = self.wplat[-1] reflon = self.wplon[-1] else: reflat = self.wplat[-2] reflon = self.wplon[-2] # Default altitude, speed and afterwp alt = -999. spd = -999. afterwp = "" beforewp = "" # Is it aspecial take-off waypoint? takeoffwpt = name.replace('-', '') == "TAKEOFF" # Normal waypoint (no take-off waypoint => see else) if not takeoffwpt: # Get waypoint position success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon if posobj.type == "nav" or posobj.type == "apt": wptype = Route.wpnav elif posobj.type == "rwy": wptype = Route.runway else: # treat as lat/lon name = bs.traf.id[idx] wptype = Route.wplatlon if len(args) > 1 and args[1]: alt = args[1] if len(args) > 2 and args[2]: spd = args[2] if len(args) > 3 and args[3]: afterwp = args[3] if len(args) > 4 and args[4]: beforewp = args[4] else: return False, "Waypoint " + name + " not found." # Take off waypoint: positioned 20% of the runway length after the runway else: # Look up runway in route rwyrteidx = -1 i = 0 while i<self.nwp and rwyrteidx<0: if self.wpname[i].count("/") >0: # print (self.wpname[i]) rwyrteidx = i i += 1 # Only TAKEOFF is specified wihtou a waypoint/runway if len(args) == 1 or not args[1]: # No runway given: use first in route or current position # print ("rwyrteidx =",rwyrteidx) # We find a runway in the route, so use it if rwyrteidx>0: rwylat = self.wplat[rwyrteidx] rwylon = self.wplon[rwyrteidx] aptidx = bs.navdb.getapinear(rwylat,rwylon) aptname = bs.navdb.aptname[aptidx] rwyname = self.wpname[rwyrteidx].split("/")[1] rwyid = rwyname.replace("RWY","").replace("RW","") rwyhdg = bs.navdb.rwythresholds[aptname][rwyid][2] else: rwylat = bs.traf.lat[idx] rwylon = bs.traf.lon[idx] rwyhdg = bs.traf.trk[idx] elif args[1].count("/") > 0 or len(args) > 2 and args[2]: # we need apt,rwy # Take care of both EHAM/RW06 as well as EHAM,RWY18L (so /&, and RW/RWY) if args[1].count("/")>0: aptid,rwyname = args[1].split("/") else: # Runway specified aptid = args[1] rwyname = args[2] rwyid = rwyname.replace("RWY", "").replace("RW", "") # take away RW or RWY # print ("apt,rwy=",aptid,rwyid) # TDO: Add fingind the runway heading with rwyrteidx>0 and navdb!!! # Try to get it from the database try: rwyhdg = bs.navdb.rwythresholds[aptid][rwyid][2] except: rwydir = rwyid.replace("L","").replace("R","").replace("C","") try: rwyhdg = float(rwydir)*10. except: return False,name+" not found." success, posobj = txt2pos(aptid+"/RW"+rwyid, reflat, reflon) if success: rwylat,rwylon = posobj.lat,posobj.lon else: rwylat = bs.traf.lat[idx] rwylon = bs.traf.lon[idx] else: return False,"Use ADDWPT TAKEOFF,AIRPORTID,RWYNAME" # Create a waypoint 2 nm away from current point rwydist = 2.0 # [nm] use default distance away from threshold lat,lon = geo.qdrpos(rwylat, rwylon, rwyhdg, rwydist) #[deg,deg wptype = Route.wplatlon # Add after the runwy in the route if rwyrteidx > 0: afterwp = self.wpname[rwyrteidx] elif self.wptype and self.wptype[0] == Route.orig: afterwp = self.wpname[0] else: # Assume we're called before other waypoints are added afterwp = "" name = "T/O-" + bs.traf.id[idx] # Use lat/lon naming convention # Add waypoint wpidx = self.addwpt(idx, name, wptype, lat, lon, alt, spd, afterwp, beforewp) # Check for success by checking insetred locaiton in flight plan >= 0 if wpidx < 0: return False, "Waypoint " + name + " not added." # chekc for presence of orig/dest norig = int(bs.traf.ap.orig[idx] != "") ndest = int(bs.traf.ap.dest[idx] != "") # Check whether this is first 'real' wayppint (not orig & dest), # And if so, make active if self.nwp - norig - ndest == 1: # first waypoint: make active self.direct(idx, self.wpname[norig]) # 0 if no orig bs.traf.swlnav[idx] = True if afterwp and self.wpname.count(afterwp) == 0: return True, "Waypoint " + afterwp + " not found" + \ "waypoint added at end of route" else: return True
def trafgencmd(cmdline): global ctrlat,ctrlon,radius,dtsegment,drains,sources,rwsdep,rwsarr,globalgain cmd,args = splitline(cmdline) #print("TRAFGEN: cmd,args=",cmd,args) if cmd=="CIRCLE" or cmd=="CIRC": # Draw circle try: swcircle = True ctrlat = float(args[0]) ctrlon = float(args[1]) radius = float(args[2]) setcircle(ctrlat, ctrlon, radius) except: return False,'TRAFGEN ERROR while reading CIRCLE command arguments (lat,lon,radius):'+str(args) stack.stack("DEL SPAWN") stack.stack("CIRCLE SPAWN," + str(ctrlat) + "," + str(ctrlon) + "," + str(radius)) elif cmd=="GAIN" or cmd=="FACTOR": # Set global gain on traffic density try: globalgain = float(args[0]) except: return False, "TRAFGEN GAIN error: invalid value "+args[0] elif cmd=="SRC" or cmd == "SOURCE": # Define streams by source, give destinations name = args[0].upper() cmd = args[1].upper() cmdargs = args[2:] if name not in sources: if not name[:4] == "SEGM": success,posobj = txt2pos(name,ctrlat,ctrlon) if success: aptlat, aptlon = posobj.lat, posobj.lon sources[name] = Source(name,cmd,cmdargs) if posobj.type == "rwy" and name.count("/")==1: aptname, rwyname = name.split('/') sources[name].polys += drawrwy(aptname,[rwyname],posobj.lat,posobj.lon,drawdeprwy) else: try: brg = int(name[4:]) aptlat,aptlon = kwikpos(ctrlat,ctrlon,brg,radius) sources[name] = Source(name, cmd, cmdargs) success = True except: success = False else: aptlat,aptlon = sources[name].lat,sources[name].lat success = True if success: if cmd[:6]=="RUNWAY" or cmd=="RWY": sources[name].setrunways(cmdargs) for polyname in sources[name].polys: stack.stack("DEL "+polyname) sources[name].polys += drawrwy(name,cmdargs,aptlat,aptlon,drawdeprwy) elif cmd=="DEST": success = sources[name].adddest(cmdargs) elif cmd=="FLOW": success = sources[name].setflow(cmdargs[0]) elif cmd=="TYPES" or cmd=="TYPE": sources[name].addactypes(cmdargs) elif cmd=="ALT": # Set fixed alt or interval sources[name].setalt(cmdargs) elif cmd=="SPD": sources[name].setspd(cmdargs) elif cmd=="HDG": sources[name].sethdg(cmdargs) if not success: return False, "TRAFGEN SRC ERROR"+cmd+" ".join(cmdargs) else: return False,"TRAFGEN SRC ERROR "+name+" NOT FOUND" elif cmd=="DRN" or cmd=="DRAIN": name = args[0].upper() cmd = args[1].upper() cmdargs = args[2:] if name in drains: aptlat, aptlon = drains[name].lat, drains[name].lat success = True else: # name not in drains: New drain defined if not name[:4]=="SEGM": success, posobj = txt2pos(name, ctrlat, ctrlon) if success: drains[name] = Drain(name, cmd, cmdargs) if posobj.type == "rwy" and name.count("/") == 1: aptname, rwyname = name.split('/') drains[name].polys += drawrwy(aptname, [rwyname], posobj.lat, posobj.lon, drawapprwy) else: try: brg = int(name[:4]) drains[name] = Drain(name, cmd, cmdargs) success = True except: success = False if success: if cmd[:6] == "RUNWAY" or cmd == "RWY": # Delete old runways for polyname in drains[name].polys: stack.stack("DEL "+polyname) aptlat, aptlon = drains[name].lat,drains[name].lon drains[name].setrunways(cmdargs) drains[name].polys += drawrwy(name,cmdargs,aptlat,aptlon,drawapprwy) elif cmd=="ORIG": success = drains[name].addorig(cmdargs) elif cmd=="FLOW": sucess = drains[name].setflow(cmdargs[0]) elif cmd=="TYPES" or cmd=="TYPE": drains[name].addactypes(cmdargs) elif cmd == "ALT": # Set fixed alt or interval drains[name].setalt(cmdargs) elif cmd == "SPD": drains[name].setspd(cmdargs) elif cmd == "HDG": drains[name].sethdg(cmdargs) if not success: return False, "TRAFGEN SRC ERROR"+cmd+" ".join(cmdargs) else: return False, "TRAFGEN DRN ERROR " + name + " NOT FOUND" return True
def addorig(self,cmdargs): # Add origin with a given aircraft types origname = cmdargs[0] try: freq = int(cmdargs[1]) except: freq = 1 # Get a/c types frequency list, if given origactypes = [] if len(cmdargs) > 2: # also types are given for this origin for c in cmdargs[2:]: if c.count(":") > 0: actype, typefreq = c.split(":") else: actype = c typefreq = "1" for f in range(int(typefreq)): origactypes.append(actype) if not origname[:4]=="SEGM": success,posobj = txt2pos(origname,self.lat,self.lon) if success: incirc = incircle(posobj.lat, posobj.lon) if posobj.type == "rwy": for i in range(freq): self.orig.append(origname) self.origlat.append(posobj.lat) self.origlon.append(posobj.lon) self.orighdg.append(None) self.origtype.append(posobj.type) self.origactypes.append(origactypes) self.origincirc.append(incirc) else: for i in range(freq): self.orig.append(origname) self.origlat.append(posobj.lat) self.origlon.append(posobj.lon) self.orighdg.append(None) self.origtype.append(posobj.type) self.origactypes.append(origactypes) self.origincirc.append(incirc) else: for i in range(freq): name = "SEGM" + str(int(random.random() * 360.)) lat, lon, hdg = getseg(name) self.orig.append(name) self.origlat.append(lat) self.origlon.append(lon) self.orighdg.append(None) self.origtype.append("seg") self.origactypes.append(origactypes) self.origincirc.append(False) else: # Segment as origin, bearing from center = heading lat,lon,hdg = getseg(origname) self.orig.append(origname) self.origlat.append(lat) self.origlon.append(lon) self.orighdg.append(hdg) self.origtype.append("seg") self.origactypes.append(origactypes) self.origincirc.append(incircle(lat,lon)) return True
def __init__(self,name,cmd,cmdargs): self.name = name.upper() self.tupdate = sim.simt-999. self.flow = 0 self.incircle = True self.segdir = None # Segment direction in degrees # Is location a circle segment? if self.name[:4]=="SEGM": self.type = "seg" self.lat,self.lon,brg = getseg(self.name) # For SEGMnnn to SEGMnnn for crossing flights optional pass else: success, posobj = txt2pos(name,ctrlat,ctrlon) if success: # for runway type, get heading as default optional argument for command line if posobj.type == "rwy": aptname, rwyname = name.split('/RW') rwyname = rwyname.lstrip('Y') try: rwyhdg = navdb.rwythresholds[aptname][rwyname][2] except: rwyhdg = None pass else: rwyhdg = None self.lat,self.lon = posobj.lat, posobj.lon self.type = posobj.type # If outside circle change lat,lon to edge of circle self.incircle = incircle(self.lat,self.lon) if not self.incircle: self.type = "seg" self.segdir,dist = qdrdist(ctrlat,ctrlon,posobj.lat,posobj.lon) segname = "SEGM"+str(int(round(self.segdir))) self.lat,self.lon,hdg = getseg(segname) else: print("ERROR: trafgen class Drain called for "+name+". Position not found") self.lat,self.lon = 0.0,0.0 # Aircraft types self.actypes = ["*"] # Runways self.runways = [] # name self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] # number of aircraft waiting in line #Origins self.orig = [] self.origlat = [] self.origlon = [] self.origtype = [] # "apt","wpt","seg" self.orighdg = [] # if orig is a runway (for flights within FIR) or circle segment (drain outside FIR) self.origactypes = [] # Types for this originations ([]=use defaults for this drain) self.origincirc = [] #Names of drawing objects runways self.polys = [] return
def update(self,gain): # Time step update of source # Get time step dt = sim.simt - self.tupdate self.tupdate = sim.simt # Time for a new aircraft? if dt>0.0: # Calculate probability of a geberate occurring with flow chances = 1.0-gain*self.flow*dt/3600. #flow is in a/c per hour=360 seconds if random.random() >= chances: # Runways defined? => use runway lines (queues) if len(self.runways)>0: # We do not yet need to create an aircraft gennow = False # Find shortest line and put it in isel = random.randint(0,len(self.runways)-1) self.rwyline[isel] = self.rwyline[isel] + 1 else: # Yes we do need to generate one now gennow = True else: gennow = False # Check for generating aircraft # First check runways for a/c already in line: txt = "" for i in range(len(self.runways)): # Runway vacated and there is one waiting? if sim.simt-self.rwytotime[i]>self.dtakeoff and self.rwyline[i]>0: #if self.name == "EHAM": # print(sim.simt, self.runways[i], self.rwytotime[i]) self.rwytotime[i] = sim.simt self.rwyline[i] = self.rwyline[i]-1 # Choose and aicraft type, check for distance if len(self.dest)>0: idest = int(random.random() * len(self.dest)) else: idest = -1 if idest>=0: acid = randacname(self.name,self.dest[idest]) if self.desttype[idest]=="seg" or self.dest[idest][:4]=="SEGM": lat,lon,hdg = getseg(self.dest[idest]) else: success,posobj = txt2pos(self.dest[idest],ctrlat,ctrlon) lat,lon = posobj.lat,posobj.lon distroute = latlondist(self.lat,self.lon,lat,lon)/nm else: acid = randacname(self.name, self.name) if self.destactypes[idest] == []: actype = random.choice(self.actypes) actype = checkactype(actype, distroute, self.actypes) else: actype = random.choice(self.destactypes[idest]) stack.stack("CRE "+",".join([acid, actype, str(self.rwylat[i]),str(self.rwylon[i]),str(self.rwyhdg[i]), "0.0","0.0"])) stack.stack(acid + " SPD 250") stack.stack(acid + " ALT FL100") stack.stack(acid + " HDG " + str(self.rwyhdg[i])) # TBD: Add waypoint for after take-off? if idest>=0: if self.dest[idest][:4] != "SEGM": stack.stack(acid + " DEST " + self.dest[idest]) else: stack.stack(acid + " DEST " + str(self.destlat[idest]) + " " + str(self.destlon[idest])) if self.name[:4] != "SEGM": stack.stack(acid + " ORIG " + self.name) else: stack.stack(acid + " ORIG " + str(self.lat) + " " + str(self.lon)) if idest>=0 and self.desttype[idest]=="seg": lat,lon,hdg = getseg(self.dest[idest]) brg,dist = kwikqdrdist(self.lat,self.lon,lat,lon) #stack.stack(acid+" HDG "+str(brg)) else: stack.stack(acid+" LNAV OFF") #stack.stack(acid+" VNAV ON") # Not runway, then define instantly at position with random heading or in case of segment inward heading if gennow: if not self.incircle: lat,lon = kwikpos(ctrlat,ctrlon,self.segdir,radius) hdg = self.segdir-180 elif self.type=="seg": lat,lon,brg = getseg(self.name) hdg = (brg+180)%360 elif self.type=="rwy": lat,lon = self.lat,self.lon hdg = self.hdg # Runway heading else: hdg = random.random()*360. if (self.type=="apt" or self.type=="rwy") and self.incircle: alttxt,spdtxt = str(0),str(0) else: alttxt,spdtxt = "FL"+str(random.randint(200,300)), str(random.randint(250,350)) # Add destination if len(self.dest)>0: idest = int(random.random() * len(self.dest)) acid = randacname(self.name,self.dest[idest]) else: acid = randacname(self.name,self.name) idest = -1 stack.stack("CRE " + ",".join([acid, random.choice(self.actypes), str(self.lat), str(self.lon), str(int(hdg%360)), alttxt,spdtxt])) if idest>=0: if self.dest[idest][:4] != "SEGM": stack.stack(acid + " DEST " + self.dest[idest]) else: stack.stack(acid + " DEST " + str(self.destlat[idest])+" "+str(self.destlon[idest])) if self.name[:4] != "SEGM": stack.stack(acid + " ORIG " + self.name) else: stack.stack(acid + " ORIG " + str(self.lat)+" "+str(self.lon)) if alttxt=="0" and spdtxt =="0": stack.stack(acid+" SPD 250") stack.stack(acid+" ALT FL100") else: if idest>=0: if self.desttype[idest] == "seg": lat, lon, hdg = getseg(self.dest[idest]) brg, dist = kwikdist(self.lat, self.lon, lat, lon) stack.stack(acid + " HDG " + str(brg)) else: stack.stack(acid + " LNAV ON")
def addwptStack(self, idx, *args): # args: all arguments of addwpt """ADDWPT acid, (wpname/lat,lon),[alt],[spd],[afterwp]""" # print "addwptStack:",args # Check FLYBY or FLYOVER switch, instead of adding a waypoint if len(args) == 1: isflyby = args[0].replace('-', '') if isflyby == "FLYBY": self.swflyby = True return True elif isflyby == "FLYOVER": self.swflyby = False return True # Convert to positions name = args[0] # Choose reference position ot look up VOR and waypoints # First waypoint: own position if self.nwp == 0: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] # Or last waypoint before destination else: if self.wptype[-1] != self.dest or self.nwp == 1: reflat = self.wplat[-1] reflon = self.wplon[-1] else: reflat = self.wplat[-2] reflon = self.wplon[-2] success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon if posobj.type == "nav" or posobj.type == "apt": wptype = self.wpnav elif posobj.type == "rwy": wptype = self.runway else: # treat as lat/lon name = bs.traf.id[idx] wptype = self.wplatlon # Default altitude, speed and afterwp if not given alt = -999. if len(args) < 2 else args[1] spd = -999. if len(args) < 3 else args[2] afterwp = "" if len(args) < 4 else args[3] #Catch empty arguments (None) if alt == "" or alt is None: alt = -999 if spd == "" or spd is None: spd = -999 if afterwp is None: afterwp = "" # Add waypoint wpidx = self.addwpt(idx, name, wptype, lat, lon, alt, spd, afterwp) # Check for success by checking insetred locaiton in flight plan >= 0 if wpidx < 0: return False, "Waypoint " + name + " not added." # chekc for presence of orig/dest norig = int(bs.traf.ap.orig[idx] != "") ndest = int(bs.traf.ap.dest[idx] != "") # Check whether this is first 'real' wayppint (not orig & dest), # And if so, make active if self.nwp - norig - ndest == 1: # first waypoint: make active self.direct(idx, self.wpname[norig]) # 0 if no orig bs.traf.swlnav[idx] = True if afterwp and self.wpname.count(afterwp) == 0: return True, "Waypoint " + afterwp + " not found" + \ "waypoint added at end of route" else: return True else: return False, "Waypoint " + name + " not found."
def adddest(self,cmdargs): # Add destination with a given aircraft types destname = cmdargs[0] try: freq = int(cmdargs[1]) except: freq = 1 # Get a/c types frequency list, if given destactypes = [] if len(cmdargs) > 2: # also types are given for this destination for c in cmdargs[2:]: if c.count(":") > 0: actype, typefreq = c.split(":") else: actype = c typefreq = "1" for f in range(int(typefreq)): destactypes.append(actype) if not destname[:4]=="SEGM": success,posobj = txt2pos(destname,self.lat,self.lon) if success: if posobj.type == "rwy": for i in range(freq): self.dest.append(destname) self.destlat.append(posobj.lat) self.destlon.append(posobj.lon) self.desthdg.append(None) self.desttype.append(posobj.type) self.destactypes.append(destactypes) else: for i in range(freq): aptname = destname self.dest.append(destname) self.destlat.append(posobj.lat) self.destlon.append(posobj.lon) self.desthdg.append(0) self.desttype.append(posobj.type) self.destactypes.append(destactypes) else: # Add random destination for i in range(freq): name = "SEGM" + str(int(random.random() * 360.)) lat, lon, hdg = getseg(name) self.dest.append(name) self.destlat.append(lat) self.destlon.append(lon) self.desthdg.append(hdg) self.desttype.append("seg") self.destactypes.append(destactypes) else: for i in range(freq): # Segment as destination, bearing from center = heading lat,lon,hdg = getseg(destname) self.dest.append(destname) self.destlat.append(lat) self.destlon.append(lon) self.desthdg.append(hdg) self.desttype.append("seg") self.destactypes.append(destactypes) return True
def setdestorig(self, cmd, idx, *args): if len(args) == 0: if cmd == 'DEST': return True, 'DEST ' + bs.traf.id[idx] + ': ' + self.dest[idx] else: return True, 'ORIG ' + bs.traf.id[idx] + ': ' + self.orig[idx] if idx<0 or idx>=bs.traf.ntraf: return False, cmd + ": Aircraft does not exist." route = self.route[idx] name = args[0] apidx = bs.navdb.getaptidx(name) if apidx < 0: if cmd =="DEST" and bs.traf.ap.route[idx].nwp>0: reflat = bs.traf.ap.route[idx].wplat[-1] reflon = bs.traf.ap.route[idx].wplon[-1] else: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, (cmd + ": Position " + name + " not found.") else: lat = bs.navdb.aptlat[apidx] lon = bs.navdb.aptlon[apidx] if cmd == "DEST": self.dest[idx] = name iwp = route.addwpt(idx, self.dest[idx], route.dest, lat, lon, 0.0, bs.traf.cas[idx]) # If only waypoint: activate if (iwp == 0) or (self.orig[idx] != "" and route.nwp == 2): bs.traf.actwp.lat[idx] = route.wplat[iwp] bs.traf.actwp.lon[idx] = route.wplon[iwp] bs.traf.actwp.nextaltco[idx] = route.wpalt[iwp] bs.traf.actwp.spd[idx] = route.wpspd[iwp] bs.traf.swlnav[idx] = True bs.traf.swvnav[idx] = True route.iactwp = iwp route.direct(idx, route.wpname[iwp]) # If not found, say so elif iwp < 0: return False, ('DEST'+self.dest[idx] + " not found.") # Origin: bookkeeping only for now, store in route as origin else: self.orig[idx] = name apidx = bs.navdb.getaptidx(name) if apidx < 0: if cmd =="ORIG" and bs.traf.ap.route[idx].nwp>0: reflat = bs.traf.ap.route[idx].wplat[0] reflon = bs.traf.ap.route[idx].wplon[0] else: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon else: return False, (cmd + ": Orig " + name + " not found.") iwp = route.addwpt(idx, self.orig[idx], route.orig, lat, lon, 0.0, bs.traf.cas[idx]) if iwp < 0: return False, (self.orig[idx] + " not found.")
def __init__(self,name,cmd,cmdargs): self.name = name.upper() self.tupdate = sim.simt-999. self.flow = 0 self.incircle = True self.segdir = None # Segment direction in degrees self.hdg = None # When runway is used as separate airport # Is location a circle segment? if swcircle and self.name[:4]=="SEGM": self.type = "seg" self.lat,self.lon,brg = getseg(self.name) pass else: success, posobj = txt2pos(name,ctrlat,ctrlon) if success: # for runway type, get heading as default optional argument for command line if posobj.type == "rwy": aptname, rwyname = name.split('/RW') rwyname = rwyname.lstrip('Y') try: self.hdg = navdb.rwythresholds[aptname][rwyname][2] except: self.hdg = None pass else: rwyhdg = None self.lat,self.lon = posobj.lat, posobj.lon self.type = posobj.type # If outside circle change lat,lon to edge of circle self.incircle = incircle(self.lat,self.lon) if not self.incircle: self.type = "seg" self.segdir,dist = qdrdist(ctrlat,ctrlon,posobj.lat,posobj.lon) segname = "SEGM"+str(int(round(self.segdir))) self.lat,self.lon,hdg = getseg(segname) else: print("ERROR: trafgen class Source called for "+name+". Position not found") self.lat,self.lon = 0.0,0.0 # Aircraft types self.actypes = ["*"] # Runways self.runways = [] # name self.rwylat = [] self.rwylon = [] self.rwyhdg = [] self.rwyline = [] # number of aircraft waiting in line self.rwytotime = [] # time of last takeoff # If source type is a runway, add it as the only runway if self.type=="rwy": self.runways = [rwyname] self.rwylat = [self.lat] self.rwylon = [self.lon] self.rwyhdg = [int(rwyname.rstrip("LCR").lstrip("0"))*10.] self.rwyline = [] # number of aircraft waiting in line self.rwytotime = [-999] # time of last takeoff self.dtakeoff = 90. # sec take-off interval on one runway, default 90 sec # Destinations self.dest = [] self.destlat = [] self.destlon = [] self.desttype = [] # "apt","wpt","seg" self.desthdg = [] # if dest is a runway (for flights within FIR) or circle segment (source outside FIR) self.destactypes = [] # Types for this destinations ([]=use defaults for this source) #Names of drawing objects runways self.polys = [] # Names of current runway polygons to remove when runways change # Limits on start values alt,spd,hdg self.startaltmin = None self.startaltmax = None self.startspdmin = None self.startspdmax = None self.starthdgmin = None self.starthdgmax = None return
def addwptStack(self, idx, *args): # args: all arguments of addwpt """ADDWPT acid, (wpname/lat,lon),[alt],[spd],[afterwp],[beforewp]""" # print "addwptStack:",args # Check FLYBY or FLYOVER switch, instead of adding a waypoint if len(args) == 1: swwpmode = args[0].replace('-', '') if swwpmode == "FLYBY": self.swflyby = True self.swflyturn = False return True elif swwpmode == "FLYOVER": self.swflyby = False self.swflyturn = False return True elif swwpmode == "FLYTURN": self.swflyby = False self.swflyturn = True return True elif len(args) == 2: swwpmode = args[0].replace('-', '') if swwpmode == "TURNRAD" or swwpmode == "TURNRADIUS": try: self.turnrad = float( args[1]) / ft # arg was originally parsed as wpalt except: return False, "Error in processing value of turn radius" return True elif swwpmode == "TURNSPD" or swwpmode == "TURNSPEED": try: self.turnspd = args[ 1] * kts / ft # [m/s] Arg was wpalt Keep it as IAS/CAS orig in kts, now in m/s except: return False, "Error in processing value of turn speed" return True # Convert to positions name = args[0].upper().strip() # Choose reference position ot look up VOR and waypoints # First waypoint: own position if self.nwp == 0: reflat = bs.traf.lat[idx] reflon = bs.traf.lon[idx] # Or last waypoint before destination else: if self.wptype[-1] != Route.dest or self.nwp == 1: reflat = self.wplat[-1] reflon = self.wplon[-1] else: reflat = self.wplat[-2] reflon = self.wplon[-2] # Default altitude, speed and afterwp alt = -999. spd = -999. afterwp = "" beforewp = "" # Is it aspecial take-off waypoint? takeoffwpt = name.replace('-', '') == "TAKEOFF" # Normal waypoint (no take-off waypoint => see else) if not takeoffwpt: # Get waypoint position success, posobj = txt2pos(name, reflat, reflon) if success: lat = posobj.lat lon = posobj.lon if posobj.type == "nav" or posobj.type == "apt": wptype = Route.wpnav elif posobj.type == "rwy": wptype = Route.runway else: # treat as lat/lon name = bs.traf.id[idx] wptype = Route.wplatlon if len(args) > 1 and args[1]: alt = args[1] if len(args) > 2 and args[2]: spd = args[2] if len(args) > 3 and args[3]: afterwp = args[3] if len(args) > 4 and args[4]: beforewp = args[4] else: return False, "Waypoint " + name + " not found." # Take off waypoint: positioned 20% of the runway length after the runway else: # Look up runway in route rwyrteidx = -1 i = 0 while i < self.nwp and rwyrteidx < 0: if self.wpname[i].count("/") > 0: # print (self.wpname[i]) rwyrteidx = i i += 1 # Only TAKEOFF is specified wihtou a waypoint/runway if len(args) == 1 or not args[1]: # No runway given: use first in route or current position # print ("rwyrteidx =",rwyrteidx) # We find a runway in the route, so use it if rwyrteidx > 0: rwylat = self.wplat[rwyrteidx] rwylon = self.wplon[rwyrteidx] aptidx = bs.navdb.getapinear(rwylat, rwylon) aptname = bs.navdb.aptname[aptidx] rwyname = self.wpname[rwyrteidx].split("/")[1] rwyid = rwyname.replace("RWY", "").replace("RW", "") rwyhdg = bs.navdb.rwythresholds[aptname][rwyid][2] else: rwylat = bs.traf.lat[idx] rwylon = bs.traf.lon[idx] rwyhdg = bs.traf.trk[idx] elif args[1].count( "/") > 0 or len(args) > 2 and args[2]: # we need apt,rwy # Take care of both EHAM/RW06 as well as EHAM,RWY18L (so /&, and RW/RWY) if args[1].count("/") > 0: aptid, rwyname = args[1].split("/") else: # Runway specified aptid = args[1] rwyname = args[2] rwyid = rwyname.replace("RWY", "").replace("RW", "") # take away RW or RWY # print ("apt,rwy=",aptid,rwyid) # TODO: Add finding the runway heading with rwyrteidx>0 and navdb!!! # Try to get it from the database try: rwyhdg = bs.navdb.rwythresholds[aptid][rwyid][2] except: rwydir = rwyid.replace("L", "").replace("R", "").replace("C", "") try: rwyhdg = float(rwydir) * 10. except: return False, name + " not found." success, posobj = txt2pos(aptid + "/RW" + rwyid, reflat, reflon) if success: rwylat, rwylon = posobj.lat, posobj.lon else: rwylat = bs.traf.lat[idx] rwylon = bs.traf.lon[idx] else: return False, "Use ADDWPT TAKEOFF,AIRPORTID,RWYNAME" # Create a waypoint 2 nm away from current point rwydist = 2.0 # [nm] use default distance away from threshold lat, lon = geo.qdrpos(rwylat, rwylon, rwyhdg, rwydist) #[deg,deg wptype = Route.wplatlon # Add after the runwy in the route if rwyrteidx > 0: afterwp = self.wpname[rwyrteidx] elif self.wptype and self.wptype[0] == Route.orig: afterwp = self.wpname[0] else: # Assume we're called before other waypoints are added afterwp = "" name = "T/O-" + bs.traf.id[idx] # Use lat/lon naming convention # Add waypoint wpidx = self.addwpt(idx, name, wptype, lat, lon, alt, spd, afterwp, beforewp) # Recalculate flight plan self.calcfp() # Check for success by checking insetred locaiton in flight plan >= 0 if wpidx < 0: return False, "Waypoint " + name + " not added." # chekc for presence of orig/dest norig = int(bs.traf.ap.orig[idx] != "") ndest = int(bs.traf.ap.dest[idx] != "") # Check whether this is first 'real' waypoint (not orig & dest), # And if so, make active if self.nwp - norig - ndest == 1: # first waypoint: make active self.direct(idx, self.wpname[norig]) # 0 if no orig bs.traf.swlnav[idx] = True if afterwp and self.wpname.count(afterwp) == 0: return True, "Waypoint " + afterwp + " not found" + \ "waypoint added at end of route" else: return True
def adddest(self,cmdargs): # Add destination with a given aircraft types destname = cmdargs[0] try: freq = int(cmdargs[1]) except: freq = 1 # Get a/c types frequency list, if given destactypes = [] if len(cmdargs) > 2: # also types are given for this destination for c in cmdargs[2:]: if c.count(":") > 0: actype, typefreq = c.split(":") else: actype = c typefreq = "1" for f in range(int(typefreq)): destactypes.append(actype) if not destname[:4]=="SEGM": success,posobj = txt2pos(destname,self.lat,self.lon) if success: if posobj.type == "rwy": for i in range(freq): self.dest.append(destname) self.destlat.append(posobj.lat) self.destlon.append(posobj.lon) self.desthdg.append(None) self.desttype.append(posobj.type) self.destactypes.append(destactypes) else: for i in range(freq): aptname = destname self.dest.append(destname) self.destlat.append(posobj.lat) self.destlon.append(posobj.lon) self.desthdg.append(0) self.desttype.append(posobj.type) self.destactypes.append(destactypes) else: # Add random destination for i in range(freq): name = "SEGM" + str(int(random.random() * 360.)) lat, lon, hdg = getseg(name) self.dest.append(name) self.destlat.append(lat) self.destlon.append(lon) self.desthdg.append(hdg) self.desttype.append("seg") self.destactypes.append(destactypes) else: for i in range(freq): # Segment as destination, bearing from center = heading lat,lon,hdg = getseg(destname) self.dest.append(destname) self.destlat.append(lat) self.destlon.append(lon) self.desthdg.append(hdg) self.desttype.append("seg") self.destactypes.append(destactypes) return True