def update(self, simt, simdt): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update(simt) #---------- Fly the Aircraft -------------------------- self.ap.update(simt) self.asas.update(simt) self.pilot.APorASAS() #---------- Limit Speeds ------------------------------ self.pilot.FlightEnvelope() #---------- Kinematics -------------------------------- self.UpdateAirSpeed(simdt, simt) self.UpdateGroundSpeed(simdt) self.UpdatePosition(simdt) #---------- Performance Update ------------------------ self.perf.perf(simt) #---------- Simulate Turbulence ----------------------- self.turbulence.Woosh(simdt) #---------- Aftermath --------------------------------- self.trails.update(simt) return
def getdata(self, userlat, userlon, useralt): """ Retrieve the north and south component of the windfield, interpolated at a given positions. :param userlat: latitude [deg] :param userlon: longitude [deg] :param useralt: altitude [m] :return: two np.array containting the north component and east component of the wind. """ if self.filename: # TODO: find a faster alternative to date2num if self.ensemble_loaded: pressure = vatmos(useralt)[0] time = date2num(bs.sim.utc, units='hours since 1900-01-01 00:00:0.0', calendar='gregorian') return self.__interpolate(userlat, userlon, pressure, time) else: return 0, 0 else: return 0, 0
def update(self, simt, simdt): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update(simt) #---------- Fly the Aircraft -------------------------- self.ap.update(simt) # Autopilot logic self.asas.update(simt) # Airboren Separation Assurance self.pilot.APorASAS() # Decide autopilot or ASAS #---------- OpenAP Performance Update ------------------------ if settings.performance_model == 'openap': self.perf.update(simt) #---------- Limit Speeds ------------------------------ self.pilot.applylimits() #---------- Kinematics -------------------------------- self.UpdateAirSpeed(simdt, simt) self.UpdateGroundSpeed(simdt) self.UpdatePosition(simdt) #---------- Legacy and BADA Performance Update ------------------------ if settings.performance_model != 'openap': self.perf.perf(simt) #---------- Simulate Turbulence ----------------------- self.turbulence.Woosh(simdt) # Check whther new traffci state triggers conditional commands self.cond.update() #---------- Aftermath --------------------------------- self.trails.update(simt) return
def getdata(self, userlat, userlon, useralt=0.0): """ Retrieve the north and south component of the windfield, interpolated at a given positions. Parameters ---------- userlat : float Latitude [deg] userlon : float Longitude [deg] userlat : float Altitude [m] Returns ------- north: array_like North component of the wind. east: array_like East component of the wind. """ p = vatmos(useralt)[0] time = bs.sim.utc return self._get_wind(userlat, userlon, p, time)
def update(self, simt, simdt): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update(simt) #---------- Fly the Aircraft -------------------------- self.ap.update(simt) self.asas.update(simt) self.pilot.APorASAS() #---------- NAP Performance Update ------------------------ if settings.performance_model == 'nap': self.perf.update(simt) #---------- Limit Speeds ------------------------------ self.pilot.applylimits() #---------- Kinematics -------------------------------- self.UpdateAirSpeed(simdt, simt) self.UpdateGroundSpeed(simdt) self.UpdatePosition(simdt) #---------- Legacy Performance Update ------------------------ if settings.performance_model in ['bluesky', 'bada']: self.perf.perf(simt) #---------- Simulate Turbulence ----------------------- self.turbulence.Woosh(simdt) #---------- Aftermath --------------------------------- self.trails.update(simt) return
def update(self): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update() #---------- Fly the Aircraft -------------------------- self.ap.update() # Autopilot logic self.update_asas() # Airborne Separation Assurance self.aporasas.update() # Decide to use autopilot or ASAS for commands #---------- Performance Update ------------------------ self.perf.update() #---------- Limit commanded speeds based on performance ------------------------------ self.aporasas.tas, self.aporasas.vs, self.aporasas.alt = \ self.perf.limits(self.aporasas.tas, self.aporasas.vs, self.aporasas.alt, self.ax) #---------- Kinematics -------------------------------- self.update_airspeed() self.update_groundspeed() self.update_pos() #---------- Simulate Turbulence ----------------------- self.turbulence.update() # Check whether new traffic state triggers conditional commands self.cond.update() #---------- Aftermath --------------------------------- self.trails.update()
def update(self): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update() #---------- Fly the Aircraft -------------------------- self.ap.update() # Autopilot logic self.asas.update() # Airborne Separation Assurance self.pilot.APorASAS() # Decide autopilot or ASAS #---------- Performance Update ------------------------ self.perf.update() #---------- Limit Speeds ------------------------------ self.pilot.applylimits() #---------- Kinematics -------------------------------- self.UpdateAirSpeed() self.UpdateGroundSpeed() self.UpdatePosition() #---------- Simulate Turbulence ----------------------- self.turbulence.update() # Check whether new traffic state triggers conditional commands self.cond.update() #---------- Aftermath --------------------------------- self.trails.update() return
def update(self, simt, simdt): # Update only if there is traffic --------------------- if self.ntraf == 0: return #---------- Atmosphere -------------------------------- self.p, self.rho, self.Temp = vatmos(self.alt) #---------- ADSB Update ------------------------------- self.adsb.update(simt) #---------- Fly the Aircraft -------------------------- self.ap.update() # Autopilot logic self.asas.update() # Airboren Separation Assurance self.pilot.APorASAS() # Decide autopilot or ASAS #---------- Performance Update ------------------------ self.perf.update() #---------- Limit Speeds ------------------------------ self.pilot.applylimits() #---------- Kinematics -------------------------------- self.UpdateAirSpeed(simdt, simt) self.UpdateGroundSpeed(simdt) self.UpdatePosition(simdt) #---------- Simulate Turbulence ----------------------- self.turbulence.Woosh(simdt) # Check whther new traffci state triggers conditional commands self.cond.update() #---------- Aftermath --------------------------------- self.trails.update(simt) return
def create(self, n=1, actype="B744", acalt=None, acspd=None, dest=None, aclat=None, aclon=None, achdg=None, acid=None): """ Create multiple random aircraft in a specified area """ area = bs.scr.getviewbounds() if acid is None: idtmp = chr(randint(65, 90)) + chr(randint(65, 90)) + '{:>05}' acid = [idtmp.format(i) for i in range(n)] elif isinstance(acid, str): # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing acid = [acid] else: # TODO: for a list of a/c, check each callsign pass super(Traffic, self).create(n) # Increase number of aircraft self.ntraf += n if aclat is None: aclat = np.random.rand(n) * (area[1] - area[0]) + area[0] elif isinstance(aclat, (float, int)): aclat = np.array(n * [aclat]) if aclon is None: aclon = np.random.rand(n) * (area[3] - area[2]) + area[2] elif isinstance(aclon, (float, int)): aclon = np.array(n * [aclon]) # Limit longitude to [-180.0, 180.0] if n == 1: aclon = aclon - 360 if aclon > 180 else \ aclon + 360 if aclon < -180.0 else aclon else: aclon[aclon > 180.0] -= 360.0 aclon[aclon < -180.0] += 360.0 if achdg is None: achdg = np.random.randint(1, 360, n) elif isinstance(achdg, (float, int)): achdg = np.array(n * [achdg]) if acalt is None: acalt = np.random.randint(2000, 39000, n) * ft elif isinstance(acalt, (float, int)): acalt = np.array(n * [acalt]) if acspd is None: acspd = np.random.randint(250, 450, n) * kts elif isinstance(acspd, (float, int)): acspd = np.array(n * [acspd]) actype = n * [actype] if isinstance(actype, str) else actype dest = n * [dest] if isinstance(dest, str) else dest # SAVEIC: save cre command when filled in # Special provision in case SAVEIC is on: then save individual CRE commands # Names of aircraft (acid) need to be recorded for saved future commands # And positions need to be the same in case of *MCRE" for i in range(n): bs.stack.savecmd(" ".join([ "CRE", acid[i], actype[i], str(aclat[i]), str(aclon[i]), str(int(round(achdg[i]))), str(int(round(acalt[i] / ft))), str(int(round(acspd[i] / kts))) ])) # Aircraft Info self.id[-n:] = acid self.type[-n:] = actype # Positions self.lat[-n:] = aclat self.lon[-n:] = aclon self.alt[-n:] = acalt self.hdg[-n:] = achdg self.trk[-n:] = achdg # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspd, acalt) self.gs[-n:] = self.tas[-n:] hdgrad = np.radians(achdg) self.gsnorth[-n:] = self.tas[-n:] * np.cos(hdgrad) self.gseast[-n:] = self.tas[-n:] * np.sin(hdgrad) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalt) # Wind if self.wind.winddim > 0: applywind = self.alt[-n:] > 50. * ft self.windnorth[-n:], self.windeast[-n:] = self.wind.getdata( self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[-n:] = self.gsnorth[-n:] + self.windnorth * applywind self.gseast[-n:] = self.gseast[-n:] + self.windeast * applywind self.trk[-n:] = np.logical_not(applywind)*achdg +\ applywind*np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) else: self.windnorth[-n:] = 0.0 self.windeast[-n:] = 0.0 # Traffic performance data #(temporarily default values) self.apvsdef[-n:] = 1500. * fpm # default vertical speed of autopilot self.aphi[-n:] = np.radians(25.) # bank angle setting of autopilot self.ax[-n:] = kts # absolute value of longitudinal accelleration self.bank[-n:] = np.radians(25.) # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n * [['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians( aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n)
def cre(self, acid, actype="B744", aclat=52., aclon=4., achdg=None, acalt=0, acspd=0): """ Create one or more aircraft. """ # Determine number of aircraft to create from array length of acid n = 1 if isinstance(acid, str) else len(acid) if isinstance(acid, str): # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing acid = n * [acid] # Adjust the size of all traffic arrays super().create(n) self.ntraf += n if isinstance(actype, str): actype = n * [actype] if isinstance(aclat, (float, int)): aclat = np.array(n * [aclat]) if isinstance(aclon, (float, int)): aclon = np.array(n * [aclon]) # Limit longitude to [-180.0, 180.0] aclon[aclon > 180.0] -= 360.0 aclon[aclon < -180.0] += 360.0 achdg = (refdata.hdg or 0.0) if achdg is None else achdg # Aircraft Info self.id[-n:] = acid self.type[-n:] = actype # Positions self.lat[-n:] = aclat self.lon[-n:] = aclon self.alt[-n:] = acalt self.hdg[-n:] = achdg self.trk[-n:] = achdg # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspd, acalt) self.gs[-n:] = self.tas[-n:] hdgrad = np.radians(achdg) self.gsnorth[-n:] = self.tas[-n:] * np.cos(hdgrad) self.gseast[-n:] = self.tas[-n:] * np.sin(hdgrad) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalt) # Wind if self.wind.winddim > 0: applywind = self.alt[-n:] > 50. * ft self.windnorth[-n:], self.windeast[-n:] = self.wind.getdata( self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[ -n:] = self.gsnorth[-n:] + self.windnorth[-n:] * applywind self.gseast[ -n:] = self.gseast[-n:] + self.windeast[-n:] * applywind self.trk[-n:] = np.logical_not(applywind)*achdg + \ applywind*np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) else: self.windnorth[-n:] = 0.0 self.windeast[-n:] = 0.0 # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n * [['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians( aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n) # Record as individual CRE commands for repeatability #print(self.ntraf-n,self.ntraf) for j in range(self.ntraf - n, self.ntraf): # Reconstruct CRE command line = "CRE " + ",".join([ self.id[j], self.type[j], str(self.lat[j]), str(self.lon[j]), str(round(self.trk[j])), str(round(self.alt[j] / ft)), str(round(self.cas[j] / kts)) ]) # Savecmd(cmd,line): line is saved, cmd is used to prevent recording PAN & ZOOM commands and CRE # So insert a dummy command to record the line savecmd("---", line)
def create(self, n=1, actype="B744", acalt=None, acspd=None, dest=None, aclat=None, aclon=None, achdg=None, acid=None): """ Create multiple random aircraft in a specified area """ area = bs.scr.getviewbounds() if acid is None: idtmp = chr(randint(65, 90)) + chr(randint(65, 90)) + '{:>05}' acid = [idtmp.format(i) for i in range(n)] elif isinstance(acid, str): # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing acid = [acid] if isinstance(actype, str): actype = n * [actype] super(Traffic, self).create(n) # Increase number of aircraft self.ntraf += n if aclat is None: aclat = np.random.rand(n) * (area[1] - area[0]) + area[0] if aclon is None: aclon = np.random.rand(n) * (area[3] - area[2]) + area[2] # Limit longitude to [-180.0, 180.0] if n == 1: aclon = aclon - 360 if aclon > 180 else \ aclon + 360 if aclon < -180.0 else aclon else: aclon[aclon > 180.0] -= 360.0 aclon[aclon < -180.0] += 360.0 if achdg is None: achdg = np.random.randint(1, 360, n) if acalt is None: acalt = np.random.randint(2000, 39000, n) * ft if acspd is None: acspd = np.random.randint(250, 450, n) * kts # Aircraft Info self.id[-n:] = acid self.type[-n:] = actype # Positions self.lat[-n:] = aclat self.lon[-n:] = aclon self.alt[-n:] = acalt self.hdg[-n:] = achdg self.trk[-n:] = achdg #Creation time self.cretime[-n:] = bs.sim.simt #Time in conflict self.timeinconf[-n:] = 0 # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspd, acalt) self.gs[-n:] = self.tas[-n:] hdgrad = np.radians(achdg) self.gsnorth[-n:] = self.tas[-n:] * np.cos(hdgrad) self.gseast[-n:] = self.tas[-n:] * np.sin(hdgrad) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalt) # Wind if self.wind.winddim > 0: vnwnd, vewnd = self.wind.getdata(self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[-n:] = self.gsnorth[-n:] + vnwnd self.gseast[-n:] = self.gseast[-n:] + vewnd self.trk[-n:] = np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) # Traffic performance data #(temporarily default values) self.apvsdef[-n:] = 1500. * fpm # default vertical speed of autopilot self.aphi[-n:] = np.radians(25.) # bank angle setting of autopilot self.ax[-n:] = kts # absolute value of longitudinal accelleration self.bank[-n:] = np.radians(25.) # Crossover altitude self.abco[-n:] = 0 # not necessary to overwrite 0 to 0, but leave for clarity self.belco[-n:] = 1 # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n*[['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians(aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n)
def create(self, n=1, actype="B744", acalt=None, acspd=None, dest=None, aclat=None, aclon=None, achdg=None, acid=None): """ Create multiple random aircraft in a specified area """ area = bs.scr.getviewbounds() if acid is None: idtmp = chr(randint(65, 90)) + chr(randint(65, 90)) + '{:>05}' acid = [idtmp.format(i) for i in range(n)] elif isinstance(acid, str): # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing acid = [acid] else: # TODO: for a list of a/c, check each callsign pass super(Traffic, self).create(n) # Increase number of aircraft self.ntraf += n if aclat is None: aclat = np.random.rand(n) * (area[1] - area[0]) + area[0] elif isinstance(aclat, (float, int)): aclat = np.array(n * [aclat]) if aclon is None: aclon = np.random.rand(n) * (area[3] - area[2]) + area[2] elif isinstance(aclon, (float, int)): aclon = np.array(n * [aclon]) # Limit longitude to [-180.0, 180.0] if n == 1: aclon = aclon - 360 if aclon > 180 else \ aclon + 360 if aclon < -180.0 else aclon else: aclon[aclon > 180.0] -= 360.0 aclon[aclon < -180.0] += 360.0 if achdg is None: achdg = np.random.randint(1, 360, n) elif isinstance(achdg, (float, int)): achdg = np.array(n * [achdg]) if acalt is None: acalt = np.random.randint(2000, 39000, n) * ft elif isinstance(acalt, (float, int)): acalt = np.array(n * [acalt]) if acspd is None: acspd = np.random.randint(250, 450, n) * kts elif isinstance(acspd,(float, int)): acspd = np.array(n * [acspd]) actype = n * [actype] if isinstance(actype, str) else actype dest = n * [dest] if isinstance(dest, str) else dest # SAVEIC: save cre command when filled in # Special provision in case SAVEIC is on: then save individual CRE commands # Names of aircraft (acid) need to be recorded for saved future commands # And positions need to be the same in case of *MCRE" for i in range(n): bs.stack.savecmd(" ".join([ "CRE", acid[i], actype[i], str(aclat[i]), str(aclon[i]), str(int(round(achdg[i]))), str(int(round(acalt[i]/ft))), str(int(round(acspd[i]/kts)))])) # Aircraft Info self.id[-n:] = acid self.type[-n:] = actype # Positions self.lat[-n:] = aclat self.lon[-n:] = aclon self.alt[-n:] = acalt self.hdg[-n:] = achdg self.trk[-n:] = achdg # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspd, acalt) self.gs[-n:] = self.tas[-n:] hdgrad = np.radians(achdg) self.gsnorth[-n:] = self.tas[-n:] * np.cos(hdgrad) self.gseast[-n:] = self.tas[-n:] * np.sin(hdgrad) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalt) # Wind if self.wind.winddim > 0: applywind = self.alt[-n:]> 50.*ft vnwnd, vewnd = self.wind.getdata(self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[-n:] = self.gsnorth[-n:] + vnwnd*applywind self.gseast[-n:] = self.gseast[-n:] + vewnd*applywind self.trk[-n:] = np.logical_not(applywind)*achdg +\ applywind*np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) # Traffic performance data #(temporarily default values) self.apvsdef[-n:] = 1500. * fpm # default vertical speed of autopilot self.aphi[-n:] = np.radians(25.) # bank angle setting of autopilot self.ax[-n:] = kts # absolute value of longitudinal accelleration self.bank[-n:] = np.radians(25.) # Crossover altitude self.abco[-n:] = 0 # not necessary to overwrite 0 to 0, but leave for clarity self.belco[-n:] = 1 # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n*[['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians(aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n)
def create(self, acid=None, actype="B744", aclat=None, aclon=None, achdg=None, acalt=None, casmach=None): """Create an aircraft""" # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing # Catch missing acid, replace by a default if acid is None or acid == "*": acid = "KL204" flno = 204 while self.id.count(acid) > 0: flno = flno + 1 acid = "KL" + str(flno) # Check for (other) missing arguments if actype is None or aclat is None or aclon is None or achdg is None \ or acalt is None or casmach is None: return False, "CRE: Missing one or more arguments:"\ "acid,actype,aclat,aclon,achdg,acalt,acspd" super(Traffic, self).create() # Increase number of aircraft self.ntraf = self.ntraf + 1 # Aircraft Info self.id[-1] = acid.upper() self.type[-1] = actype # Positions self.lat[-1] = aclat self.lon[-1] = aclon self.alt[-1] = acalt self.hdg[-1] = achdg self.trk[-1] = achdg # Velocities self.tas[-1], self.cas[-1], self.M[-1] = casormach(casmach, acalt) self.gs[-1] = self.tas[-1] self.gsnorth[-1] = self.tas[-1] * cos(radians(self.hdg[-1])) self.gseast[-1] = self.tas[-1] * sin(radians(self.hdg[-1])) # Atmosphere self.p[-1], self.rho[-1], self.Temp[-1] = vatmos(acalt) # Wind if self.wind.winddim > 0: vnwnd, vewnd = self.wind.getdata(self.lat[-1], self.lon[-1], self.alt[-1]) self.gsnorth[-1] = self.gsnorth[-1] + vnwnd self.gseast[-1] = self.gseast[-1] + vewnd self.trk[-1] = np.degrees(np.arctan2(self.gseast[-1], self.gsnorth[-1])) self.gs[-1] = np.sqrt(self.gsnorth[-1]**2 + self.gseast[-1]**2) # Traffic performance data #(temporarily default values) self.apvsdef[-1] = 1500. * fpm # default vertical speed of autopilot self.aphi[-1] = radians(25.) # bank angle setting of autopilot self.ax[-1] = 1.0*kts # absolute value of longitudinal accelleration self.bank[-1] = radians(25.) # Crossover altitude self.abco[-1] = 0 # not necessary to overwrite 0 to 0, but leave for clarity self.belco[-1] = 1 # Traffic autopilot settings self.selspd[-1] = self.cas[-1] self.aptas[-1] = self.tas[-1] self.selalt[-1] = self.alt[-1] # Display information on label self.label[-1] = ['', '', '', 0] # Miscallaneous self.coslat[-1] = cos(radians(aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-1] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children() return True
def mcreate(self, count, actype=None, alt=None, spd=None, dest=None): """ Create multiple random aircraft in a specified area """ area = bs.scr.getviewlatlon() idbase = chr(randint(65, 90)) + chr(randint(65, 90)) if actype is None: actype = 'B744' n = count super(Traffic, self).create(n) # Increase number of aircraft self.ntraf = self.ntraf + count acids = [] aclats = [] aclons = [] achdgs = [] acalts = [] acspds = [] for i in range(count): acids.append((idbase + '%05d' % i).upper()) aclats.append(random() * (area[1] - area[0]) + area[0]) aclons.append(random() * (area[3] - area[2]) + area[2]) achdgs.append(float(randint(1, 360))) acalts.append((randint(2000, 39000) * ft) if alt is None else alt) acspds.append((randint(250, 450) * kts) if spd is None else spd) # Aircraft Info self.id[-n:] = acids self.type[-n:] = [actype] * n # Positions self.lat[-n:] = aclats self.lon[-n:] = aclons self.alt[-n:] = acalts self.hdg[-n:] = achdgs self.trk[-n:] = achdgs # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspds, acalts) self.gs[-n:] = self.tas[-n:] self.gsnorth[-n:] = self.tas[-n:] * np.cos(np.radians(self.hdg[-n:])) self.gseast[-n:] = self.tas[-n:] * np.sin(np.radians(self.hdg[-n:])) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalts) # Wind if self.wind.winddim > 0: vnwnd, vewnd = self.wind.getdata(self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[-n:] = self.gsnorth[-n:] + vnwnd self.gseast[-n:] = self.gseast[-n:] + vewnd self.trk[-n:] = np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) # Traffic performance data #(temporarily default values) self.apvsdef[-n:] = 1500. * fpm # default vertical speed of autopilot self.aphi[-n:] = np.radians(25.) # bank angle setting of autopilot self.ax[-n:] = kts # absolute value of longitudinal accelleration self.bank[-n:] = np.radians(25.) # Crossover altitude self.abco[-n:] = 0 # not necessary to overwrite 0 to 0, but leave for clarity self.belco[-n:] = 1 # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n*[['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians(aclats)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n)
def cre(self, acid, actype, aclat, aclon, achdg=None, acalt=0, acspd=0): """ Create one or more aircraft. """ # Determine number of aircraft to create from array length of acid n = 1 if isinstance(acid, str) else len(acid) if isinstance(acid, str): # Check if not already exist if self.id.count(acid.upper()) > 0: return False, acid + " already exists." # already exists do nothing acid = n * [acid] # Adjust the size of all traffic arrays super().create(n) self.ntraf += n if isinstance(aclat, (float, int)): aclat = np.array(n * [aclat]) if isinstance(aclon, (float, int)): aclon = np.array(n * [aclon]) # Limit longitude to [-180.0, 180.0] aclon[aclon > 180.0] -= 360.0 aclon[aclon < -180.0] += 360.0 achdg = refdata.hdg if achdg is None else achdg # Aircraft Info self.id[-n:] = acid self.type[-n:] = actype # Positions self.lat[-n:] = aclat self.lon[-n:] = aclon self.alt[-n:] = acalt self.hdg[-n:] = achdg self.trk[-n:] = achdg # Velocities self.tas[-n:], self.cas[-n:], self.M[-n:] = vcasormach(acspd, acalt) self.gs[-n:] = self.tas[-n:] hdgrad = np.radians(achdg) self.gsnorth[-n:] = self.tas[-n:] * np.cos(hdgrad) self.gseast[-n:] = self.tas[-n:] * np.sin(hdgrad) # Atmosphere self.p[-n:], self.rho[-n:], self.Temp[-n:] = vatmos(acalt) # Wind if self.wind.winddim > 0: applywind = self.alt[-n:]> 50.*ft self.windnorth[-n:], self.windeast[-n:] = self.wind.getdata(self.lat[-n:], self.lon[-n:], self.alt[-n:]) self.gsnorth[-n:] = self.gsnorth[-n:] + self.windnorth[-n:]*applywind self.gseast[-n:] = self.gseast[-n:] + self.windeast[-n:]*applywind self.trk[-n:] = np.logical_not(applywind)*achdg + \ applywind*np.degrees(np.arctan2(self.gseast[-n:], self.gsnorth[-n:])) self.gs[-n:] = np.sqrt(self.gsnorth[-n:]**2 + self.gseast[-n:]**2) else: self.windnorth[-n:] = 0.0 self.windeast[-n:] = 0.0 # Traffic performance data #(temporarily default values) self.apvsdef[-n:] = 1500. * fpm # default vertical speed of autopilot self.aphi[-n:] = 0. # bank angle output of autopilot (optional) self.ax[-n:] = kts # absolute value of longitudinal accelleration self.bank[-n:] = np.radians(25.) # Traffic autopilot settings self.selspd[-n:] = self.cas[-n:] self.aptas[-n:] = self.tas[-n:] self.selalt[-n:] = self.alt[-n:] # Display information on label self.label[-n:] = n*[['', '', '', 0]] # Miscallaneous self.coslat[-n:] = np.cos(np.radians(aclat)) # Cosine of latitude for flat-earth aproximations self.eps[-n:] = 0.01 # Finally call create for child TrafficArrays. This only needs to be done # manually in Traffic. self.create_children(n)
def getdata(self, userlat, userlon, useralt=0.0): p = vatmos(useralt)[0] time = bs.sim.utc return self._get_wind(userlat, userlon, p, time)