コード例 #1
0
def drawdeprwy(apt,rwy,rwylat,rwylon,rwyhdg):
    # Draw approach ILS arrow
    Ldep  =  5. # [nm] length of approach path drawn
    phi   =  3. # [deg] angle of half the arrow

    # Calculate arrow (T = Threshold runway):
    #      L   (left)
    #     /
    #   D ------------------------------------- T    (approach)
    #     \
    #      R    (right)
    #

    deplat,deplon     = kwikpos(rwylat,rwylon,rwyhdg%360.,Ldep*1.1)
    rightlat,rightlon = kwikpos(rwylat,rwylon,(rwyhdg+phi)%360,Ldep)
    leftlat,leftlon   = kwikpos(rwylat,rwylon,(rwyhdg-phi)%360,Ldep)

    # Make arguments for POLYLINE command
    T = str(rwylat)+","+str(rwylon)
    D = str(deplat)+","+str(deplon)
    L = str(leftlat)+","+str(leftlon)
    R = str(rightlat)+","+str(rightlon)

    stack.stack("POLYLINE " + apt + rwy + "-D," + ",".join([R,D,L,D,T]))
   

    return apt + rwy + "-D"
コード例 #2
0
def drawapprwy(apt,rwy,rwylat,rwylon,rwyhdg):
    # Draw approach ILS arrow
    Lapp  =  7. # [nm] length of approach path drawn
    phi   =  5. # [deg] angle of half the arrow

    # Calculate arrow (T = Threshold runway):
    #                               /------------- L   (left)
    #                 /-----------/              /
    #   T -------------------------------------- A    (approach)
    #                 \-----------\              \
    #                              \--------------R    (right)
    #

    applat,applon     = kwikpos(rwylat,rwylon,(rwyhdg+180)%360.,Lapp)
    rightlat,rightlon = kwikpos(rwylat,rwylon,(rwyhdg+180-phi)%360,Lapp*1.1)
    leftlat,leftlon   = kwikpos(rwylat,rwylon,(rwyhdg+180+phi)%360,Lapp*1.1)

    # Make arguments for POLYLINE command
    T = str(rwylat)+","+str(rwylon)
    A = str(applat)+","+str(applon)
    L = str(leftlat)+","+str(leftlon)
    R = str(rightlat)+","+str(rightlon)

    stack.stack("POLYLINE "+apt+rwy+"-A,"+",".join([T,A,L,T,R,A]))

    return apt+rwy+"-A"
コード例 #3
0
ファイル: traffic.py プロジェクト: wanghuimu/bluesky
    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
コード例 #4
0
def getseg(txt):

    # Get a random position on the segment with the heading inward
    # SEGMnnn is segment in direction nnn degrees from center circle

    brg = float(txt[4:])

    lat,lon = kwikpos(ctrlat,ctrlon,brg,radius)

    return lat,lon,brg
コード例 #5
0
ファイル: trafgenclasses.py プロジェクト: thobson88/bluesky
def getseg(txt):

    # Get a random position on the segment with the heading inward
    # SEGMnnn is segment in direction nnn degrees from center circle

    brg = float(txt[4:])

    lat,lon = kwikpos(ctrlat,ctrlon,brg,radius)

    return lat,lon,brg
コード例 #6
0
    def detect_all(cls, traf, dtlookahead=None):
        #dtlookahead: lookahead time in s
        if dtlookahead is None:
            dtlookahead = settings.geofence_dtlookahead

        # Linearly extrapolate current state to prefict future position
        pred_lat, pred_lon = geo.kwikpos(traf.lat, traf.lon, traf.hdg,
                                         (dtlookahead * traf.gs) / aero.nm)
        pred_alt = traf.alt + dtlookahead * traf.vs

        # Check intersections with geofences for each aircraft separately
        hits_per_ac = []
        for lat1, lon1, alt1, lat2, lon2, alt2 in zip(traf.lat, traf.lon,
                                                      traf.alt, pred_lat,
                                                      pred_lon, pred_alt):
            hits = []
            # First a course detection based on geofence bounding boxes
            potential_hits = areafilter.get_intersecting(
                min(lat1, lat2), min(lon1, lon2), max(lat1, lat2),
                max(lon1, lon2))

            # Create linearly extrapolated 2D flight path
            flightpath = Path([(lat1, lon1), (lat2, lon2)])

            # Loop through all detected areas from the course detection
            for geofence in potential_hits:
                # Check if the area is a geofence
                if type(geofence) is Geofence:
                    # Check if the 2D horizontal flight path intersects the geofence border
                    if flightpath.intersects_path(geofence.border):
                        # Check if the vertical flight path intersects simultaneously
                        if geofence.bottom <= alt1 <= geofence.top and geofence.bottom <= alt2 <= geofence.top:
                            hits.append(
                                geofence
                            )  # always a hit: entire vertical flight path lies inside
                        else:  # linearly extrapolate flightpath and check points separately
                            lats = np.linspace(
                                lat1, lat2, 100)  # for now use 100 iterations
                            lons = np.linspace(lon1, lon2, 100)
                            alts = np.linspace(alt1, alt2, 100)
                            hit_ver = geofence.checkInside(lats, lons, alts)
                            if np.any(hit_ver):
                                hits.append(geofence)

            # Finally append all geofence hits to the overall list
            hits_per_ac.append(hits)

        return hits_per_ac
コード例 #7
0
    def detect_all(cls, traf, dtlookahead=None):
        if dtlookahead is None:
            dtlookahead = settings.geofence_dtlookahead
        
        # Linearly extrapolate current state to prefict future position
        pred_lat, pred_lon = geo.kwikpos(traf.lat, traf.lon, traf.hdg, traf.gs / aero.nm)
        hits_per_ac = []
        for idx, line in zip(traf.lat, traf.lon, pred_lat, pred_lon):
            hits = []
            # First a course detection based on geofence bounding boxes
            potential_hits = areafilter.get_intersecting(*line)
            # Then a fine-grained intersection detection
            for geofence in potential_hits:
                if geofence.intersects(line):
                    hits.append(geofence)
            hits_per_ac.append(hits)

        return hits_per_ac
コード例 #8
0
    def getLastPoint(self, last_node):
        # add last point to delete aircraft from map as fast as possible
        destination_side = cb.getCurrentBorder(last_node, cb.GRAPH)
        # 0 - north, 1-bottom, 2-east, 3-west
        heading_finalpoint = 0  # up
        alt_final = 2
        if destination_side == 1:  # bottom
            heading_finalpoint = 180
            alt_final = 6
        elif destination_side == 2:  # east
            heading_finalpoint = 90
            alt_final = 4
        elif destination_side == 3:  # left
            heading_finalpoint = 270
            alt_final = 8

        lat0, lon0 = cb.getLatLonnode(cb.GRAPH, last_node)
        lat_final, lon_final = geo.kwikpos(lat0, lon0, heading_finalpoint,
                                           1000 / nm)
        return lat_final, lon_final, alt_final
コード例 #9
0
def getNewNode(previous_node, step, edges):
    lat_node, lon_node = cb.getLatLonnode(cb.GRAPH, previous_node)
    possible_directions = [86.8, 176.8, 266.8, 356.8]
    distances = [94.4, 207.6, 94.4, 207.6]  # meters
    lat0, lon0 = geo.kwikpos(lat_node, lon_node, possible_directions[step],
                             distances[step] / nm)

    # check if we ended up in an existing node
    lat_nodes, lon_nodes, node_ids = cb.getLatLonAllNodes(cb.GRAPH)
    closest_node, dummy = cb.getclosestnode([lat0], [lon0], lat_nodes,
                                            lon_nodes, node_ids)
    lat_closest_node, lon_closest_node = cb.getLatLonnode(
        cb.GRAPH, closest_node)
    qdr, dist = geo.kwikqdrdist(lat0, lon0, lat_closest_node, lon_closest_node)
    if closest_node != previous_node and dist * nm < 15:  # lets use this existent node
        lat0, lon0 = lat_closest_node, lon_closest_node
        edges[step] = (closest_node, qdr, dist * nm)
        cb.EDGES_PER_NODE[previous_node] = edges
    # create a new node
    else:
        existent_nodes = list(cb.NODES.keys())
        # find the smallest positive number not in list
        new_nodes_key = next(
            filterfalse(set(existent_nodes).__contains__, count(1)))
        cb.addtoNodes(lat0, lon0, new_nodes_key, True)
        if edges[step] is None:
            edges[step] = (new_nodes_key, possible_directions[step],
                           distances[step])
            cb.EDGES_PER_NODE[previous_node] = edges
        # create edges for the new node, create only the ones that we are going to need
        new_nodes_edges = [None, None, None, None]
        opposite_step = getOppositeStep(step)
        new_nodes_edges[opposite_step] = (previous_node,
                                          possible_directions[opposite_step],
                                          distances[step])
        cb.EDGES_PER_NODE[new_nodes_key] = new_nodes_edges
        closest_node = new_nodes_key

    return lat0, lon0, edges, closest_node
コード例 #10
0
ファイル: trafgenclasses.py プロジェクト: thobson88/bluesky
    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")
コード例 #11
0
    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
コード例 #12
0
ファイル: screen.py プロジェクト: rjdverbeek/bluesky
    def update(self):
        """Draw a new frame"""
        # First check for keys & mouse
        self.keyb.update()
        # Navdisp mode: get center:
        if self.swnavdisp:
            i = bs.traf.id2idx(self.ndacid)
            if i >= 0:
                self.ndlat = bs.traf.lat[i]
                self.ndlon = bs.traf.lon[i]
                self.ndcrs = bs.traf.hdg[i]
            else:
                self.swnavdisp = False
        else:
            self.ndcrs = 0.0

        # Radar window
        # --------------Background--------------

        if self.redrawradbg or self.swnavdisp:
            if self.swnavdisp or not self.swsat:
                self.radbmp.fill(darkgrey)

            else:
                #--------------Satellite image--------------
                navsel = (self.lat0, self.lat1, \
                          self.lon0, self.lon1)
                if not self.satsel == navsel:
                    # Map cutting and scaling: normal case
                    if self.lon1 > self.lon0:
                        x0 = max(0, self.lon0 * self.mapax + self.mapbx)
                        x1 = min(self.mapbmp.get_width() - 1, \
                                 self.lon1 * self.mapax + self.mapbx)

                        y1 = min(self.mapbmp.get_height() - 1, \
                                 self.lat0 * self.mapay + self.mapby)
                        y0 = max(0, self.lat1 * self.mapay + self.mapby)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (self.width, self.height))

                        self.radbmp.blit(self.submap, (0, 0))

                    else:
                        # Wrap around case: clip two segments
                        w0 = int(self.width * (180. - self.lon0) / \
                                 (180.0 - self.lon0 + self.lon1 + 180.))
                        w1 = int(self.width - w0)

                        # Left part
                        x0 = max(0, self.lon0 * self.mapax + self.mapbx)
                        x1 = self.mapbmp.get_width() - 1

                        y1 = min(self.mapbmp.get_height() - 1, \
                                 self.lat0 * self.mapay + self.mapby)
                        y0 = max(0, self.lat1 * self.mapay + self.mapby)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (w0, self.height))
                        self.radbmp.blit(self.submap, (0, 0))

                        # Right half
                        x0 = 0
                        x1 = min(self.mapbmp.get_width() - 1, \
                                 self.lon1 * self.mapax + self.mapbx)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (w1, self.height))
                        self.radbmp.blit(self.submap, (w0, 0))
                        self.submap = self.radbmp.copy()

                    self.satsel = navsel

                else:
                    # Map blit only
                    self.radbmp.blit(self.submap, (0, 0))

            if self.swgrid and not self.swnavdisp:
                # ------Draw lat/lon grid------
                ngrad = int(self.lon1 - self.lon0)

                if ngrad >= 10:
                    step = 10
                    i0 = step * int(self.lon0 / step)
                    j0 = step * int(self.lat0 / step)
                else:
                    step = 1
                    i0 = int(self.lon0)
                    j0 = int(self.lon0)

                for i in range(i0, int(self.lon1 + 1.), step):
                    x, y = self.ll2xy(self.ctrlat, i)
                    pg.draw.line(self.radbmp, lightgreygreen, \
                                 (x, 0), (x, self.height))

                for j in range(j0, int(self.lat1 + 1.), step):
                    x, y = self.ll2xy(j, self.ctrlon)
                    pg.draw.line(self.radbmp, lightgreygreen, \
                                 (0, y), (self.width, y))

            #------ Draw coastlines ------
            if self.swgeo:
                # cx,cy = -1,-1
                geosel = (self.lat0, self.lon0, self.lat1, self.lon1)
                if self.geosel != geosel:
                    self.geosel = geosel

                    self.cstsel = np.where(
                        self.onradar(self.coastlat0, self.coastlon0) + \
                        self.onradar(self.coastlat1, self.coastlon1))

                    # print len(self.cstsel[0])," coastlines"
                    self.cx0, self.cy0 = self.ll2xy(self.coastlat0,
                                                    self.coastlon0)
                    self.cx1, self.cy1 = self.ll2xy(self.coastlat1,
                                                    self.coastlon1)

                for i in list(self.cstsel[0]):
                    pg.draw.line(self.radbmp, grey, (self.cx0[i], self.cy0[i]), \
                                 (self.cx1[i], self.cy1[i]))

            #------ Draw FIRs ------
            if self.swfir:
                self.firx0, self.firy0 = self.ll2xy(bs.navdb.firlat0, \
                                                    bs.navdb.firlon0)

                self.firx1, self.firy1 = self.ll2xy(bs.navdb.firlat1, \
                                                    bs.navdb.firlon1)

                for i in range(len(self.firx0)):
                    pg.draw.line(self.radbmp, lightcyan,
                                 (self.firx0[i], self.firy0[i]),
                                 (self.firx1[i], self.firy1[i]))

            # -----------------Waypoint & airport symbols-----------------
            # Check whether we need to reselect waypoint set to be drawn

            navsel = (self.lat0, self.lat1, \
                      self.lon0, self.lon1)
            if self.navsel != navsel:
                self.navsel = navsel

                # Make list of indices of waypoints & airports on screen

                self.wpinside = list(np.where(self.onradar(bs.navdb.wplat, \
                                                           bs.navdb.wplon))[0])

                self.wptsel = []
                for i in self.wpinside:
                    if self.wpsw == 3 or \
                            (self.wpsw == 1 and len(bs.navdb.wpid[i]) == 3) or \
                            (self.wpsw == 2 and bs.navdb.wpid[i].isalpha()):
                        self.wptsel.append(i)
                self.wptx, self.wpty = self.ll2xy(bs.navdb.wplat,
                                                  bs.navdb.wplon)

                self.apinside = list(np.where(self.onradar(bs.navdb.aptlat, \
                                                           bs.navdb.aptlon))[0])

                self.aptsel = []
                for i in self.apinside:
                    if self.apsw == 2 or (self.apsw == 1 and \
                                                      bs.navdb.aptmaxrwy[i] > 1000.):
                        self.aptsel.append(i)
                self.aptx, self.apty = self.ll2xy(bs.navdb.aptlat,
                                                  bs.navdb.aptlon)

            #------- Draw waypoints -------
            if self.wpsw > 0:
                # print len(self.wptsel)," waypoints"
                if len(self.wptsel) < self.maxnrwp:
                    wptrect = self.wptsymbol.get_rect()
                    for i in self.wptsel:
                        # wptrect.center = self.ll2xy(bs.navdb.wplat[i],  \
                        #     bs.navdb.wplon[i])
                        wptrect.center = self.wptx[i], self.wpty[i]
                        self.radbmp.blit(self.wptsymbol, wptrect)

                        # If waypoint label bitmap does not yet exist, make it
                        if not self.wpswbmp[i]:
                            self.wplabel[i] = pg.Surface((80, 30), 0, self.win)
                            self.fontnav.printat(self.wplabel[i], 0, 0, \
                                                 bs.navdb.wpid[i])
                            self.wpswbmp[i] = True

                        # In any case, blit it
                        xtxt = wptrect.right + 2
                        ytxt = wptrect.top
                        self.radbmp.blit(self.wplabel[i], (xtxt, ytxt), \
                                         None, pg.BLEND_ADD)

                        if not self.wpswbmp[i]:
                            xtxt = wptrect.right + 2
                            ytxt = wptrect.top

                            # self.fontnav.printat(self.radbmp,xtxt,ytxt, \
                            #     bs.navdb.wpid[i])

            #------- Draw airports -------
            if self.apsw > 0:
                # if len(self.aptsel)<800:
                aptrect = self.aptsymbol.get_rect()

                # print len(self.aptsel)," airports"

                for i in self.aptsel:
                    # aptrect.center = self.ll2xy(bs.navdb.aptlat[i],  \
                    #                            bs.navdb.aptlon[i])
                    aptrect.center = self.aptx[i], self.apty[i]
                    self.radbmp.blit(self.aptsymbol, aptrect)

                    # If airport label bitmap does not yet exist, make it
                    if not self.apswbmp[i]:
                        self.aplabel[i] = pg.Surface((50, 30), 0, self.win)
                        self.fontnav.printat(self.aplabel[i], 0, 0, \
                                             bs.navdb.aptid[i])
                        self.apswbmp[i] = True

                    # In either case, blit it
                    xtxt = aptrect.right + 2
                    ytxt = aptrect.top
                    self.radbmp.blit(self.aplabel[i], (xtxt, ytxt), \
                                     None, pg.BLEND_ADD)

                    # self.fontnav.printat(self.radbmp,xtxt,ytxt, \
                    #     bs.navdb.aptid[i])

            #---------- Draw background trails ----------
            if bs.traf.trails.active:
                bs.traf.trails.buffer()  # move all new trails to background

                trlsel = list(np.where(
                    self.onradar(bs.traf.trails.bglat0, bs.traf.trails.bglon0) + \
                    self.onradar(bs.traf.trails.bglat1, bs.traf.trails.bglon1))[0])

                x0, y0 = self.ll2xy(bs.traf.trails.bglat0,
                                    bs.traf.trails.bglon0)
                x1, y1 = self.ll2xy(bs.traf.trails.bglat1,
                                    bs.traf.trails.bglon1)

                for i in trlsel:
                    pg.draw.aaline(self.radbmp, bs.traf.trails.bgcol[i], \
                                   (x0[i], y0[i]), (x1[i], y1[i]))

            #---------- Draw ADSB Coverage Area
            if self.swAdsbCoverage:
                # These points are based on the positions of the antennas with range = 200km
                adsbCoverageLat = [
                    53.7863, 53.5362, 52.8604, 51.9538, 51.2285, 50.8249,
                    50.7382, 50.9701, 51.6096, 52.498, 53.4047, 53.6402
                ]
                adsbCoverageLon = [
                    4.3757, 5.8869, 6.9529, 7.2913, 6.9312, 6.251, 5.7218,
                    4.2955, 3.2162, 2.7701, 3.1117, 3.4891
                ]

                for i in range(0, len(adsbCoverageLat)):
                    if i == len(adsbCoverageLat) - 1:
                        x0, y0 = self.ll2xy(adsbCoverageLat[i],
                                            adsbCoverageLon[i])
                        x1, y1 = self.ll2xy(adsbCoverageLat[0],
                                            adsbCoverageLon[0])

                    else:
                        x0, y0 = self.ll2xy(adsbCoverageLat[i],
                                            adsbCoverageLon[i])
                        x1, y1 = self.ll2xy(adsbCoverageLat[i + 1],
                                            adsbCoverageLon[i + 1])

                    pg.draw.line(self.radbmp, red, (x0, y0), (x1, y1))

            # User defined objects
            for i in range(len(self.objtype)):

                # Draw LINE or POLYGON with objdata = [lat0,lon,lat1,lon1,lat2,lon2,..]
                if self.objtype[i] == 'LINE' or self.objtype[i] == "POLY":
                    npoints = len(self.objdata[i]) / 2
                    print(npoints)
                    x0, y0 = self.ll2xy(self.objdata[i][0], self.objdata[i][1])
                    for j in range(1, npoints):
                        x1, y1 = self.ll2xy(self.objdata[i][j * 2],
                                            self.objdata[i][j * 2 + 1])
                        pg.draw.line(self.radbmp, self.objcolor[i], (x0, y0),
                                     (x1, y1))
                        x0, y0 = x1, y1

                    if self.objtype[i] == "POLY":
                        x1, y1 = self.ll2xy(self.objdata[i][0],
                                            self.objdata[i][1])
                        pg.draw.line(self.radbmp, self.objcolor[i], (x0, y0),
                                     (x1, y1))

                # Draw bounding box of objdata = [lat0,lon0,lat1,lon1]
                elif self.objtype[i] == 'BOX':
                    lat0 = min(self.objdata[i][0], self.objdata[i][2])
                    lon0 = min(self.objdata[i][1], self.objdata[i][3])
                    lat1 = max(self.objdata[i][0], self.objdata[i][2])
                    lon1 = max(self.objdata[i][1], self.objdata[i][3])

                    x0, y0 = self.ll2xy(lat1, lon0)
                    x1, y1 = self.ll2xy(lat0, lon1)
                    pg.draw.rect(self.radbmp, self.objcolor[i],
                                 pg.Rect(x0, y0, x1 - x0, y1 - y0), 1)

                # Draw circle with objdata = [latcenter,loncenter,radiusnm]
                elif self.objtype[i] == 'CIRCLE':
                    pass
                    xm, ym = self.ll2xy(self.objdata[i][0], self.objdata[i][1])
                    xtop, ytop = self.ll2xy(
                        self.objdata[i][0] + self.objdata[i][2] / 60.,
                        self.objdata[i][1])
                    radius = int(round(abs(ytop - ym)))
                    pg.draw.circle(self.radbmp, self.objcolor[i],
                                   (int(xm), int(ym)), radius, 1)

            # Reset background drawing switch
            self.redrawradbg = False

        ##############################################################################
        #                          END OF BACKGROUND DRAWING                         #
        ##############################################################################

        # Blit background
        self.win.blit(self.radbmp, (0, 0))

        # Decide to redraw radar picture of a/c
        syst = pg.time.get_ticks() * 0.001
        redrawrad = self.redrawradbg or abs(syst - self.radt0) >= self.radardt

        if redrawrad:
            self.radt0 = syst  # Update lats drawing time of radar

            # Select which aircraft are within screen area
            trafsel = np.where((bs.traf.lat > self.lat0) * (bs.traf.lat < self.lat1) * \
                               (bs.traf.lon > self.lon0) * (bs.traf.lon < self.lon1))[0]

            # ------------------- Draw aircraft -------------------
            # Convert lat,lon to x,y

            trafx, trafy = self.ll2xy(bs.traf.lat, bs.traf.lon)
            trafy -= bs.traf.alt * self.isoalt

            if bs.traf.trails.active:
                ltx, lty = self.ll2xy(bs.traf.trails.lastlat,
                                      bs.traf.trails.lastlon)

            # Find pixel size of horizontal separation on screen
            pixelrad = self.dtopix_eq(bs.traf.asas.R / 2)

            # Loop through all traffic indices which we found on screen
            for i in trafsel:

                # Get index of ac symbol, based on heading and its rect object
                isymb = int(round((bs.traf.hdg[i] - self.ndcrs) / 6.)) % 60
                pos = self.acsymbol[isymb].get_rect()

                # Draw aircraft symbol
                pos.centerx = trafx[i]
                pos.centery = trafy[i]
                dy = self.fontrad.linedy * 7 / 6

                # Draw aircraft altitude line
                if self.isoalt > 1e-7:
                    pg.draw.line(
                        self.win, white, (int(trafx[i]), int(trafy[i])),
                        (int(trafx[i]),
                         int(trafy[i] + bs.traf.alt[i] * self.isoalt)))

                # Normal symbol if no conflict else amber
                toosmall = self.lat1 - self.lat0 > 6  #don't draw circles if zoomed out too much

                if not bs.traf.asas.inconf[i]:
                    self.win.blit(self.acsymbol[isymb], pos)
                    if self.swsep and not toosmall:
                        pg.draw.circle(self.win, green,
                                       (int(trafx[i]), int(trafy[i])),
                                       pixelrad, 1)
                else:
                    self.win.blit(self.ambacsymbol[isymb], pos)
                    if self.swsep and not toosmall:
                        pg.draw.circle(self.win, amber,
                                       (int(trafx[i]), int(trafy[i])),
                                       pixelrad, 1)

                # Draw last trail part
                if bs.traf.trails.active:
                    pg.draw.line(self.win, tuple(bs.traf.trails.accolor[i]),
                                 (ltx[i], lty[i]), (trafx[i], trafy[i]))

                # Label text
                label = []
                if self.swlabel > 0:
                    label.append(bs.traf.id[i])  # Line 1 of label: id
                else:
                    label.append(" ")
                if self.swlabel > 1:
                    if bs.traf.alt[i] > bs.traf.translvl:
                        label.append(
                            "FL" + str(int(round(
                                bs.traf.alt[i] /
                                (100. * ft)))))  # Line 2 of label: altitude
                    else:
                        label.append(str(int(
                            round(bs.traf.alt[i] /
                                  ft))))  # Line 2 of label: altitude
                else:
                    label.append(" ")
                if self.swlabel > 2:
                    cas = bs.traf.cas[i] / kts
                    label.append(str(int(
                        round(cas))))  # line 3 of label: speed
                else:
                    label.append(" ")

                # Check for changes in traffic label text
                if  not (type(bs.traf.label[i])==list) or \
                      not (type(bs.traf.label[i][3])==str) or \
                        not (label[:3] == bs.traf.label[i][:3]):

                    bs.traf.label[i] = []
                    labelbmp = pg.Surface((100, 60), 0, self.win)
                    if not bs.traf.asas.inconf[i]:
                        acfont = self.fontrad
                    else:
                        acfont = self.fontamb

                    acfont.printat(labelbmp, 0, 0, label[0])
                    acfont.printat(labelbmp, 0, dy, label[1])
                    acfont.printat(labelbmp, 0, 2 * dy, label[2])

                    bs.traf.label[i].append(label[0])
                    bs.traf.label[i].append(label[1])
                    bs.traf.label[i].append(label[2])
                    bs.traf.label[i].append(labelbmp)

                # Blit label
                dest = bs.traf.label[i][3].get_rect()
                dest.top = trafy[i] - 5
                dest.left = trafx[i] + 15
                self.win.blit(bs.traf.label[i][3], dest, None, pg.BLEND_ADD)

                # Draw aircraft speed vectors
                if self.swspd:
                    # just a nominal length: a speed of 150 kts will be displayed
                    # as an arrow of 30 pixels long on screen
                    nomlength = 30
                    nomspeed = 150.

                    vectorlength = float(nomlength) * bs.traf.tas[i] / nomspeed

                    spdvcx = trafx[i] + np.sin(np.radians(
                        bs.traf.trk[i])) * vectorlength
                    spdvcy = trafy[i] - np.cos(np.radians(bs.traf.trk[i])) * vectorlength \
                                - bs.traf.vs[i]/nomspeed*nomlength*self.isoalt /   \
                                            self.dtopix_eq(1e5)*1e5

                    pg.draw.line(self.win, green, (trafx[i], trafy[i]),
                                 (spdvcx, spdvcy))

            # ---- End of per aircraft i loop

            # Draw conflicts: line from a/c to closest point of approach
            nconf = len(bs.traf.asas.confpairs_unique)
            n2conf = len(bs.traf.asas.confpairs)

            if nconf > 0:

                for j in range(n2conf):
                    i = bs.traf.id2idx(bs.traf.asas.confpairs[j][0])
                    if i >= 0 and i < bs.traf.ntraf and (i in trafsel):
                        latcpa, loncpa = geo.kwikpos(bs.traf.lat[i], bs.traf.lon[i], \
                                                    bs.traf.trk[i], bs.traf.asas.tcpa[j] * bs.traf.gs[i] / nm)
                        altcpa = bs.traf.lat[
                            i] + bs.traf.vs[i] * bs.traf.asas.tcpa[j]
                        xc, yc = self.ll2xy(latcpa, loncpa)
                        yc = yc - altcpa * self.isoalt
                        pg.draw.line(self.win, amber, (xc, yc),
                                     (trafx[i], trafy[i]))

            # Draw selected route:
            if self.acidrte != "":
                i = bs.traf.id2idx(self.acidrte)
                if i >= 0:
                    for j in range(0, bs.traf.ap.route[i].nwp):
                        if j == 0:
                            x1,y1 = self.ll2xy(bs.traf.ap.route[i].wplat[j], \
                                               bs.traf.ap.route[i].wplon[j])
                        else:
                            x0, y0 = x1, y1
                            x1,y1 = self.ll2xy(bs.traf.ap.route[i].wplat[j], \
                                               bs.traf.ap.route[i].wplon[j])
                            pg.draw.line(self.win, magenta, (x0, y0), (x1, y1))

                        if j >= len(self.rtewpid) or not self.rtewpid[
                                j] == bs.traf.ap.route[i].wpname[j]:
                            # Waypoint name labels
                            # If waypoint label bitmap does not yet exist, make it

                            # Waypoint name and constraint(s), if there are any
                            txt = bs.traf.ap.route[i].wpname[j]

                            alt = bs.traf.ap.route[i].wpalt[j]
                            spd = bs.traf.ap.route[i].wpspd[j]

                            if alt >= 0. or spd >= 0.:
                                # Altitude
                                if alt < 0:
                                    txt = txt + " -----/"

                                elif alt > 4500 * ft:
                                    FL = int(round((alt / (100. * ft))))
                                    txt = txt + " FL" + str(FL) + "/"

                                else:
                                    txt = txt + " " + str(int(round(
                                        alt / ft))) + "/"

                                # Speed
                                if spd < 0:
                                    txt = txt + "---"
                                else:
                                    txt = txt + str(int(round(spd / kts)))

                            wplabel = pg.Surface((128, 32), 0, self.win)
                            self.fontnav.printat(wplabel, 0, 0, \
                                                 txt)

                            if j >= len(self.rtewpid):
                                self.rtewpid.append(txt)
                                self.rtewplabel.append(wplabel)
                            else:
                                self.rtewpid[j] = txt
                                self.rtewplabel[j] = wplabel

                        # In any case, blit the waypoint name
                        xtxt = x1 + 7
                        ytxt = y1 - 3
                        self.radbmp.blit(self.rtewplabel[j], (xtxt, ytxt), \
                                         None, pg.BLEND_ADD)

                        # Line from aircraft to active waypoint
                        if bs.traf.ap.route[i].iactwp == j:
                            x0, y0 = self.ll2xy(bs.traf.lat[i], bs.traf.lon[i])
                            pg.draw.line(self.win, magenta, (x0, y0), (x1, y1))

            # Draw aircraft trails which are on screen
            if bs.traf.trails.active:
                trlsel = list(np.where(
                    self.onradar(bs.traf.trails.lat0, bs.traf.trails.lon0) + \
                    self.onradar(bs.traf.trails.lat1, bs.traf.trails.lon1))[0])

                x0, y0 = self.ll2xy(bs.traf.trails.lat0, bs.traf.trails.lon0)
                x1, y1 = self.ll2xy(bs.traf.trails.lat1, bs.traf.trails.lon1)

                for i in trlsel:
                    pg.draw.line(self.win, bs.traf.trails.col[i], \
                                 (x0[i], y0[i]), (x1[i], y1[i]))

                # Redraw background => buffer ; if >1500 foreground linepieces on screen
                if len(trlsel) > 1500:
                    self.redrawradbg = True

        # Draw edit window
        self.editwin.update()

        if self.redrawradbg or redrawrad or self.editwin.redraw:
            self.win.blit(self.menu.bmps[self.menu.ipage], \
                           (self.menu.x, self.menu.y))
            self.win.blit(self.editwin.bmp,
                          (self.editwin.winx, self.editwin.winy))

            # Draw frames
            pg.draw.rect(self.win, white, self.editwin.rect, 1)
            pg.draw.rect(self.win, white,
                         pg.Rect(1, 1, self.width - 1, self.height - 1), 1)

            # Add debug line
            self.fontsys.printat(self.win, 10, 2,
                                 str(bs.sim.utc.replace(microsecond=0)))
            self.fontsys.printat(self.win, 10, 18, tim2txt(bs.sim.simt))
            self.fontsys.printat(self.win, 10+80, 2, \
                                 "ntraf = " + str(bs.traf.ntraf))
            self.fontsys.printat(self.win, 10+160, 2, \
                                 "Freq=" + str(int(len(bs.sim.dts) / max(0.001, sum(bs.sim.dts)))))

            self.fontsys.printat(self.win, 10+240, 2, \
                                 "#LOS      = " + str(len(bs.traf.asas.lospairs_unique)))
            self.fontsys.printat(self.win, 10+240, 18, \
                                 "Total LOS = " + str(len(bs.traf.asas.lospairs_all)))
            self.fontsys.printat(self.win, 10+240, 34, \
                                 "#Con      = " + str(len(bs.traf.asas.confpairs_unique)))
            self.fontsys.printat(self.win, 10+240, 50, \
                                 "Total Con = " + str(len(bs.traf.asas.confpairs_all)))

            # Frame ready, flip to screen
            pg.display.flip()

            # If needed, take a screenshot
            if self.screenshot:
                pg.image.save(self.win, self.screenshotname)
                self.screenshot = False
        return
コード例 #13
0
ファイル: screen.py プロジェクト: thobson88/bluesky
    def update(self):
        """Draw a new frame"""
        # First check for keys & mouse
        self.keyb.update()
        # Navdisp mode: get center:
        if self.swnavdisp:
            i = bs.traf.id2idx(self.ndacid)
            if i >= 0:
                self.ndlat = bs.traf.lat[i]
                self.ndlon = bs.traf.lon[i]
                self.ndcrs = bs.traf.hdg[i]
            else:
                self.swnavdisp = False
        else:
            self.ndcrs = 0.0


        # Radar window
        # --------------Background--------------

        if self.redrawradbg or self.swnavdisp:
            if self.swnavdisp or not self.swsat:
                self.radbmp.fill(darkgrey)

            else:
                #--------------Satellite image--------------
                navsel = (self.lat0, self.lat1, \
                          self.lon0, self.lon1)
                if not self.satsel == navsel:
                    # Map cutting and scaling: normal case
                    if self.lon1 > self.lon0:
                        x0 = max(0, self.lon0 * self.mapax + self.mapbx)
                        x1 = min(self.mapbmp.get_width() - 1, \
                                 self.lon1 * self.mapax + self.mapbx)

                        y1 = min(self.mapbmp.get_height() - 1, \
                                 self.lat0 * self.mapay + self.mapby)
                        y0 = max(0, self.lat1 * self.mapay + self.mapby)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (self.width, self.height))

                        self.radbmp.blit(self.submap, (0, 0))

                    else:
                        # Wrap around case: clip two segments
                        w0 = int(self.width * (180. - self.lon0) / \
                                 (180.0 - self.lon0 + self.lon1 + 180.))
                        w1 = int(self.width - w0)

                        # Left part
                        x0 = max(0, self.lon0 * self.mapax + self.mapbx)
                        x1 = self.mapbmp.get_width() - 1

                        y1 = min(self.mapbmp.get_height() - 1, \
                                 self.lat0 * self.mapay + self.mapby)
                        y0 = max(0, self.lat1 * self.mapay + self.mapby)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (w0, self.height))
                        self.radbmp.blit(self.submap, (0, 0))

                        # Right half
                        x0 = 0
                        x1 = min(self.mapbmp.get_width() - 1, \
                                 self.lon1 * self.mapax + self.mapbx)

                        selrect = pg.Rect(x0, y0, abs(x1 - x0), abs(y1 - y0))
                        mapsel = self.mapbmp.subsurface(selrect)
                        self.submap = pg.transform.scale(mapsel, \
                                                         (w1, self.height))
                        self.radbmp.blit(self.submap, (w0, 0))
                        self.submap = self.radbmp.copy()

                    self.satsel = navsel

                else:
                    # Map blit only
                    self.radbmp.blit(self.submap, (0, 0))


            if self.swgrid and not self.swnavdisp:
                # ------Draw lat/lon grid------
                ngrad = int(self.lon1 - self.lon0)

                if ngrad >= 10:
                    step = 10
                    i0 = step * int(self.lon0 / step)
                    j0 = step * int(self.lat0 / step)
                else:
                    step = 1
                    i0 = int(self.lon0)
                    j0 = int(self.lon0)

                for i in range(i0, int(self.lon1 + 1.), step):
                    x, y = self.ll2xy(self.ctrlat, i)
                    pg.draw.line(self.radbmp, lightgreygreen, \
                                 (x, 0), (x, self.height))

                for j in range(j0, int(self.lat1 + 1.), step):
                    x, y = self.ll2xy(j, self.ctrlon)
                    pg.draw.line(self.radbmp, lightgreygreen, \
                                 (0, y), (self.width, y))

            #------ Draw coastlines ------
            if self.swgeo:
                # cx,cy = -1,-1
                geosel = (self.lat0, self.lon0, self.lat1, self.lon1)
                if self.geosel != geosel:
                    self.geosel = geosel

                    self.cstsel = np.where(
                        self.onradar(self.coastlat0, self.coastlon0) + \
                        self.onradar(self.coastlat1, self.coastlon1))

                    # print len(self.cstsel[0])," coastlines"
                    self.cx0, self.cy0 = self.ll2xy(self.coastlat0, self.coastlon0)
                    self.cx1, self.cy1 = self.ll2xy(self.coastlat1, self.coastlon1)

                for i in list(self.cstsel[0]):
                    pg.draw.line(self.radbmp, grey, (self.cx0[i], self.cy0[i]), \
                                 (self.cx1[i], self.cy1[i]))

            #------ Draw FIRs ------
            if self.swfir:
                self.firx0, self.firy0 = self.ll2xy(bs.navdb.firlat0, \
                                                    bs.navdb.firlon0)

                self.firx1, self.firy1 = self.ll2xy(bs.navdb.firlat1, \
                                                    bs.navdb.firlon1)

                for i in range(len(self.firx0)):
                    pg.draw.line(self.radbmp, lightcyan,
                                 (self.firx0[i], self.firy0[i]),
                                 (self.firx1[i], self.firy1[i]))

            # -----------------Waypoint & airport symbols-----------------
            # Check whether we need to reselect waypoint set to be drawn

            navsel = (self.lat0, self.lat1, \
                      self.lon0, self.lon1)
            if self.navsel != navsel:
                self.navsel = navsel

                # Make list of indices of waypoints & airports on screen

                self.wpinside = list(np.where(self.onradar(bs.navdb.wplat, \
                                                           bs.navdb.wplon))[0])

                self.wptsel = []
                for i in self.wpinside:
                    if self.wpsw == 3 or \
                            (self.wpsw == 1 and len(bs.navdb.wpid[i]) == 3) or \
                            (self.wpsw == 2 and bs.navdb.wpid[i].isalpha()):
                        self.wptsel.append(i)
                self.wptx, self.wpty = self.ll2xy(bs.navdb.wplat, bs.navdb.wplon)

                self.apinside = list(np.where(self.onradar(bs.navdb.aptlat, \
                                                           bs.navdb.aptlon))[0])

                self.aptsel = []
                for i in self.apinside:
                    if self.apsw == 2 or (self.apsw == 1 and \
                                                      bs.navdb.aptmaxrwy[i] > 1000.):
                        self.aptsel.append(i)
                self.aptx, self.apty = self.ll2xy(bs.navdb.aptlat, bs.navdb.aptlon)


            #------- Draw waypoints -------
            if self.wpsw > 0:
                # print len(self.wptsel)," waypoints"
                if len(self.wptsel) < self.maxnrwp:
                    wptrect = self.wptsymbol.get_rect()
                    for i in self.wptsel:
                        # wptrect.center = self.ll2xy(bs.navdb.wplat[i],  \
                        #     bs.navdb.wplon[i])
                        wptrect.center = self.wptx[i], self.wpty[i]
                        self.radbmp.blit(self.wptsymbol, wptrect)

                        # If waypoint label bitmap does not yet exist, make it
                        if not self.wpswbmp[i]:
                            self.wplabel[i] = pg.Surface((80, 30), 0, self.win)
                            self.fontnav.printat(self.wplabel[i], 0, 0, \
                                                 bs.navdb.wpid[i])
                            self.wpswbmp[i] = True

                        # In any case, blit it
                        xtxt = wptrect.right + 2
                        ytxt = wptrect.top
                        self.radbmp.blit(self.wplabel[i], (xtxt, ytxt), \
                                         None, pg.BLEND_ADD)

                        if not self.wpswbmp[i]:
                            xtxt = wptrect.right + 2
                            ytxt = wptrect.top

                            # self.fontnav.printat(self.radbmp,xtxt,ytxt, \
                            #     bs.navdb.wpid[i])

            #------- Draw airports -------
            if self.apsw > 0:
                # if len(self.aptsel)<800:
                aptrect = self.aptsymbol.get_rect()

                # print len(self.aptsel)," airports"

                for i in self.aptsel:
                    # aptrect.center = self.ll2xy(bs.navdb.aptlat[i],  \
                    #                            bs.navdb.aptlon[i])
                    aptrect.center = self.aptx[i], self.apty[i]
                    self.radbmp.blit(self.aptsymbol, aptrect)

                    # If airport label bitmap does not yet exist, make it
                    if not self.apswbmp[i]:
                        self.aplabel[i] = pg.Surface((50, 30), 0, self.win)
                        self.fontnav.printat(self.aplabel[i], 0, 0, \
                                             bs.navdb.aptid[i])
                        self.apswbmp[i] = True

                    # In either case, blit it
                    xtxt = aptrect.right + 2
                    ytxt = aptrect.top
                    self.radbmp.blit(self.aplabel[i], (xtxt, ytxt), \
                                     None, pg.BLEND_ADD)

                    # self.fontnav.printat(self.radbmp,xtxt,ytxt, \
                    #     bs.navdb.aptid[i])


            #---------- Draw background trails ----------
            if bs.traf.trails.active:
                bs.traf.trails.buffer()  # move all new trails to background

                trlsel = list(np.where(
                    self.onradar(bs.traf.trails.bglat0, bs.traf.trails.bglon0) + \
                    self.onradar(bs.traf.trails.bglat1, bs.traf.trails.bglon1))[0])

                x0, y0 = self.ll2xy(bs.traf.trails.bglat0, bs.traf.trails.bglon0)
                x1, y1 = self.ll2xy(bs.traf.trails.bglat1, bs.traf.trails.bglon1)

                for i in trlsel:
                    pg.draw.aaline(self.radbmp, bs.traf.trails.bgcol[i], \
                                   (x0[i], y0[i]), (x1[i], y1[i]))

            #---------- Draw ADSB Coverage Area
            if self.swAdsbCoverage:
                # These points are based on the positions of the antennas with range = 200km
                adsbCoverageLat = [53.7863,53.5362,52.8604,51.9538,51.2285,50.8249,50.7382,
                                   50.9701,51.6096,52.498,53.4047,53.6402]
                adsbCoverageLon = [4.3757,5.8869,6.9529,7.2913,6.9312,6.251,5.7218,4.2955,
                                   3.2162,2.7701,3.1117,3.4891]

                for i in range(0,len(adsbCoverageLat)):
                    if i == len(adsbCoverageLat)-1:
                        x0, y0 = self.ll2xy(adsbCoverageLat[i],adsbCoverageLon[i])
                        x1, y1 = self.ll2xy(adsbCoverageLat[0],adsbCoverageLon[0])

                    else:
                        x0, y0 = self.ll2xy(adsbCoverageLat[i],adsbCoverageLon[i])
                        x1, y1 = self.ll2xy(adsbCoverageLat[i+1],adsbCoverageLon[i+1])

                    pg.draw.line(self.radbmp, red,(x0, y0), (x1, y1))

            # User defined objects
            for i in range(len(self.objtype)):

                # Draw LINE or POLYGON with objdata = [lat0,lon,lat1,lon1,lat2,lon2,..]
                if self.objtype[i]=='LINE' or self.objtype[i]=="POLY" or self.objtype[i]=="POLYLINE":
                    npoints = int(len(self.objdata[i])/2)
                    print(npoints)
                    x0,y0 = self.ll2xy(self.objdata[i][0],self.objdata[i][1])
                    for j in range(1,npoints):
                        x1,y1 = self.ll2xy(self.objdata[i][j*2],self.objdata[i][j*2+1])
                        pg.draw.line(self.radbmp,self.objcolor[i],(x0, y0), (x1, y1))
                        x0,y0 = x1,y1

                    if self.objtype[i]=="POLY":
                        x1,y1 = self.ll2xy(self.objdata[i][0],self.objdata[i][1])
                        pg.draw.line(self.radbmp,self.objcolor[i],(x0, y0), (x1, y1))

                # Draw bounding box of objdata = [lat0,lon0,lat1,lon1]
                elif self.objtype[i]=='BOX':
                    lat0 = min(self.objdata[i][0],self.objdata[i][2])
                    lon0 = min(self.objdata[i][1],self.objdata[i][3])
                    lat1 = max(self.objdata[i][0],self.objdata[i][2])
                    lon1 = max(self.objdata[i][1],self.objdata[i][3])

                    x0,y0 = self.ll2xy(lat1,lon0)
                    x1,y1 = self.ll2xy(lat0,lon1)
                    pg.draw.rect(self.radbmp,self.objcolor[i],pg.Rect(x0, y0, x1-x0, y1-y0),1)

                # Draw circle with objdata = [latcenter,loncenter,radiusnm]
                elif self.objtype[i]=='CIRCLE':
                    pass
                    xm,ym     = self.ll2xy(self.objdata[i][0],self.objdata[i][1])
                    xtop,ytop = self.ll2xy(self.objdata[i][0]+self.objdata[i][2]/60.,self.objdata[i][1])
                    radius    = int(round(abs(ytop-ym)))
                    pg.draw.circle(self.radbmp, self.objcolor[i], (int(xm),int(ym)), radius, 1)

            # Reset background drawing switch
            self.redrawradbg = False

        ##############################################################################
        #                          END OF BACKGROUND DRAWING                         #
        ##############################################################################

        # Blit background
        self.win.blit(self.radbmp, (0, 0))

        # Decide to redraw radar picture of a/c
        syst = pg.time.get_ticks() * 0.001
        redrawrad = self.redrawradbg or abs(syst - self.radt0) >= self.radardt

        if redrawrad:
            self.radt0 = syst  # Update lats drawing time of radar


            # Select which aircraft are within screen area
            trafsel = np.where((bs.traf.lat > self.lat0) * (bs.traf.lat < self.lat1) * \
                               (bs.traf.lon > self.lon0) * (bs.traf.lon < self.lon1))[0]

            # ------------------- Draw aircraft -------------------
            # Convert lat,lon to x,y

            trafx, trafy = self.ll2xy(bs.traf.lat, bs.traf.lon)
            trafy -= bs.traf.alt*self.isoalt

            if bs.traf.trails.active:
                ltx, lty = self.ll2xy(bs.traf.trails.lastlat, bs.traf.trails.lastlon)

            # Find pixel size of horizontal separation on screen
            pixelrad=self.dtopix_eq(bs.traf.asas.R/2)

            # Loop through all traffic indices which we found on screen
            for i in trafsel:

                # Get index of ac symbol, based on heading and its rect object
                isymb = int(round((bs.traf.hdg[i] - self.ndcrs) / 6.)) % 60
                pos = self.acsymbol[isymb].get_rect()

                # Draw aircraft symbol
                pos.centerx = trafx[i]
                pos.centery = trafy[i]
                dy = int(self.fontrad.linedy * 7 / 6)

                # Draw aircraft altitude line
                if self.isoalt>1e-7:
                    pg.draw.line(self.win,white,(int(trafx[i]),int(trafy[i])),(int(trafx[i]),int(trafy[i]+bs.traf.alt[i]*self.isoalt)))

                # Normal symbol if no conflict else amber
                toosmall=self.lat1-self.lat0>6 #don't draw circles if zoomed out too much

                if not bs.traf.asas.inconf[i]:
                    self.win.blit(self.acsymbol[isymb], pos)
                    if self.swsep and not toosmall:
                        pg.draw.circle(self.win,green,(int(trafx[i]),int(trafy[i])),pixelrad,1)
                else:
                    self.win.blit(self.ambacsymbol[isymb], pos)
                    if self.swsep and not toosmall:
                        pg.draw.circle(self.win,amber,(int(trafx[i]),int(trafy[i])),pixelrad,1)


                # Draw last trail part
                if bs.traf.trails.active:
                    pg.draw.line(self.win, tuple(bs.traf.trails.accolor[i]),
                                 (ltx[i], lty[i]), (trafx[i], trafy[i]))

                # Label text
                label = []
                if self.swlabel > 0:
                    label.append(bs.traf.id[i])  # Line 1 of label: id
                else:
                    label.append(" ")
                if self.swlabel > 1:
                    if bs.traf.alt[i]>bs.traf.translvl:
                        label.append("FL"+str(int(round(bs.traf.alt[i] / (100.*ft)))))  # Line 2 of label: altitude
                    else:
                        label.append(str(int(round(bs.traf.alt[i] / ft))))  # Line 2 of label: altitude
                else:
                    label.append(" ")
                if self.swlabel > 2:
                    cas = bs.traf.cas[i] / kts
                    label.append(str(int(round(cas))))  # line 3 of label: speed
                else:
                    label.append(" ")


                # Check for changes in traffic label text
                if  not (type(bs.traf.label[i])==list) or \
                      not (type(bs.traf.label[i][3])==str) or \
                        not (label[:3] == bs.traf.label[i][:3]):

                    bs.traf.label[i] = []
                    labelbmp = pg.Surface((100, 60), 0, self.win)
                    if not bs.traf.asas.inconf[i]:
                        acfont = self.fontrad
                    else:
                        acfont = self.fontamb

                    acfont.printat(labelbmp, 0, 0, label[0])
                    acfont.printat(labelbmp, 0, dy, label[1])
                    acfont.printat(labelbmp, 0, 2 * dy, label[2])

                    bs.traf.label[i].append(label[0])
                    bs.traf.label[i].append(label[1])
                    bs.traf.label[i].append(label[2])
                    bs.traf.label[i].append(labelbmp)

                # Blit label
                dest = bs.traf.label[i][3].get_rect()
                dest.top = trafy[i] - 5
                dest.left = trafx[i] + 15
                self.win.blit(bs.traf.label[i][3], dest, None, pg.BLEND_ADD)

                # Draw aircraft speed vectors
                if self.swspd:
                    # just a nominal length: a speed of 150 kts will be displayed
                    # as an arrow of 30 pixels long on screen
                    nomlength    = 30
                    nomspeed     = 150.

                    vectorlength = float(nomlength)*bs.traf.tas[i]/nomspeed

                    spdvcx = trafx[i] + np.sin(np.radians(bs.traf.trk[i])) * vectorlength
                    spdvcy = trafy[i] - np.cos(np.radians(bs.traf.trk[i])) * vectorlength \
                                - bs.traf.vs[i]/nomspeed*nomlength*self.isoalt /   \
                                            self.dtopix_eq(1e5)*1e5

                    pg.draw.line(self.win,green,(trafx[i],trafy[i]),(spdvcx,spdvcy))

            # ---- End of per aircraft i loop


            # Draw conflicts: line from a/c to closest point of approach
            nconf = len(bs.traf.asas.confpairs_unique)
            n2conf = len(bs.traf.asas.confpairs)

            if nconf>0:

                for j in range(n2conf):
                    i = bs.traf.id2idx(bs.traf.asas.confpairs[j][0])
                    if i>=0 and i<bs.traf.ntraf and (i in trafsel):
                        latcpa, loncpa = geo.kwikpos(bs.traf.lat[i], bs.traf.lon[i], \
                                                    bs.traf.trk[i], bs.traf.asas.tcpa[j] * bs.traf.gs[i] / nm)
                        altcpa = bs.traf.lat[i] + bs.traf.vs[i]*bs.traf.asas.tcpa[j]
                        xc, yc = self.ll2xy(latcpa,loncpa)
                        yc = yc - altcpa * self.isoalt
                        pg.draw.line(self.win,amber,(xc,yc),(trafx[i],trafy[i]))

            # Draw selected route:
            if self.acidrte != "":
                i = bs.traf.id2idx(self.acidrte)
                if i >= 0:
                    for j in range(0,bs.traf.ap.route[i].nwp):
                        if j==0:
                            x1,y1 = self.ll2xy(bs.traf.ap.route[i].wplat[j], \
                                               bs.traf.ap.route[i].wplon[j])
                        else:
                            x0,y0 = x1,y1
                            x1,y1 = self.ll2xy(bs.traf.ap.route[i].wplat[j], \
                                               bs.traf.ap.route[i].wplon[j])
                            pg.draw.line(self.win, magenta,(x0,y0),(x1,y1))

                        if j>=len(self.rtewpid) or not self.rtewpid[j]== bs.traf.ap.route[i].wpname[j]:
                            # Waypoint name labels
                            # If waypoint label bitmap does not yet exist, make it

                            # Waypoint name and constraint(s), if there are any
                            txt = bs.traf.ap.route[i].wpname[j]

                            alt = bs.traf.ap.route[i].wpalt[j]
                            spd = bs.traf.ap.route[i].wpspd[j]

                            if alt>=0. or spd >=0.:
                                # Altitude
                                if alt < 0:
                                    txt = txt + " -----/"

                                elif alt > 4500 * ft:
                                    FL = int(round((alt/(100.*ft))))
                                    txt = txt+" FL"+str(FL)+"/"

                                else:
                                    txt = txt+" "+str(int(round(alt / ft))) + "/"

                                # Speed
                                if spd < 0:
                                    txt = txt+"---"
                                else:
                                    txt = txt+str(int(round(spd / kts)))

                            wplabel = pg.Surface((128, 32), 0, self.win)
                            self.fontnav.printat(wplabel, 0, 0, \
                                                 txt)

                            if j>=len(self.rtewpid):
                                self.rtewpid.append(txt)
                                self.rtewplabel.append(wplabel)
                            else:
                                self.rtewpid[j]    = txt
                                self.rtewplabel[j] = wplabel

                        # In any case, blit the waypoint name
                        xtxt = x1 + 7
                        ytxt = y1 - 3
                        self.radbmp.blit(self.rtewplabel[j], (xtxt, ytxt), \
                                         None, pg.BLEND_ADD)

                        # Line from aircraft to active waypoint
                        if bs.traf.ap.route[i].iactwp == j:
                            x0,y0 = self.ll2xy(bs.traf.lat[i],bs.traf.lon[i])
                            pg.draw.line(self.win, magenta,(x0,y0),(x1,y1))



            # Draw aircraft trails which are on screen
            if bs.traf.trails.active:
                trlsel = list(np.where(
                    self.onradar(bs.traf.trails.lat0, bs.traf.trails.lon0) + \
                    self.onradar(bs.traf.trails.lat1, bs.traf.trails.lon1))[0])

                x0, y0 = self.ll2xy(bs.traf.trails.lat0, bs.traf.trails.lon0)
                x1, y1 = self.ll2xy(bs.traf.trails.lat1, bs.traf.trails.lon1)

                for i in trlsel:
                    pg.draw.line(self.win, bs.traf.trails.col[i], \
                                 (x0[i], y0[i]), (x1[i], y1[i]))

                # Redraw background => buffer ; if >1500 foreground linepieces on screen
                if len(trlsel) > 1500:
                    self.redrawradbg = True

        # Draw edit window
        self.editwin.update()

        if self.redrawradbg or redrawrad or self.editwin.redraw:
            self.win.blit(self.menu.bmps[self.menu.ipage], \
                           (self.menu.x, self.menu.y))
            self.win.blit(self.editwin.bmp, (self.editwin.winx, self.editwin.winy))

            # Draw frames
            pg.draw.rect(self.win, white, self.editwin.rect, 1)
            pg.draw.rect(self.win, white, pg.Rect(1, 1, self.width - 1, self.height - 1), 1)

            # Add debug line
            self.fontsys.printat(self.win, 10, 2, str(bs.sim.utc.replace(microsecond=0)))
            self.fontsys.printat(self.win, 10, 18, tim2txt(bs.sim.simt))
            self.fontsys.printat(self.win, 10+80, 2, \
                                 "ntraf = " + str(bs.traf.ntraf))
            self.fontsys.printat(self.win, 10+160, 2, \
                                 "Freq=" + str(int(len(bs.sim.dts) / max(0.001, sum(bs.sim.dts)))))

            self.fontsys.printat(self.win, 10+240, 2, \
                                 "#LOS      = " + str(len(bs.traf.asas.lospairs_unique)))
            self.fontsys.printat(self.win, 10+240, 18, \
                                 "Total LOS = " + str(len(bs.traf.asas.lospairs_all)))
            self.fontsys.printat(self.win, 10+240, 34, \
                                 "#Con      = " + str(len(bs.traf.asas.confpairs_unique)))
            self.fontsys.printat(self.win, 10+240, 50, \
                                 "Total Con = " + str(len(bs.traf.asas.confpairs_all)))

            # Frame ready, flip to screen
            pg.display.flip()

            # If needed, take a screenshot
            if self.screenshot:
                pg.image.save(self.win,self.screenshotname)
                self.screenshot=False
        return
コード例 #14
0
    def update(self,gain):
        # Time step update of drain

        # 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:
                # Calculate starting position using origin
                if len(self.orig)>0:
                    # Add origin
                    iorig = int(random.random() * len(self.orig))
                else:
                    iorig = -1

                if iorig>=0:
                    incirc = self.origincirc[iorig]
                    lat,lon = self.origlat[iorig],self.origlon[iorig]
                    hdg,dist = qdrdist(lat,lon,self.lat,self.lon)
                else:
                    print("Warning update drain",self.name,"called with no origins present!")
                    hdg = random.random()*360.
                    print("using random segment",int(hdg+180)%360)

                    incirc = False

                if not incirc:
                    lat,lon = kwikpos(ctrlat,ctrlon,(hdg+180)%360,radius)
                elif self.origtype=="seg":
                    lat,lon,brg = getseg(self.name)
                    hdg = (brg+180)%360
                else:
                    hdg = random.random()*360.

                if incirc and (self.origtype[iorig]=="apt" or self.origtype[iorig]=="rwy"):
                    alttxt,spdtxt = str(0),str(0)
                else:
                    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)

                if iorig>=0:
                    acid = randacname(self.orig[iorig], self.name)
                else:
                    acid = randacname("LFPG", self.name)

                if len(self.origactypes)>0:
                    actype = random.choice(self.origactypes[iorig])
                else:
                    actype = random.choice(self.actypes)

                stack.stack("CRE " + ",".join([acid,actype,str(lat), str(lon),
                                               str(int(hdg%360)),alttxt,spdtxt]))
                if iorig>=0:
                    if self.orig[iorig][:4]!="SEGM":
                        stack.stack(acid + " ORIG " + self.orig[iorig])
                    else:
                        stack.stack(acid + " ORIG " + str(self.origlat[iorig]) + " " +\
                                     str(self.origlon[iorig]))
                if not (self.name[:4]=="SEGM"):
                    stack.stack(acid + " DEST " + self.name)
                else:
                    stack.stack(acid + " ADDWPT " + str(self.lat) + " " + str(self.lon))

                if alttxt=="0" and spdtxt =="0":
                    stack.stack(acid+" SPD 250")
                    stack.stack(acid+" ALT FL100")
                    #stack.stack(acid+" LNAV ON")
                else:
                    stack.stack(acid + " LNAV ON")
コード例 #15
0
    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")
コード例 #16
0
ファイル: trafgenclasses.py プロジェクト: thobson88/bluesky
    def update(self,gain):
        # Time step update of drain

        # 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:
                # Calculate starting position using origin
                if len(self.orig)>0:
                    # Add origin
                    iorig = int(random.random() * len(self.orig))
                else:
                    iorig = -1

                if iorig>=0:
                    incirc = self.origincirc[iorig]
                    lat,lon = self.origlat[iorig],self.origlon[iorig]
                    hdg,dist = qdrdist(lat,lon,self.lat,self.lon)
                else:
                    print("Warning update drain",self.name,"called with no origins present!")
                    hdg = random.random()*360.
                    print("using random segment",int(hdg+180)%360)

                    incirc = False

                if not incirc:
                    lat,lon = kwikpos(ctrlat,ctrlon,(hdg+180)%360,radius)
                elif self.origtype=="seg":
                    lat,lon,brg = getseg(self.name)
                    hdg = (brg+180)%360
                else:
                    hdg = random.random()*360.

                if incirc and (self.origtype[iorig]=="apt" or self.origtype[iorig]=="rwy"):
                    alttxt,spdtxt = str(0),str(0)
                else:
                    alttxt,spdtxt = "FL"+str(random.randint(200,300)), str(random.randint(250,350))

                if iorig>=0:
                    acid = randacname(self.orig[iorig], self.name)
                else:
                    acid = randacname("LFPG", self.name)

                if len(self.origactypes)>0:
                    actype = random.choice(self.origactypes[iorig])
                else:
                    actype = random.choice(self.actypes)

                stack.stack("CRE " + ",".join([acid,actype,str(lat), str(lon),
                                               str(int(hdg%360)),alttxt,spdtxt]))
                if iorig>=0:
                    if self.orig[iorig][:4]!="SEGM":
                        stack.stack(acid + " ORIG " + self.orig[iorig])
                    else:
                        stack.stack(acid + " ORIG " + str(self.origlat[iorig]) + " " +\
                                     str(self.origlat[iorig]))
                if not (self.name[:4]=="SEGM"):
                    stack.stack(acid + " DEST " + self.name)
                else:
                    stack.stack(acid + " ADDWPT " + str(self.lat) + " " + str(self.lon))

                if alttxt=="0" and spdtxt =="0":
                    stack.stack(acid+" SPD 250")
                    stack.stack(acid+" ALT FL100")
                    #stack.stack(acid+" LNAV ON")
                else:
                    stack.stack(acid + " LNAV ON")
コード例 #17
0
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