0

My current GUI is to show target tracking from a TI processor to PC via UART. Sometimes, GUI crashes due to UART performance. But everytime I want to reset GUI, I also have to reset my TI device. So I want to modify python code so as to only re-open GUI, enter COM port without having to reset device whenever GUI crashes.

Currently, each time GUI crashes, even though I re-opened GUI but didn't reset device (power off & on), I can not continue tracking.

I put python code for GUI below.In this GUI python program, we have 2 blanks & button to enter UART COM port, 2 buttons to select & send configuration to device. Then it can begin tracking.

I'm considering to modify the part of sendCfg(self), but still not sure how to make it work as my purpose due to my lack of experience in Python & GUI design. Please help me with sample code for this task.

    class Window(QDialog):
    def __init__(self, parent=None, size=[]):
        super(Window, self).__init__(parent)
        #when running Gree Demo
        self.Gree = 1
        # set window toolbar options, and title. #deb_gp
        self.setWindowFlags(
            Qt.Window |
            Qt.CustomizeWindowHint |
            Qt.WindowTitleHint |
            Qt.WindowMinimizeButtonHint |
            Qt.WindowMaximizeButtonHint |
            Qt.WindowCloseButtonHint
        )
        self.setWindowTitle("mmWave People Counting")

        print('Python is ', struct.calcsize("P")*8, ' bit')
        print('Python version: ', sys.version_info)



        gridlay = QGridLayout()
        gridlay.addWidget(self.comBox, 0,0,1,1)
        gridlay.addWidget(self.statBox, 1,0,1,1)
        gridlay.addWidget(self.configBox,2,0,1,1)
        gridlay.addWidget(self.plotControlBox,3,0,1,1)
        gridlay.addWidget(self.boxTab,4,0,1,1)
        gridlay.addWidget(self.spBox,5,0,1,1)
        gridlay.addWidget(self.graphTabs,0,1,6,1)
        gridlay.addWidget(self.gw, 0, 2, 6, 1)
        #gridlay.addWidget(self.demoData, 0,3,1,2)
        #gridlay.addWidget(self.hPlot,1,3,4,2)
        gridlay.setColumnStretch(0,1)
        gridlay.setColumnStretch(1,3)
        self.setLayout(gridlay)
#
# left side pane layout
#
    def setConnectionLayout(self):
        self.comBox = QGroupBox('Connect to Com Ports')
        self.uartCom = QLineEdit('')    #deb_gp
        self.dataCom = QLineEdit('')    #deb_gp
        self.uartLabel = QLabel('UART COM:')
        self.dataLabel = QLabel('DATA COM:')
        self.connectStatus = QLabel('Not Connected')
        self.connectButton = QPushButton('Connect')
        self.connectButton.clicked.connect(self.connectCom)
        self.configLabel = QLabel('Config Type:')
        self.configType = QComboBox()
        self.configType.addItems(["3D People Counting", "SDK Out of Box Demo", "Long Range People Detection", "Indoor False Detection Mitigation", "(Legacy) 2D People Counting", "(Legacy): Overhead People Counting"])
        self.comLayout = QGridLayout()
        self.comLayout.addWidget(self.uartLabel,0,0)
        self.comLayout.addWidget(self.uartCom,0,1)
        self.comLayout.addWidget(self.dataLabel,1,0)
        self.comLayout.addWidget(self.dataCom,1,1)
        self.comLayout.addWidget(self.configLabel,2,0)
        self.comLayout.addWidget(self.configType,2,1)
        self.comLayout.addWidget(self.connectButton,3,0)
        self.comLayout.addWidget(self.connectStatus,3,1)
        self.comBox.setLayout(self.comLayout)




    def setConfigLayout(self):
        self.configBox = QGroupBox('Configuration')
        self.selectConfig = QPushButton('Select Configuration')
        self.sendConfig = QPushButton('Send Configuration')
        self.selectConfig.clicked.connect(self.selectCfg)
        self.sendConfig.clicked.connect(self.sendCfg)       
        self.configTable = QTableWidget(5,2)
        #set parameter names
        self.configTable.setItem(0,0,QTableWidgetItem('Radar Parameter'))
        self.configTable.setItem(0,1,QTableWidgetItem('Value'))
        self.configTable.setItem(1,0,QTableWidgetItem('Max Range'))
        self.configTable.setItem(2,0,QTableWidgetItem('Range Resolution'))
        self.configTable.setItem(3,0,QTableWidgetItem('Max Velocity'))
        self.configTable.setItem(4,0,QTableWidgetItem('Velcoity Resolution'))
        self.configLayout = QVBoxLayout()
        self.configLayout.addWidget(self.selectConfig)
        self.configLayout.addWidget(self.sendConfig)
        self.configLayout.addWidget(self.configTable)       
        #self.configLayout.addStretch(1)
        self.configBox.setLayout(self.configLayout)



    def updateGraph(self, parsedData):
        updateStart = int(round(time.time()*1000))
        self.useFilter = 0
        classifierOutput = []
        pointCloud = parsedData[0]
        targets = parsedData[1]
        indexes = parsedData[2]
        numPoints = parsedData[3]
        numTargets = parsedData[4]
        self.frameNum = parsedData[5]
        fail = parsedData[6]
        classifierOutput = parsedData[7]
        fallDetEn = 0
        indicesIn = []
        if (fail != 1):
            #left side
            pointstr = 'Points: '+str(numPoints)
            targetstr = 'Targets: '+str(numTargets)
            self.numPointsDisplay.setText(pointstr)
            self.numTargetsDisplay.setText(targetstr)
            #right side fall detection
            peopleStr = 'Number of Detected People: '+str(numTargets)
            if (numTargets == 0):
                fdestr = 'Fall Detection Disabled - No People Detected'
            elif (numTargets == 1):
                fdestr = 'Fall Detection Enabled'
                fallDetEn = 1
            elif (numTargets > 1):
                fdestr = 'Fall Detected Disabled - Too Many People'
            #self.numDetPeople.setText(peopleStr)
            #self.fallDetEnabled.setText(fdestr)
        if (len(targets) < 13):
            targets = []
            classifierOutput = []
        if (fail):
            return
        #remove static points
        if (self.configType.currentText() == '3D People Counting'):
            if (not self.staticclutter.isChecked()):
                statics = np.where(pointCloud[3,:] == 0)
                try:
                    firstZ = statics[0][0]
                    numPoints = firstZ
                    pointCloud = pointCloud[:,:firstZ]
                    indexes = indexes[:,:self.previousFirstZ]
                    self.previousFirstZ = firstZ
                except:
                    firstZ = -1
        #point cloud persistence
        fNum = self.frameNum%10
        if (numPoints):
            self.previousCloud[:5,:numPoints,fNum] = pointCloud[:5,:numPoints]
            self.previousCloud[5,:len(indexes),fNum] = indexes
        self.previousPointCount[fNum]=numPoints
        #plotting 3D - get correct point cloud (persistent points and synchronize the frame)
        if (self.configType.currentText() == 'SDK3xPeopleCount'):
            pointIn = pointCloud
        else:
            totalPoints = 0
            persistentFrames = int(self.persistentFramesInput.currentText())
            #allocate new array for all the points
            for i in range(1,persistentFrames+1):
                totalPoints += self.previousPointCount[fNum-i]
            pointIn = np.zeros((5,int(totalPoints)))
            indicesIn = np.ones((1, int(totalPoints)))*255
            totalPoints = 0
            #fill array
            for i in range(1,persistentFrames+1):
                prevCount = int(self.previousPointCount[fNum-i])
                pointIn[:,totalPoints:totalPoints+prevCount] = self.previousCloud[:5,:prevCount,fNum-i]
                if (numTargets > 0):
                    indicesIn[0,totalPoints:totalPoints+prevCount] = self.previousCloud[5,:prevCount,fNum-i]
                totalPoints+=prevCount
        if (self.graphFin):
            self.plotstart = int(round(time.time()*1000))
            self.graphFin = 0
            if (self.threeD):
                try:
                    indicesIn = indicesIn[0,:]
                except:
                    indicesIn = []
                self.get_thread = updateQTTargetThread3D(pointIn, targets, indicesIn, self.scatter, self.pcplot, numTargets, self.ellipsoids, self.coordStr, classifierOutput, self.zRange, self.gw, self.plotByIndex.isChecked(), self.plotTracks.isChecked(), self.bbox,self.boundaryBoxes[0]['checkEnable'].isChecked())
                self.get_thread.done.connect(self.graphDone)
                self.get_thread.start(priority=QThread.HighestPriority-1)
            else:
                npc = pointIn[0:2,:]
                print (np.shape(npc))
                self.legacyThread = update2DQTGraphThread(npc, targets, numTargets, indexes, numPoints, self.trailData, self.activeTrail, self.trails, self.scatter2D, self.gatingScatter)
                self.legacyThread.done.connect(self.graphDone)
                self.legacyThread.start(priority=QThread.HighestPriority-1)
        else:
            return
        #pointIn = self.previousCloud[:,:int(self.previousPointCount[fNum-1]),fNum-1]

        #state tracking
        if (numTargets > 0):
            self.lastFrameHadTargets = True
        else:
            self.lastFrameHadTargets = False
        if (numTargets):
            self.lastTID = targets[0,:]
        else:
            self.lastTID = []

    def graphDone(self):
        plotend = int(round(time.time()*1000))
        plotime = plotend - self.plotstart
        try:
            if (self.frameNum > 1):
                self.averagePlot = (plotime*1/self.frameNum) + (self.averagePlot*(self.frameNum-1)/(self.frameNum))
            else:
                self.averagePlot = plotime
        except:
            self.averagePlot = plotime
        self.graphFin = 1
        pltstr = 'Average Plot time: '+str(plotime)[:5] + ' ms'
        fnstr = 'Frame: '+str(self.frameNum)
        self.frameNumDisplay.setText(fnstr)
        self.plotTimeDisplay.setText(pltstr)

    def resetFallText(self):
        self.fallAlert.setText('Standing')
        self.fallPic.setPixmap(self.standingPicture)
        self.fallResetTimerOn = 0

    def updateFallThresh(self):
        try:
            newThresh = float(self.fallThreshInput.text())
            self.fallThresh = newThresh
            self.fallThreshMarker.setPos(self.fallThresh)
        except:
            print('No numberical threshold')

    def connectCom(self):
        #get parser
        self.parser = uartParserSDK(type=self.configType.currentText())
        self.parser.frameTime = self.frameTime
        print('Parser type: ',self.configType.currentText())
        #init threads and timers
        self.uart_thread = parseUartThread(self.parser)
        if (self.configType.currentText() != 'Replay'):
            self.uart_thread.fin.connect(self.parseData)
        self.uart_thread.fin.connect(self.updateGraph)
        self.parseTimer = QTimer()
        self.parseTimer.setSingleShot(False)
        self.parseTimer.timeout.connect(self.parseData)        
        try:
            uart = "COM"+ self.uartCom.text()       #deb_gp
            data = "COM"+ self.dataCom.text()       #deb_gp
#TODO: find the serial ports automatically.
            self.parser.connectComPorts(uart, data)
            self.connectStatus.setText('Connected')     #deb_gp
            self.connectButton.setText('Disconnect')    #deb_gp
#TODO: create the disconnect button action
        except:
            self.connectStatus.setText('Unable to Connect')
        if (self.configType.currentText() == "Replay"):
            self.connectStatus.setText('Replay')
        if (self.configType.currentText() == "Long Range People Detection"):
            self.frameTime = 400
#
# Select and parse the configuration file
# TODO select the cfgfile automatically based on the profile.
    def selectCfg(self):
        try:
            self.parseCfg(self.selectFile())
        except:
            print('No cfg file selected!')
    def selectFile(self):
        fd = QFileDialog()
        filt = "cfg(*.cfg)"
        filename = fd.getOpenFileName(directory='./../chirp_configs',filter=filt)    #deb_gp - added folder name
        return filename[0]
    def parseCfg(self, fname):
        cfg_file = open(fname, 'r')
        self.cfg = cfg_file.readlines()
        counter = 0
        chirpCount = 0
        for line in self.cfg:
            args = line.split()
            if (len(args) > 0):
                if (args[0] == 'cfarCfg'):
                    zy = 4
                    #self.cfarConfig = {args[10], args[11], '1'}
                elif (args[0] == 'AllocationParam'):
                    zy=3
                    #self.allocConfig = tuple(args[1:6])
                elif (args[0] == 'GatingParam'):
                    zy=2
                    #self.gatingConfig = tuple(args[1:4])
                elif (args[0] == 'SceneryParam' or args[0] == 'boundaryBox'):
                    self.boundaryLine = counter
                    self.profile['leftX'] = float(args[1])
                    self.profile['rightX'] = float(args[2])
                    self.profile['nearY'] = float(args[3])
                    self.profile['farY'] = float(args[4])
                    self.setBoundaryTextVals(self.profile)
                    self.boundaryBoxes[0]['checkEnable'].setChecked(True)
                elif (args[0] == 'staticBoundaryBox'):
                    self.staticLine = counter
                elif (args[0] == 'profileCfg'):
                    self.profile['startFreq'] = float(args[2])
                    self.profile['idle'] = float(args[3])
                    self.profile['adcStart'] = float(args[4])
                    self.profile['rampEnd'] = float(args[5])
                    self.profile['slope'] = float(args[8])
                    self.profile['samples'] = float(args[10])
                    self.profile['sampleRate'] = float(args[11])
                    print(self.profile)
                elif (args[0] == 'frameCfg'):
                    self.profile['numLoops'] = float(args[3])
                    self.profile['numTx'] = float(args[2])+1
                elif (args[0] == 'chirpCfg'):
                    chirpCount += 1
                elif (args[0] == 'sensorPosition'):
                    self.profile['sensorHeight'] = float(args[1])
                    self.profile['az_tilt'] = float(args[2])
                    self.profile['elev_tilt'] = float(args[3])
            counter += 1
        maxRange = self.profile['sampleRate']*1e3*0.9*3e8/(2*self.profile['slope']*1e12)
        #update boundary box
        self.drawBoundaryGrid(maxRange)
        #update chirp table values
        bw = self.profile['samples']/(self.profile['sampleRate']*1e3)*self.profile['slope']*1e12
        rangeRes = 3e8/(2*bw)
        Tc = (self.profile['idle']*1e-6 + self.profile['rampEnd']*1e-6)*chirpCount
        lda = 3e8/(self.profile['startFreq']*1e9)
        maxVelocity = lda/(4*Tc)
        velocityRes = lda/(2*Tc*self.profile['numLoops']*self.profile['numTx'])
        self.configTable.setItem(1,1,QTableWidgetItem(str(maxRange)[:5]))
        self.configTable.setItem(2,1,QTableWidgetItem(str(rangeRes)[:5]))
        self.configTable.setItem(3,1,QTableWidgetItem(str(maxVelocity)[:5]))
        self.configTable.setItem(4,1,QTableWidgetItem(str(velocityRes)[:5]))
        #update sensor position
        self.az_tilt.setText(str(self.profile['az_tilt']))
        self.elev_tilt.setText(str(self.profile['elev_tilt']))
        self.s_height.setText(str(self.profile['sensorHeight']))

    def sendCfg(self):
        try:
            if (self.configType.currentText() != "Replay"):
                self.parser.sendCfg(self.cfg)
                self.configSent = 1
            self.parseTimer.start(self.frameTime)
        except:
            print ('No cfg file selected!')

    # Needed ?? deb_gp
    # def setParser(self, uParser):
    #     self.parser = uParser

    def parseData(self):
        self.uart_thread.start(priority=QThread.HighestPriority)

    def whoVisible(self):
        if (self.threeD):
            self.threeD = 0
        else:
            self.threeD = 1
        print('3d: ', self.threeD)

if __name__ == '__main__':
    if (compileGui):
        appctxt = ApplicationContext()
        app = QApplication(sys.argv)
        screen = app.primaryScreen()
        size = screen.size()
        main = Window(size=size)
        main.show()
        exit_code = appctxt.app.exec_()
        sys.exit(exit_code)
    else:
        app = QApplication(sys.argv)
        screen = app.primaryScreen()
        size = screen.size()
        main = Window(size=size)
        main.show()
        sys.exit(app.exec_())
Hector Ta
  • 81
  • 2
  • 14
  • Does this answer your question? [python-try-except-inside-of-function](https://stackoverflow.com/questions/4148015) – stovfl Apr 23 '20 at 10:36
  • @stovfl I already had try-except in sendCfg(). So I'm not sure how to modify it to reach my expectation? After GUI crashes, I only want to re-open GUI, I don't want to send configuration to my device again or reset device. – Hector Ta Apr 23 '20 at 14:12
  • ***already had try-except in sendCfg(). ... After GUI crashes***: Then you don't catch the exception. The goal to use a try-except are to **catch** the exception and **not** to crash. – stovfl Apr 23 '20 at 14:43

0 Answers0