Esempio n. 1
0
    def updatePolygon(self, name, data_in):
        if not self.initialized:
            return

        nact = self.nodedata[manager.sender()[0]]
        if name in nact.polynames:
            # We're either updating a polygon, or deleting it. In both cases
            # we remove the current one.
            nact.polydata = np.delete(nact.polydata, list(range(*nact.polynames[name])))
            del nact.polynames[name]

        # Break up polyline list of (lat,lon)s into separate line segments
        if data_in is not None:
            nact.polynames[name] = (len(nact.polydata), 2 * len(data_in))
            newbuf = np.empty(2 * len(data_in), dtype=np.float32)
            newbuf[0::4]   = data_in[0::2]  # lat
            newbuf[1::4]   = data_in[1::2]  # lon
            newbuf[2:-2:4] = data_in[2::2]  # lat
            newbuf[3:-3:4] = data_in[3::2]  # lon
            newbuf[-2:]    = data_in[0:2]
            nact.polydata  = np.append(nact.polydata, newbuf)

        # If the updated polygon buffer is also currently viewed, also send
        # updates to the gpu buffer
        if manager.sender()[0] == self.iactconn:
            self.makeCurrent()
            update_buffer(self.allpolysbuf, nact.polydata)
            self.allpolys.set_vertex_count(int(len(nact.polydata) / 2))
Esempio n. 2
0
    def updatePolygon(self, name, data_in):
        if not self.initialized:
            return

        nact = self.nodedata[manager.sender()[0]]
        if name in nact.polynames:
            # We're either updating a polygon, or deleting it. In both cases
            # we remove the current one.
            nact.polydata = np.delete(nact.polydata,
                                      range(*nact.polynames[name]))
            del nact.polynames[name]

        # Break up polyline list of (lat,lon)s into separate line segments
        if data_in is not None:
            nact.polynames[name] = (len(nact.polydata), 2 * len(data_in))
            newbuf = np.empty(2 * len(data_in), dtype=np.float32)
            newbuf[0::4] = data_in[0::2]  # lat
            newbuf[1::4] = data_in[1::2]  # lon
            newbuf[2:-2:4] = data_in[2::2]  # lat
            newbuf[3:-3:4] = data_in[3::2]  # lon
            newbuf[-2:] = data_in[0:2]
            nact.polydata = np.append(nact.polydata, newbuf)

        # If the updated polygon buffer is also currently viewed, also send
        # updates to the gpu buffer
        if manager.sender()[0] == self.iactconn:
            self.makeCurrent()
            update_buffer(self.allpolysbuf, nact.polydata)
            self.allpolys.set_vertex_count(len(nact.polydata) / 2)
Esempio n. 3
0
 def stack(self, text):
     # Add command to the command history
     self.command_history.append(text)
     self.echo(text)
     # Send stack command to sim process
     manager.sendEvent(StackTextEvent(cmdtext=text))
     self.cmdline_stacked.emit(self.cmd, self.args)
     # reset commandline and the autocomplete history
     self.setCmdline('')
     autocomplete.reset()
Esempio n. 4
0
    def defwpt(self, wpdata):
        if not self.initialized:
            return
        nact = self.nodedata[manager.sender()[0]]
        nact.custwplbl += wpdata[0].ljust(5)
        nact.custwplat = np.append(nact.custwplat, np.float32(wpdata[1]))
        nact.custwplon = np.append(nact.custwplon, np.float32(wpdata[2]))

        if manager.sender()[0] == self.iactconn:
            self.makeCurrent()
            update_buffer(self.custwplblbuf, np.array(nact.custwplbl))
            update_buffer(self.custwplatbuf, nact.custwplat)
            update_buffer(self.custwplonbuf, nact.custwplon)
            self.ncustwpts = len(nact.custwplat)
Esempio n. 5
0
    def defwpt(self, wpdata):
        if not self.initialized:
            return
        nact = self.nodedata[manager.sender()[0]]
        nact.custwplbl += wpdata[0].ljust(5)
        nact.custwplat = np.append(nact.custwplat, np.float32(wpdata[1]))
        nact.custwplon = np.append(nact.custwplon, np.float32(wpdata[2]))

        if manager.sender()[0] == self.iactconn:
            self.makeCurrent()
            update_buffer(self.custwplblbuf, np.array(nact.custwplbl))
            update_buffer(self.custwplatbuf, nact.custwplat)
            update_buffer(self.custwplonbuf, nact.custwplon)
            self.ncustwpts = len(nact.custwplat)
Esempio n. 6
0
def MainLoop():
    if node_only:
        runNode()

    else:
        # ======================================================================
        # Create gui and simulation objects
        # ======================================================================
        global navdb, manager, gui
        manager   = MainManager()
        gui       = Gui()
        navdb     = Navdatabase('global')  # Read database from specified folder
        telnet_in = StackTelnetServer()
        sim 	  = Simulation(manager)

        # Initialize the gui (loading graphics data, etc.)
        gui.init(navdb)

        # Start the node manager
        manager.start()

        # Start the telnet input server for stack commands
        telnet_in.listen(port=settings.telnet_port)

        # Start the gui
        gui.start()

        print 'Stopping telnet server.'
        telnet_in.close()

        # Close the manager, stop all nodes
        manager.stop()
        sim.quit()
        # ======================================================================
        # Clean up before exit. Comment this out when debugging for checking
        # variables in the shell.
        # ======================================================================
        del gui
        print 'BlueSky normal end.'
Esempio n. 7
0
    def clearNodeData(self):
        if not self.initialized:
            return

        # Clear all data for sender node
        nact = self.nodedata[manager.sender()[0]]
        nact.polynames.clear()
        nact.polydata = np.array([], dtype=np.float32)
        nact.custwplbl = ''
        nact.custwplat = np.array([], dtype=np.float32)
        nact.custwplon = np.array([], dtype=np.float32)

        # Clear trail data
        nact.traillat0 = []
        nact.traillon0 = []
        nact.traillat1 = []
        nact.traillon1 = []

        # If the updated polygon buffer is also currently viewed, also send
        # updates to the gpu buffer
        if manager.sender()[0] == self.iactconn:
            self.allpolys.set_vertex_count(0)
            self.traillines.set_vertex_count(0)
            self.ncustwpts = 0
Esempio n. 8
0
    def clearNodeData(self):
        if not self.initialized:
            return

        # Clear all data for sender node
        nact = self.nodedata[manager.sender()[0]]
        nact.polynames.clear()
        nact.polydata  = np.array([], dtype=np.float32)
        nact.custwplbl = ''
        nact.custwplat = np.array([], dtype=np.float32)
        nact.custwplon = np.array([], dtype=np.float32)

        # Clear trail data
        nact.traillat0 = []
        nact.traillon0 = []
        nact.traillat1 = []
        nact.traillon1 = []

        # If the updated polygon buffer is also currently viewed, also send
        # updates to the gpu buffer
        if manager.sender()[0] == self.iactconn:
            self.allpolys.set_vertex_count(0)
            self.traillines.set_vertex_count(0)
            self.ncustwpts = 0
Esempio n. 9
0
    def setCmdline(self, text):
        if self.command_line == text:
            return

        self.command_line   = text
        self.cmd, self.args = cmdsplit(self.command_line)

        hintline = ''
        allhints = node_stacks.get(manager.actnode())
        if allhints:
            hint = allhints.get(self.cmd)
            if hint:
                if len(self.args) > 0:
                    hintargs = hint.split(',')
                    hintline = ' ' + str.join(',', hintargs[len(self.args):])
                else:
                    hintline = ' ' + hint

        self.lineEdit.setHtml('>>' + self.command_line + '<font color="#aaaaaa">' + hintline + '</font>')
Esempio n. 10
0
def MainLoop():
    if node_only:
        runNode()

    else:
        # ======================================================================
        # Create gui and simulation objects
        # ======================================================================
        global navdb, manager, gui
        manager   = MainManager()
        gui       = Gui()
        navdb     = Navdatabase('global')  # Read database from specified folder
        telnet_in = StackTelnetServer()

        # Initialize the gui (loading graphics data, etc.)
        gui.init(navdb)

        # Start the node manager
        manager.start()

        # Start the telnet input server for stack commands
        telnet_in.listen(port=settings.telnet_port)

        # Start the gui
        gui.start()

        print 'Stopping telnet server.'
        telnet_in.close()

        # Close the manager, stop all nodes
        manager.stop()

        # ======================================================================
        # Clean up before exit. Comment this out when debugging for checking
        # variables in the shell.
        # ======================================================================
        del gui
        print 'BlueSky normal end.'
Esempio n. 11
0
    def notify(self, receiver, event):
        # Keep track of event processing
        event_processed = False

        # Events from the simulation threads
        if receiver is self:
            if event.type() == PanZoomEventType:
                if event.zoom is not None:
                    event.origin = (self.radarwidget.width / 2,
                                    self.radarwidget.height / 2)

                if event.pan is not None and not event.absolute:
                    event.pan = (
                        2.0 * event.pan[0] /
                        (self.radarwidget.zoom * self.radarwidget.ar),
                        2.0 * event.pan[1] /
                        (self.radarwidget.zoom * self.radarwidget.flat_earth))

                # send the pan/zoom event to the radarwidget
                self.radarwidget.event(event)

            elif event.type() == ACDataEventType:
                self.acdata = event
                self.radarwidget.update_aircraft_data(event)
                if self.nd.ac_id in event.id:
                    idx = event.id.index(self.nd.ac_id.upper())
                    lat = event.lat[idx]
                    lon = event.lon[idx]
                    trk = event.trk[idx]
                    tas = event.tas[idx]
                    self.nd.update_aircraft_data(idx, lat, lon, tas, trk,
                                                 len(event.lat))
                return True

            elif event.type() == RouteDataEventType:
                self.routedata = event
                self.radarwidget.update_route_data(event)
                return True

            elif event.type() == DisplayShapeEventType:
                self.radarwidget.updatePolygon(event.name, event.data)

            elif event.type() == SimInfoEventType:
                simt = tim2txt(event.simt)[:-3]
                simtclock = tim2txt(event.simtclock)[:-3]
                self.win.setNodeInfo(manager.sender()[0], simt, event.scenname)
                if manager.sender()[0] == manager.actnode():
                    self.simt = event.simt
                    self.win.siminfoLabel.setText(
                        u'<b>t:</b> %s, <b>\u0394t:</b> %.2f, <b>Speed:</b> %.1fx, <b>UTC:</b> %s, <b>Mode:</b> %s, <b>Aircraft:</b> %d, <b>Conflicts:</b> %d/%d, <b>LoS:</b> %d/%d'
                        % (simt, event.simdt, event.sys_freq, simtclock,
                           self.modes[event.mode], event.n_ac,
                           self.acdata.nconf_cur, self.acdata.nconf_tot,
                           self.acdata.nlos_cur, self.acdata.nlos_tot))
                return True

            elif event.type() == StackTextEventType:
                event_processed = True
                if event.disptext:
                    self.win.console.echo(event.disptext)
                if event.cmdtext:
                    self.win.console.setCmdline(event.cmdtext)

            elif event.type() == StackInitEventType:
                event_processed = True
                self.win.console.addStackHelp(manager.sender()[0],
                                              event.stackdict)

            elif event.type() == ShowDialogEventType:
                if event.dialog_type == event.filedialog_type:
                    self.show_file_dialog()
                elif event.dialog_type == event.docwin_type:
                    self.show_doc_window(event.cmd)
                return True

            elif event.type() == DisplayFlagEventType:
                # Switch/toggle/cycle radar screen features e.g. from SWRAD command
                if event.switch == 'RESET':
                    self.radarwidget.clearNodeData()
                # Coastlines
                elif event.switch == "GEO":
                    self.radarwidget.show_coast = not self.radarwidget.show_coast

                # FIR boundaries
                elif event.switch == "FIR":
                    self.radarwidget.showfir = not self.radarwidget.showfir

                # Airport: 0 = None, 1 = Large, 2= All
                elif event.switch == "APT":
                    self.radarwidget.show_apt = not self.radarwidget.show_apt

                # Waypoint: 0 = None, 1 = VOR, 2 = also WPT, 3 = Also terminal area wpts
                elif event.switch == "VOR" or event.switch == "WPT" or event.switch == "WP" or event.switch == "NAV":
                    self.radarwidget.show_apt = not self.radarwidget.show_apt

                # Satellite image background on/off
                elif event.switch == "SAT":
                    self.radarwidget.show_map = not self.radarwidget.show_map

                # Satellite image background on/off
                elif event.switch == "TRAF":
                    self.radarwidget.show_traf = not self.radarwidget.show_traf

                # ND window for selected aircraft
                elif event.switch == "ND":
                    self.nd.setAircraftID(event.argument)
                    self.nd.setVisible(not self.nd.isVisible())

                elif event.switch == "SSD":
                    self.radarwidget.show_ssd(event.argument)

                elif event.switch == "SYM":
                    # For now only toggle PZ
                    self.radarwidget.show_pz = not self.radarwidget.show_pz

                elif event.switch == "DEFWPT":
                    self.radarwidget.defwpt(event.argument)

                elif event.switch == "FILTERALT":
                    # First argument is an on/off flag
                    nact = self.radarwidget.nodedata[manager.sender()[0]]
                    if event.argument[0]:
                        nact.filteralt = event.argument[1:]
                    else:
                        nact.filteralt = False

                return True

            elif event.type() == AMANEventType:
                # self.aman.update(self.simt, event)
                pass

        # Mouse/trackpad event handling for the Radar widget
        elif receiver is self.radarwidget and self.radarwidget.initialized:
            panzoom = None
            if event.type() == QEvent.Wheel:
                # For mice we zoom with control/command and the scrolwheel
                if event.modifiers() & Qt.ControlModifier:
                    origin = (event.pos().x(), event.pos().y())
                    zoom = 1.0
                    try:
                        if event.pixelDelta():
                            # High resolution scroll
                            zoom *= (1.0 + 0.01 * event.pixelDelta().y())
                        else:
                            # Low resolution scroll
                            zoom *= (1.0 + 0.001 * event.angleDelta().y())
                    except:
                        zoom *= (1.0 + 0.001 * event.delta())
                    panzoom = PanZoomEvent(zoom=zoom, origin=origin)

                # For touchpad scroll (2D) is used for panning
                else:
                    try:
                        dlat = 0.01 * event.pixelDelta().y() / (
                            self.radarwidget.zoom * self.radarwidget.ar)
                        dlon = -0.01 * event.pixelDelta().x() / (
                            self.radarwidget.zoom *
                            self.radarwidget.flat_earth)
                        panzoom = PanZoomEvent(pan=(dlat, dlon))
                    except:
                        pass

            # For touchpad, pinch gesture is used for zoom
            elif event.type() == QEvent.Gesture:
                zoom = None
                pan = None
                dlat = 0.0
                dlon = 0.0
                for g in event.gestures():
                    if g.gestureType() == Qt.PinchGesture:
                        if zoom is None:
                            zoom = 1.0
                        zoom *= g.scaleFactor()
                        if correct_pinch:
                            zoom /= g.lastScaleFactor()
                    elif g.gestureType() == Qt.PanGesture:
                        if abs(g.delta().y() + g.delta().x()) > 1e-1:
                            dlat += 0.005 * g.delta().y() / (
                                self.radarwidget.zoom * self.radarwidget.ar)
                            dlon -= 0.005 * g.delta().x() / (
                                self.radarwidget.zoom *
                                self.radarwidget.flat_earth)
                            pan = (dlat, dlon)
                if pan is not None or zoom is not None:
                    panzoom = PanZoomEvent(pan, zoom, self.mousepos)

            elif event.type(
            ) == QEvent.MouseButtonPress and event.button() & Qt.LeftButton:
                event_processed = True
                self.mousedragged = False
                # For mice we pan with control/command and mouse movement. Mouse button press marks the beginning of a pan
                self.prevmousepos = (event.x(), event.y())

            elif event.type() == QEvent.MouseButtonRelease and event.button(
            ) & Qt.LeftButton and not self.mousedragged:
                event_processed = True
                lat, lon = self.radarwidget.pixelCoordsToLatLon(
                    event.x(), event.y())
                tostack, tocmdline = radarclick(self.win.console.command_line,
                                                lat, lon, self.acdata,
                                                self.routedata)
                if len(tocmdline) > 0:
                    if '\n' in tocmdline:
                        self.win.console.setCmdline('')
                        # Clear any shape command preview on the radar display
                        self.radarwidget.previewpoly(None)
                    else:
                        self.win.console.appendCmdline(tocmdline)
                    if len(tostack) > 0:
                        self.win.console.stack(tostack)

            elif event.type() == QEvent.MouseMove:
                event_processed = True
                self.mousedragged = True
                self.mousepos = (event.x(), event.y())
                if event.buttons() & Qt.LeftButton:
                    dlat = 0.003 * (event.y() - self.prevmousepos[1]) / (
                        self.radarwidget.zoom * self.radarwidget.ar)
                    dlon = 0.003 * (self.prevmousepos[0] - event.x()) / (
                        self.radarwidget.zoom * self.radarwidget.flat_earth)
                    self.prevmousepos = (event.x(), event.y())
                    panzoom = PanZoomEvent(pan=(dlat, dlon))

            # Update pan/zoom to simulation thread only when the pan/zoom gesture is finished
            elif (event.type() == QEvent.MouseButtonRelease
                  or event.type() == QEvent.TouchEnd) and self.panzoomchanged:
                self.panzoomchanged = False
                manager.sendEvent(
                    PanZoomEvent(pan=(self.radarwidget.panlat,
                                      self.radarwidget.panlon),
                                 zoom=self.radarwidget.zoom,
                                 absolute=True))

            # If we've just processed a change to pan and/or zoom, send the event to the radarwidget
            if panzoom is not None:
                self.panzoomchanged = True
                return self.radarwidget.event(panzoom)

        # Send all key presses directly to the main window
        if event.type() == QEvent.KeyPress:
            self.win.keyPressEvent(event)
            return True

        # If we haven't processed the event: call Base Class Method to Continue Normal Event Processing
        if not event_processed:
            return super(Gui, self).notify(receiver, event)

        if self.win.console.cmd in [
                'AREA', 'BOX', 'POLY', 'POLYALT', 'POLYGON', 'CIRCLE', 'LINE'
        ]:
            if self.mousepos != self.prevmousepos and len(
                    self.win.console.args) >= 2:
                self.prevmousepos = self.mousepos
                try:
                    # get the largest even number of points
                    start = 0 if self.win.console.cmd == 'AREA' else 3 if self.win.console.cmd == 'POLYALT' else 1
                    end = (
                        (len(self.win.console.args) - start) / 2) * 2 + start
                    data = [float(v) for v in self.win.console.args[start:end]]
                    data += self.radarwidget.pixelCoordsToLatLon(
                        *self.mousepos)
                    self.radarwidget.previewpoly(self.win.console.cmd, data)

                except ValueError:
                    pass

        event.accept()
        return True
Esempio n. 12
0
 def buttonClicked(self):
     if self.sender() == self.shownodes:
         vis = not self.nodetree.isVisible()
         self.nodetree.setVisible(vis)
         self.shownodes.setText('>' if vis else '<')
     if self.sender() == self.zoomin:
         self.app.notify(self.app, PanZoomEvent(zoom=1.4142135623730951))
     elif self.sender() == self.zoomout:
         self.app.notify(self.app, PanZoomEvent(zoom=0.70710678118654746))
     elif self.sender() == self.pandown:
         self.app.notify(self.app, PanZoomEvent(pan=(-0.5, 0.0)))
     elif self.sender() == self.panup:
         self.app.notify(self.app, PanZoomEvent(pan=(0.5, 0.0)))
     elif self.sender() == self.panleft:
         self.app.notify(self.app, PanZoomEvent(pan=(0.0, -0.5)))
     elif self.sender() == self.panright:
         self.app.notify(self.app, PanZoomEvent(pan=(0.0, 0.5)))
     elif self.sender() == self.ic:
         self.app.show_file_dialog()
     elif self.sender() == self.sameic:
         manager.sendEvent(StackTextEvent(cmdtext='IC IC'))
     elif self.sender() == self.hold:
         manager.sendEvent(StackTextEvent(cmdtext='HOLD'))
     elif self.sender() == self.op:
         manager.sendEvent(StackTextEvent(cmdtext='OP'))
     elif self.sender() == self.fast:
         manager.sendEvent(StackTextEvent(cmdtext='FF'))
     elif self.sender() == self.fast10:
         manager.sendEvent(StackTextEvent(cmdtext='FF 0:0:10'))
     elif self.sender() == self.showac:
         self.radarwidget.show_traf = not self.radarwidget.show_traf
     elif self.sender() == self.showpz:
         self.radarwidget.show_pz = not self.radarwidget.show_pz
     elif self.sender() == self.showapt:
         if self.radarwidget.show_apt < 3:
             self.radarwidget.show_apt += 1
         else:
             self.radarwidget.show_apt = 0
     elif self.sender() == self.showwpt:
         if self.radarwidget.show_wpt < 2:
             self.radarwidget.show_wpt += 1
         else:
             self.radarwidget.show_wpt = 0
     elif self.sender() == self.showlabels:
         self.radarwidget.show_lbl = not self.radarwidget.show_lbl
     elif self.sender() == self.showmap:
         self.radarwidget.show_map = not self.radarwidget.show_map
     elif self.sender() == self.action_Save:
         manager.sendEvent(StackTextEvent(cmdtext='SAVEIC'))
Esempio n. 13
0
    def update_aircraft_data(self, data):
        if not self.initialized:
            return

        self.makeCurrent()
        curnode = self.nodedata[self.iactconn]
        if curnode.filteralt:
            idx = np.where((data.alt >= curnode.filteralt[0]) *
                           (data.alt <= curnode.filteralt[1]))
            data.lat = data.lat[idx]
            data.lon = data.lon[idx]
            data.trk = data.trk[idx]
            data.alt = data.alt[idx]
            data.tas = data.tas[idx]
        self.naircraft = len(data.lat)

        if self.naircraft == 0:
            self.cpalines.set_vertex_count(0)
        else:
            # Update data in GPU buffers
            update_buffer(self.aclatbuf, np.array(data.lat, dtype=np.float32))
            update_buffer(self.aclonbuf, np.array(data.lon, dtype=np.float32))
            update_buffer(self.achdgbuf, np.array(data.trk, dtype=np.float32))
            update_buffer(self.acaltbuf, np.array(data.alt, dtype=np.float32))
            update_buffer(self.actasbuf, np.array(data.tas, dtype=np.float32))

            # CPA lines to indicate conflicts
            ncpalines = len(data.confcpalat)

            cpalines = np.zeros(4 * ncpalines, dtype=np.float32)
            self.cpalines.set_vertex_count(2 * ncpalines)

            # Labels and colors
            rawlabel = ''
            color = np.empty((self.naircraft, 4), dtype=np.uint8)
            selssd = np.zeros(self.naircraft, dtype=np.uint8)
            for i, acid in enumerate(data.id):
                # Make label: 3 lines of 8 characters per aircraft
                if data.alt[i] <= 4500. * ft:
                    rawlabel += '%-8s%-5d   %-8d' % (
                        acid[:8], int(data.alt[i] / ft + 0.5),
                        int(data.cas[i] / kts + 0.5))
                else:
                    rawlabel += '%-8sFL%03d   %-8d' % (
                        acid[:8], int(data.alt[i] / ft / 100. + 0.5),
                        int(data.cas[i] / kts + 0.5))
                confindices = data.iconf[i]
                if len(confindices) > 0:
                    if self.ssd_conflicts:
                        selssd[i] = 255
                    color[i, :] = amber + (255, )
                    for confidx in confindices:
                        cpalines[4 * confidx:4 * confidx + 4] = [
                            data.lat[i], data.lon[i], data.confcpalat[confidx],
                            data.confcpalon[confidx]
                        ]
                else:
                    color[i, :] = green + (255, )

                #  Check if aircraft is selected to show SSD
                if acid in self.ssd_ownship:
                    selssd[i] = 255

            if len(self.ssd_ownship) > 0 or self.ssd_conflicts:
                update_buffer(self.ssd.selssdbuf, selssd)

            update_buffer(self.confcpabuf, cpalines)
            update_buffer(self.accolorbuf, color)
            update_buffer(self.aclblbuf, np.array(rawlabel, dtype=np.string_))

            # If there is a visible route, update the start position
            if self.route_acid != "":
                if self.route_acid in data.id:
                    idx = data.id.index(self.route_acid)
                    update_buffer(
                        self.routebuf,
                        np.array([data.lat[idx], data.lon[idx]],
                                 dtype=np.float32))

            nact = self.nodedata[manager.sender()[0]]

            # Update trails database with new lines
            if data.swtrails:
                nact.traillat0.extend(data.traillat0)
                nact.traillon0.extend(data.traillon0)
                nact.traillat1.extend(data.traillat1)
                nact.traillon1.extend(data.traillon1)
                update_buffer(
                    self.trailbuf,
                    np.array(zip(nact.traillat0, nact.traillon0,
                                 nact.traillat1, nact.traillon1) +
                             zip(data.traillastlat, data.traillastlon,
                                 list(data.lat), list(data.lon)),
                             dtype=np.float32))

                self.traillines.set_vertex_count(2 * len(nact.traillat0) +
                                                 2 * len(data.lat))

            else:
                nact.traillat0 = []
                nact.traillon0 = []
                nact.traillat1 = []
                nact.traillon1 = []

                self.traillines.set_vertex_count(0)
Esempio n. 14
0
    def notify(self, receiver, event):
        # Keep track of event processing
        event_processed = False

        # Events from the simulation threads
        if receiver is self:
            if event.type() == PanZoomEventType:
                if event.zoom is not None:
                    event.origin = (self.radarwidget.width / 2, self.radarwidget.height / 2)

                if event.pan is not None and not event.absolute:
                    event.pan = (2.0 * event.pan[0] / (self.radarwidget.zoom * self.radarwidget.ar),
                                 2.0 * event.pan[1] / (self.radarwidget.zoom * self.radarwidget.flat_earth))

                # send the pan/zoom event to the radarwidget
                self.radarwidget.event(event)

            elif event.type() == ACDataEventType:
                self.acdata = event
                self.radarwidget.update_aircraft_data(event)
                if self.nd.ac_id in event.id:
                    idx = event.id.index(self.nd.ac_id.upper())
                    lat = event.lat[idx]
                    lon = event.lon[idx]
                    trk = event.trk[idx]
                    tas = event.tas[idx]
                    self.nd.update_aircraft_data(idx, lat, lon, tas, trk, len(event.lat))
                return True

            elif event.type() == RouteDataEventType:
                self.routedata = event
                self.radarwidget.update_route_data(event)
                return True

            elif event.type() == DisplayShapeEventType:
                self.radarwidget.updatePolygon(event.name, event.data)

            elif event.type() == SimInfoEventType:
                simt = tim2txt(event.simt)[:-3]
                simtclock = tim2txt(event.simtclock)[:-3]
                self.win.setNodeInfo(manager.sender()[0], simt, event.scenname)
                if manager.sender()[0] == manager.actnode():
                    self.simt = event.simt
                    self.win.siminfoLabel.setText(u'<b>t:</b> %s, <b>\u0394t:</b> %.2f, <b>Speed:</b> %.1fx, <b>UTC:</b> %s, <b>Mode:</b> %s, <b>Aircraft:</b> %d, <b>Conflicts:</b> %d/%d, <b>LoS:</b> %d/%d'
                        % (simt, event.simdt, event.sys_freq, simtclock, self.modes[event.mode], event.n_ac, self.acdata.nconf_cur, self.acdata.nconf_tot, self.acdata.nlos_cur, self.acdata.nlos_tot))
                return True

            elif event.type() == StackTextEventType:
                event_processed = True
                if event.disptext:
                    self.win.console.echo(event.disptext)
                if event.cmdtext:
                    self.win.console.setCmdline(event.cmdtext)

            elif event.type() == StackInitEventType:
                event_processed = True
                self.win.console.addStackHelp(manager.sender()[0], event.stackdict)

            elif event.type() == ShowDialogEventType:
                if event.dialog_type == event.filedialog_type:
                    self.show_file_dialog()
                elif event.dialog_type == event.docwin_type:
                    self.show_doc_window(event.cmd)
                return True

            elif event.type() == DisplayFlagEventType:
                # Switch/toggle/cycle radar screen features e.g. from SWRAD command
                if event.switch == 'RESET':
                    self.radarwidget.clearNodeData()
                # Coastlines
                elif event.switch == "GEO":
                    self.radarwidget.show_coast = not self.radarwidget.show_coast

                # FIR boundaries
                elif event.switch == "FIR":
                    self.radarwidget.showfir = not self.radarwidget.showfir

                # Airport: 0 = None, 1 = Large, 2= All
                elif event.switch == "APT":
                    self.radarwidget.show_apt = not self.radarwidget.show_apt

                # Waypoint: 0 = None, 1 = VOR, 2 = also WPT, 3 = Also terminal area wpts
                elif event.switch == "VOR" or event.switch == "WPT" or event.switch == "WP" or event.switch == "NAV":
                    self.radarwidget.show_apt = not self.radarwidget.show_apt

                # Satellite image background on/off
                elif event.switch == "SAT":
                    self.radarwidget.show_map = not self.radarwidget.show_map

                # Satellite image background on/off
                elif event.switch == "TRAF":
                    self.radarwidget.show_traf = not self.radarwidget.show_traf

                # ND window for selected aircraft
                elif event.switch == "ND":
                    self.nd.setAircraftID(event.argument)
                    self.nd.setVisible(not self.nd.isVisible())

                elif event.switch == "SSD":
                    self.radarwidget.show_ssd(event.argument)

                elif event.switch == "SYM":
                    # For now only toggle PZ
                    self.radarwidget.show_pz = not self.radarwidget.show_pz

                elif event.switch == "DEFWPT":
                    self.radarwidget.defwpt(event.argument)

                elif event.switch == "FILTERALT":
                    # First argument is an on/off flag
                    nact = self.radarwidget.nodedata[manager.sender()[0]]
                    if event.argument[0]:
                        nact.filteralt = event.argument[1:]
                    else:
                        nact.filteralt = False

                return True

            elif event.type() == AMANEventType:
                # self.aman.update(self.simt, event)
                pass

        # Mouse/trackpad event handling for the Radar widget
        elif receiver is self.radarwidget and self.radarwidget.initialized:
            panzoom = None
            if event.type() == QEvent.Wheel:
                # For mice we zoom with control/command and the scrolwheel
                if event.modifiers() & Qt.ControlModifier:
                    origin = (event.pos().x(), event.pos().y())
                    zoom   = 1.0
                    try:
                        if event.pixelDelta():
                            # High resolution scroll
                            zoom *= (1.0 + 0.01 * event.pixelDelta().y())
                        else:
                            # Low resolution scroll
                            zoom *= (1.0 + 0.001 * event.angleDelta().y())
                    except:
                        zoom *= (1.0 + 0.001 * event.delta())
                    panzoom = PanZoomEvent(zoom=zoom, origin=origin)

                # For touchpad scroll (2D) is used for panning
                else:
                    try:
                        dlat =  0.01 * event.pixelDelta().y() / (self.radarwidget.zoom * self.radarwidget.ar)
                        dlon = -0.01 * event.pixelDelta().x() / (self.radarwidget.zoom * self.radarwidget.flat_earth)
                        panzoom = PanZoomEvent(pan=(dlat, dlon))
                    except:
                        pass

            # For touchpad, pinch gesture is used for zoom
            elif event.type() == QEvent.Gesture:
                zoom   = None
                pan    = None
                dlat   = 0.0
                dlon   = 0.0
                for g in event.gestures():
                    if g.gestureType() == Qt.PinchGesture:
                        if zoom is None:
                            zoom = 1.0
                        zoom  *= g.scaleFactor()
                        if correct_pinch:
                            zoom /= g.lastScaleFactor()
                    elif g.gestureType() == Qt.PanGesture:
                        if abs(g.delta().y() + g.delta().x()) > 1e-1:
                            dlat += 0.005 * g.delta().y() / (self.radarwidget.zoom * self.radarwidget.ar)
                            dlon -= 0.005 * g.delta().x() / (self.radarwidget.zoom * self.radarwidget.flat_earth)
                            pan = (dlat, dlon)
                if pan is not None or zoom is not None:
                    panzoom = PanZoomEvent(pan, zoom, self.mousepos)

            elif event.type() == QEvent.MouseButtonPress and event.button() & Qt.LeftButton:
                event_processed   = True
                self.mousedragged = False
                # For mice we pan with control/command and mouse movement. Mouse button press marks the beginning of a pan
                self.prevmousepos = (event.x(), event.y())

            elif event.type() == QEvent.MouseButtonRelease and event.button() & Qt.LeftButton and not self.mousedragged:
                event_processed = True
                lat, lon  = self.radarwidget.pixelCoordsToLatLon(event.x(), event.y())
                tostack, tocmdline = radarclick(self.win.console.command_line, lat, lon, self.acdata, self.routedata)
                if len(tocmdline) > 0:
                    if '\n' in tocmdline:
                        self.win.console.setCmdline('')
                        # Clear any shape command preview on the radar display
                        self.radarwidget.previewpoly(None)
                    else:
                        self.win.console.appendCmdline(tocmdline)
                    if len(tostack) > 0:
                        self.win.console.stack(tostack)

            elif event.type() == QEvent.MouseMove:
                event_processed   = True
                self.mousedragged = True
                self.mousepos = (event.x(), event.y())
                if event.buttons() & Qt.LeftButton:
                    dlat = 0.003 * (event.y() - self.prevmousepos[1]) / (self.radarwidget.zoom * self.radarwidget.ar)
                    dlon = 0.003 * (self.prevmousepos[0] - event.x()) / (self.radarwidget.zoom * self.radarwidget.flat_earth)
                    self.prevmousepos = (event.x(), event.y())
                    panzoom = PanZoomEvent(pan=(dlat, dlon))

            # Update pan/zoom to simulation thread only when the pan/zoom gesture is finished
            elif (event.type() == QEvent.MouseButtonRelease or event.type() == QEvent.TouchEnd) and self.panzoomchanged:
                self.panzoomchanged = False
                manager.sendEvent(PanZoomEvent( pan=(self.radarwidget.panlat, self.radarwidget.panlon),
                                                zoom=self.radarwidget.zoom, absolute=True))

            # If we've just processed a change to pan and/or zoom, send the event to the radarwidget
            if panzoom is not None:
                self.panzoomchanged = True
                return self.radarwidget.event(panzoom)

        # Send all key presses directly to the main window
        if event.type() == QEvent.KeyPress:
            self.win.keyPressEvent(event)
            return True

        # If we haven't processed the event: call Base Class Method to Continue Normal Event Processing
        if not event_processed:
            return super(Gui, self).notify(receiver, event)

        if self.win.console.cmd in ['AREA', 'BOX', 'POLY', 'POLYALT', 'POLYGON', 'CIRCLE', 'LINE']:
            if self.mousepos != self.prevmousepos and len(self.win.console.args) >= 2:
                self.prevmousepos = self.mousepos
                try:
                    # get the largest even number of points
                    start = 0 if self.win.console.cmd == 'AREA' else 3 if self.win.console.cmd == 'POLYALT' else 1
                    end   = ((len(self.win.console.args) - start) // 2) * 2 + start
                    data  = [float(v) for v in self.win.console.args[start:end]]
                    data += self.radarwidget.pixelCoordsToLatLon(*self.mousepos)
                    self.radarwidget.previewpoly(self.win.console.cmd, data)

                except ValueError:
                    pass

        event.accept()
        return True
Esempio n. 15
0
 def buttonClicked(self):
     if self.sender() == self.shownodes:
         vis = not self.nodetree.isVisible()
         self.nodetree.setVisible(vis)
         self.shownodes.setText('>' if vis else '<')
     if self.sender() == self.zoomin:
         self.app.notify(self.app, PanZoomEvent(zoom=1.4142135623730951))
     elif self.sender() == self.zoomout:
         self.app.notify(self.app, PanZoomEvent(zoom=0.70710678118654746))
     elif self.sender() == self.pandown:
         self.app.notify(self.app, PanZoomEvent(pan=(-0.5,  0.0)))
     elif self.sender() == self.panup:
         self.app.notify(self.app, PanZoomEvent(pan=( 0.5,  0.0)))
     elif self.sender() == self.panleft:
         self.app.notify(self.app, PanZoomEvent(pan=( 0.0, -0.5)))
     elif self.sender() == self.panright:
         self.app.notify(self.app, PanZoomEvent(pan=( 0.0,  0.5)))
     elif self.sender() == self.ic:
         self.app.show_file_dialog()
     elif self.sender() == self.sameic:
         manager.sendEvent(StackTextEvent(cmdtext='IC IC'))
     elif self.sender() == self.hold:
         manager.sendEvent(StackTextEvent(cmdtext='HOLD'))
     elif self.sender() == self.op:
         manager.sendEvent(StackTextEvent(cmdtext='OP'))
     elif self.sender() == self.fast:
         manager.sendEvent(StackTextEvent(cmdtext='FF'))
     elif self.sender() == self.fast10:
         manager.sendEvent(StackTextEvent(cmdtext='FF 0:0:10'))
     elif self.sender() == self.showac:
         self.radarwidget.show_traf = not self.radarwidget.show_traf
     elif self.sender() == self.showpz:
         self.radarwidget.show_pz = not self.radarwidget.show_pz
     elif self.sender() == self.showapt:
         if self.radarwidget.show_apt < 3:
             self.radarwidget.show_apt += 1
         else:
             self.radarwidget.show_apt = 0
     elif self.sender() == self.showwpt:
         if self.radarwidget.show_wpt < 2:
             self.radarwidget.show_wpt += 1
         else:
             self.radarwidget.show_wpt = 0
     elif self.sender() == self.showlabels:
         self.radarwidget.show_lbl -= 1
         if self.radarwidget.show_lbl < 0:
             self.radarwidget.show_lbl = 2
     elif self.sender() == self.showmap:
         self.radarwidget.show_map = not self.radarwidget.show_map
     elif self.sender() == self.action_Save:
         manager.sendEvent(StackTextEvent(cmdtext='SAVEIC'))
Esempio n. 16
0
    def update_aircraft_data(self, data):
        if not self.initialized:
            return

        self.makeCurrent()
        curnode = self.nodedata[self.iactconn]
        if curnode.filteralt:
            idx = np.where((data.alt >= curnode.filteralt[0]) * (data.alt <= curnode.filteralt[1]))
            data.lat = data.lat[idx]
            data.lon = data.lon[idx]
            data.trk = data.trk[idx]
            data.alt = data.alt[idx]
            data.tas = data.tas[idx]
            data.vs  = data.vs[idx]
        self.naircraft = len(data.lat)

        if self.naircraft == 0:
            self.cpalines.set_vertex_count(0)
        else:
            # Update data in GPU buffers
            update_buffer(self.aclatbuf, np.array(data.lat, dtype=np.float32))
            update_buffer(self.aclonbuf, np.array(data.lon, dtype=np.float32))
            update_buffer(self.achdgbuf, np.array(data.trk, dtype=np.float32))
            update_buffer(self.acaltbuf, np.array(data.alt, dtype=np.float32))
            update_buffer(self.actasbuf, np.array(data.tas, dtype=np.float32))

            # CPA lines to indicate conflicts
            ncpalines = len(data.confcpalat)

            cpalines  = np.zeros(4 * ncpalines, dtype=np.float32)
            self.cpalines.set_vertex_count(2 * ncpalines)

            # Labels and colors
            rawlabel = ''
            color    = np.empty((self.naircraft, 4), dtype=np.uint8)
            selssd   = np.zeros(self.naircraft, dtype=np.uint8)
            for i, acid in enumerate(data.id):
                vs = 30 if data.vs[i] > 0.25 else 31 if data.vs[i] < -0.25 else 32
                # Make label: 3 lines of 8 characters per aircraft
                if self.show_lbl >= 1:
                    rawlabel += '%-8s' % acid[:8]
                    if self.show_lbl == 2:
                        if data.alt[i] <= 4500. * ft:
                            rawlabel += '%-5d' % int(data.alt[i]/ft  + 0.5)
                        else:
                            rawlabel += 'FL%03d' % int(data.alt[i]/ft/100.+0.5)
                        rawlabel += '%1s  %-8d' % (chr(vs), int(data.cas[i] / kts+0.5))
                    else:
                        rawlabel += 16 * ' '
                confindices = data.iconf[i]
                if len(confindices) > 0:
                    if self.ssd_conflicts:
                        selssd[i] = 255
                    color[i, :] = palette.conflict + (255,)
                    for confidx in confindices:
                        cpalines[4 * confidx : 4 * confidx + 4] = [ data.lat[i], data.lon[i],
                                                                    data.confcpalat[confidx], data.confcpalon[confidx]]
                else:
                    color[i, :] = palette.aircraft + (255,)

                #  Check if aircraft is selected to show SSD
                if acid in self.ssd_ownship:
                    selssd[i] = 255

            if len(self.ssd_ownship) > 0 or self.ssd_conflicts:
                update_buffer(self.ssd.selssdbuf, selssd)

            update_buffer(self.confcpabuf, cpalines)
            update_buffer(self.accolorbuf, color)
            update_buffer(self.aclblbuf, np.array(rawlabel.encode('utf8'), dtype=np.string_))

            # If there is a visible route, update the start position
            if self.route_acid != "":
                if self.route_acid in data.id:
                    idx = data.id.index(self.route_acid)
                    update_buffer(self.routebuf,
                                  np.array([data.lat[idx], data.lon[idx]], dtype=np.float32))

            nact = self.nodedata[manager.sender()[0]]

            # Update trails database with new lines
            if data.swtrails:
                nact.traillat0.extend(data.traillat0)
                nact.traillon0.extend(data.traillon0)
                nact.traillat1.extend(data.traillat1)
                nact.traillon1.extend(data.traillon1)
                update_buffer(self.trailbuf, np.array(
                              list(zip(nact.traillat0, nact.traillon0,
                                  nact.traillat1, nact.traillon1)) +
                              list(zip(data.traillastlat, data.traillastlon,
                                  list(data.lat), list(data.lon))),
                                       dtype=np.float32))

                self.traillines.set_vertex_count(2 * len(nact.traillat0) +
                                  2 * len(data.lat))

            else:
                nact.traillat0 = []
                nact.traillon0 = []
                nact.traillat1 = []
                nact.traillon1 = []

                self.traillines.set_vertex_count(0)