logInspector.py
Go to the documentation of this file.
1 #!/usr/bin/python3
2 
3 import sys, os, shutil
4 from PyQt5 import QtCore
5 from PyQt5.QtWidgets import QWidget, QDialog, QApplication, QPushButton, QVBoxLayout, QLineEdit, QTreeView, QFileSystemModel,\
6  QHBoxLayout, QGridLayout, QMainWindow, QSizePolicy, QSpacerItem, QFileDialog, QMessageBox, QLabel, QRadioButton,\
7  QAbstractItemView, QMenu, QTableWidget,QTableWidgetItem, QSpinBox, QSpacerItem
8 from PyQt5.QtGui import QMovie, QPicture, QIcon, QDropEvent, QPixmap, QImage
9 from PyQt5.Qt import QApplication, QClipboard, QStyle
10 import json
11 import io
12 
13 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
14 from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
15 import matplotlib.pyplot as plt
16 import numpy as np
17 from threading import Thread
18 
19 from logReader import Log
20 from logPlotter import logPlot
21 import traceback
22 import yaml
23 import sys
24 
25 sys.path.append('..')
26 sys.path.append('../supernpp/')
27 sys.path.append('../ci_hdw/')
28 from pylib.data_sets import *
29 import subprocess
30 import re
31 
32 START_MODE_HOT = 0
33 START_MODE_COLD = 1
34 START_MODE_FACTORY = 2
35 
37  if sys.platform == 'darwin':
38  subprocess.check_call(['open', '--', path])
39  elif sys.platform == 'linux':
40  subprocess.check_call(['xdg-open', path])
41  elif sys.platform == 'win32':
42  # subprocess.check_call(['explorer', path]) # Not stable
43  subprocess.Popen(r'explorer '+path)
44 
45 def cleanFolder(path, toplevel=True):
46  containsDAT = False
47  containsSDAT = False
48  for fname in os.listdir(path):
49  if fname.endswith('.dat'):
50  containsDAT = True
51  if fname.endswith('.sdat'):
52  containsSDAT = True
53 
54  for fname in os.listdir(path):
55  fpath = os.path.join(path, fname)
56  if os.path.isdir( fpath ):
57  if fname == 'post_processed':
58  removeDirectory(fpath)
59  else:
60  cleanFolder(fpath, False)
61  else:
62  # Remove .csv if .dat or .sdat exist
63  if containsDAT or containsSDAT:
64  if fname.endswith('.csv'):
65  print('Deleting: ' + fpath)
66  os.remove(fpath)
67  # Remove .sdat if .dat exist
68  if containsDAT:
69  if fname.endswith('.sdat'):
70  print('Deleting: ' + fpath)
71  os.remove(fpath)
72  if toplevel:
73  print('Finished Cleaning!')
74 
75 def removeDirectory(fpath):
76  print('Removing Directory: ' + fpath)
77  shutil.rmtree(fpath)
78 
79 # startMode 0=hot, 1=cold, 2=factory
80 def setDataInformationDirectory(path, startMode=START_MODE_HOT):
81  settings_filename = os.path.expanduser("~") + '/Documents/Inertial_Sense/dataInformation.json'
82 
83  if settings_filename is not None:
84  # with open(settings_filename, 'r') as f:
85  # data = json.load(f)
86  # f.close()
87  data = {}
88  data['dataInfo'] = {}
89  data['dataInfo']['dataDirectory'] = os.path.dirname(path).replace('\\','/')
90  data['dataInfo']['subDirectories'] = [os.path.basename(path)]
91  serialnumbers = []
92  for root, dirs, files in os.walk(path):
93  for filename in files:
94  if "LOG_SN" in filename:
95  serialnum = filename[4:11]
96  if serialnum not in serialnumbers:
97  serialnumbers += [serialnum]
98 
99  data['processData'] = {}
100  data['processData']['datasets'] = [{}]
101  data['processData']['datasets'][0]['SerialNumbers'] = serialnumbers
102  data['processData']['datasets'][0]['folder'] = os.path.basename(path)
103  data['processData']['datasets'][0]['logType'] = 'DAT'
104  if startMode == START_MODE_HOT:
105  data['processData']['datasets'][0]['startMode'] = 'HOT'
106  elif startMode == START_MODE_COLD:
107  data['processData']['datasets'][0]['startMode'] = 'COLD'
108  else:
109  data['processData']['datasets'][0]['startMode'] = 'FACTORY'
110 
111  # os.remove(settings_filename)
112  with open(settings_filename, 'w') as f:
113  json.dump(data, f, indent=4)
114 
115 def verArrayToString(array):
116  return str(array[0]) + '.' + str(array[1]) + '.' + str(array[2]) #+ '.' + str(array[3])
117 
118 def dateTimeArrayToString(date, time):
119  return str(date[1]+2000) + '-' + f'{date[2]:02}' + '-' + f'{date[3]:02}' + ' ' + f'{time[0]:02}' + ':' + f'{time[1]:02}' + ':' + f'{time[2]:02}'
120 
121 class DeviceInfoDialog(QDialog):
122 
123  def __init__(self, log, parent=None):
124  super(DeviceInfoDialog, self).__init__(parent)
125  self.setWindowTitle("Device Info")
126 
127  if np.shape(log.data[0,DID_DEV_INFO])[0] == 0:
128  self.label = QLabel('No DID_DEV_INFO data available.')
129  self.mainlayout = QVBoxLayout()
130  self.mainlayout.addWidget(self.label)
131  self.setLayout(self.mainlayout)
132  self.resize(400, 200)
133  return
134 
135  self.table = QTableWidget()
136  nfields = len(log.data[0, DID_DEV_INFO].dtype.names)
137  field_names = []
138  vals = []
139 
140  self.table.setColumnCount(9)
141  self.table.setHorizontalHeaderLabels(['Serial#','Hardware','Firmware','Build','Protocol','Repo','Build Date','Manufacturer','AddInfo'])
142 
143  for d, dev in enumerate(log.data):
144  data = dev[DID_DEV_INFO][0]
145  self.table.setRowCount(d+1)
146  self.table.setItem(d, 0, QTableWidgetItem(str(data[1]))) # Serial#
147  self.table.setItem(d, 1, QTableWidgetItem(verArrayToString(data[2]))) # Hardware version
148  self.table.setItem(d, 2, QTableWidgetItem(verArrayToString(data[3]))) # Firmware version
149  self.table.setItem(d, 3, QTableWidgetItem(str(data[4]))) # Build
150  self.table.setItem(d, 4, QTableWidgetItem(verArrayToString(data[5]))) # Protocol
151  self.table.setItem(d, 5, QTableWidgetItem(str(data[6]))) # Repo
152  self.table.setItem(d, 6, QTableWidgetItem(dateTimeArrayToString(data[8], data[9]))) # Build Date & Time
153  self.table.setItem(d, 7, QTableWidgetItem(data[7].decode('UTF-8'))) # Manufacturer
154  self.table.setItem(d, 8, QTableWidgetItem(data[10].decode('UTF-8'))) # Additional Info
155 
156  self.mainlayout = QVBoxLayout()
157  self.mainlayout.addWidget(self.table)
158  self.setLayout(self.mainlayout)
159  self.resize(2000, 800)
160 
161 class FlashConfigDialog(QDialog):
162  def __init__(self, log, parent=None):
163  super(FlashConfigDialog, self).__init__(parent)
164  self.setWindowTitle("Flash Config")
165 
166  if np.shape(log.data[0,DID_FLASH_CONFIG])[0] == 0:
167  self.label = QLabel('No DID_FLASH_CONFIG data available.')
168  self.mainlayout = QVBoxLayout()
169  self.mainlayout.addWidget(self.label)
170  self.setLayout(self.mainlayout)
171  self.resize(400, 200)
172  return
173 
174  self.table = QTableWidget()
175  nfields = len(log.data[0, DID_FLASH_CONFIG].dtype.names)
176  field_names = []
177  vals = []
178 
179  for d, dev in enumerate(log.data):
180  vals.append([])
181  for f, field in enumerate(dev[DID_FLASH_CONFIG].dtype.names):
182  if isinstance(dev[DID_FLASH_CONFIG][field][0], np.ndarray):
183  length = len(dev[DID_FLASH_CONFIG][field][0])
184  if d == 0: nfields += length-1 # add extra rows for arrays in flash config
185  for i in range(length):
186  if d == 0: field_names.append(field + "[" + str(i) + "]")
187  vals[d].append(dev[DID_FLASH_CONFIG][field][0][i])
188  else:
189  if d == 0: field_names.append(field)
190  vals[d].append(dev[DID_FLASH_CONFIG][field][0])
191 
192  self.table.setRowCount(nfields)
193  self.table.setColumnCount(log.numDev)
194 
195  self.table.setHorizontalHeaderLabels([str(ser) for ser in log.serials])
196  self.table.setVerticalHeaderLabels(field_names)
197 
198  hex_fields = ['ioConfig', 'cBrdConfig', 'RTKCfgBits', 'sysCfgBits']
199  for d in range(log.numDev):
200  for f, field in enumerate(field_names):
201  if field in hex_fields:
202  self.table.setItem(f, d, QTableWidgetItem(hex(vals[d][f])))
203  else:
204  self.table.setItem(f, d, QTableWidgetItem(str(vals[d][f])))
205 
206  self.mainlayout = QVBoxLayout()
207  self.mainlayout.addWidget(self.table)
208  self.setLayout(self.mainlayout)
209  self.resize(1280, 900)
210 
211 
212 
213 
214 class LogInspectorWindow(QMainWindow):
215  def __init__(self, configFilePath, parent=None):
216  super(LogInspectorWindow, self).__init__(parent)
217  self.initMatPlotLib()
218  self.configFilePath = configFilePath
219 
220  if os.path.exists(self.configFilePath):
221  # config.yaml found. Read from file.
222  file = open(self.configFilePath, 'r')
223  self.config = yaml.load(file)
224  file.close()
225  else:
226  # config.yaml not found. Create new file.
227  self.config = {}
228  self.config['logs_directory'] = os.path.join(os.path.expanduser("~"), "Documents", "Inertial_Sense", "Logs")
229  self.config['directory'] = ""
230  self.config['serials'] = ["ALL"]
231  file = open(self.configFilePath, 'w')
232  yaml.dump(self.config, file)
233  file.close()
234 
235  self.currently_selected = 'posNEDMap'
236  self.downsample = 5
237  self.plotargs = None
238  self.log = None
239  self.plotter = None
240 
241 
242  def initMatPlotLib(self):
243  self.figure = plt.figure()
244  self.canvas = FigureCanvas(self.figure)
245  self.toolbar = NavigationToolbar(self.canvas, self)
246  self.figure.subplots_adjust(left=0.05, right=0.99, bottom=0.05, top=0.91, wspace=0.2, hspace=0.2)
247 
248  def addButton(self, name, function, multithreaded=True, layout=None):
249  setattr(self, name+"button", QPushButton(name))
250  # if multithreaded:
251  # setattr(self, name+"buttonThread", Thread(target=function))
252  # getattr(self, name+"button").pressed.connect(self.startLoadingIndicator)
253  # getattr(self, name+"button").released.connect(getattr(self, name+"buttonThread").start)
254  # else:
255  getattr(self, name + "button").clicked.connect(function)
256  # getattr(self, name + "button").setMinimumWidth(220)
257  if layout is None:
259  self.buttonLayoutRightCol.addWidget(getattr(self, name + "button"))
261  self.buttonLayoutMiddleCol.addWidget(getattr(self, name + "button"))
262  else:
263  self.buttonLayoutLeftCol.addWidget(getattr(self, name + "button"))
264  else:
265  layout.addWidget(getattr(self, name + "button"))
266 
267  def updatePlot(self):
268  self.plot(self.currently_selected, self.plotargs)
269 
270  def updateWindowTitle(self):
271  if np.shape(self.log.data[0,DID_DEV_INFO])[0] != 0:
272  info = self.log.data[0,DID_DEV_INFO][0]
273  infoStr = 'SN' + str(info[1]) + ', H:' + verArrayToString(info[2]) + ', F:' + verArrayToString(info[3]) + ' build ' + str(info[4]) + ', ' + dateTimeArrayToString(info[8], info[9]) + ', ' + info[10].decode('UTF-8')
274  self.setWindowTitle("LogInspector - " + infoStr)
275 
276  def choose_directory(self):
277  log_dir = config['logs_directory']
278  directory = QFileDialog.getExistingDirectory(parent=self, caption='Choose Log Directory', directory=log_dir)
279 
280  if directory != '':
281  try:
282  self.load(directory)
283  except Exception as e:
284  msg = QMessageBox()
285  msg.setIcon(QMessageBox.Critical)
286  msg.setText("Unable to load log: " + e.__str__())
287  msg.setDetailedText(traceback.format_exc())
288  msg.exec()
289 
290  def load(self, directory):
291  print("loading files from " + directory)
292  # if self.log is None:
293  self.log = Log()
294  self.log.load(directory)
295  print("done loading")
296  self.plotter = logPlot(False, False, 'svg', self.log)
297  self.plotter.setDownSample(self.downsample)
298  # str = ''
299  # if self.log.navMode:
300  # str += 'NAV '
301  # if self.log.rtk:
302  # str += 'RTK '
303  # if self.log.compassing:
304  # str += 'Comp '
305  # self.statusLabel.setText(str)
306  self.updatePlot()
307  self.updateWindowTitle()
308  self.stopLoadingIndicator()
309 
310  def setupUi(self):
311  self.setObjectName("LogInspector")
312  self.setWindowTitle("LogInspector")
313  self.resize(1280, 900)
314  self.setWindowFlags(self.windowFlags() |
315  QtCore.Qt.WindowSystemMenuHint |
316  QtCore.Qt.WindowMinMaxButtonsHint)
317  self.setWindowIcon(QIcon("assets/Magnifying_glass_icon.png"))
318 
319  # MainWindow.showMaximized()
320 
321  self.createFileTree()
322  self.createButtonColumn()
323  self.formatButtonColumn()
324  self.createBottomToolbar()
325 
326  self.figureLayout = QVBoxLayout()
327  self.figureLayout.addWidget(self.canvas)
328  self.figureLayout.addLayout(self.toolLayout)
329  self.figureLayout.setStretchFactor(self.canvas, 1)
330 
331  layout = QHBoxLayout()
332  layout.addLayout(self.controlLayout)
333  layout.addLayout(self.figureLayout)
334  layout.setStretch(1, 1)
335  widget = QWidget()
336  widget.setLayout(layout)
337  self.setCentralWidget(widget)
338  # self.resize(1280, 900)
339  self.resize(1450, 1000)
340  self.setAcceptDrops(True)
341 
343  self.controlLayout = QVBoxLayout()
344  self.buttonLayoutLeftCol = QVBoxLayout()
345  self.buttonLayoutMiddleCol = QVBoxLayout()
346  self.buttonLayoutRightCol = QVBoxLayout()
347  self.addButton('Pos NED Map', lambda: self.plot('posNEDMap'))
348  self.addButton('Pos NED', lambda: self.plot('posNED'))
349  self.addButton('Pos LLA', lambda: self.plot('posLLA'))
350  self.addButton('GPS LLA', lambda: self.plot('llaGps'))
351  self.addButton('Vel NED', lambda: self.plot('velNED'))
352  self.addButton('Vel UVW', lambda: self.plot('velUVW'))
353  self.addButton('Attitude', lambda: self.plot('attitude'))
354  self.addButton('Heading', lambda: self.plot('heading'))
355  self.addButton('INS Status', lambda: self.plot('insStatus'))
356  self.addButton('HDW Status', lambda: self.plot('hdwStatus'))
357  self.addButton('GPS 1 Stats', lambda: self.plot('gpsStats'))
358  self.addButton('GPS 2 Stats', lambda: self.plot('gps2Stats'))
359  self.addButton('RTK Pos Stats', lambda: self.plot('rtkPosStats'))
360  self.addButton('RTK Cmp Stats', lambda: self.plot('rtkCmpStats'))
361  self.addButton('Flash Config', lambda: self.showFlashConfig())
362  self.addButton('Device Info', lambda: self.showDeviceInfo())
363  self.addButton('IMU PQR', lambda: self.plot('imuPQR'))
364  self.addButton('IMU Accel', lambda: self.plot('imuAcc'))
365  self.addButton('IMU PSD', lambda: self.plot('imuPSD'))
366  self.addButton('Magnetometer', lambda: self.plot('magnetometer'))
367  self.addButton('Temp', lambda: self.plot('temp'))
368 
370  self.buttonLayoutLeftCol.setAlignment(QtCore.Qt.AlignTop)
371  self.buttonLayoutMiddleCol.setAlignment(QtCore.Qt.AlignTop)
372  self.buttonLayoutRightCol.setAlignment(QtCore.Qt.AlignTop)
373  self.buttonColumnLayout = QHBoxLayout()
374  self.buttonColumnLayout.addLayout(self.buttonLayoutLeftCol)
375  self.buttonColumnLayout.addLayout(self.buttonLayoutMiddleCol)
376  self.buttonColumnLayout.addLayout(self.buttonLayoutRightCol)
377  self.controlLayout.addLayout(self.buttonColumnLayout)
378  self.controlDirLayout = QHBoxLayout();
379  self.controlDirLayout.addWidget(self.dirLineEdit)
380  self.controlLayout.addLayout(self.controlDirLayout)
381  self.controlLayout.addWidget(self.fileTree)
382  # self.buttonLayout.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))
383  # self.addButton('load', self.choose_directory, multithreaded=False)
384 
385 
387  self.toolLayout = QHBoxLayout()
388  self.toolLayout.addWidget(self.toolbar)
389 
390  self.loadingIndictator = QLabel()
391  self.loadingMovie = QMovie('assets/loader.gif')
392  self.emptyLoadingPicture = QPicture()
393  self.emptyLoadingPicture.load('assets/empty_loader.png')
394  self.stopLoadingIndicator()
395  self.toolLayout.addWidget(self.loadingIndictator)
396 
397  self.toolLayout.addItem(QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))
398  # self.toolLayout.addWidget(QSpacerItem(150, 10, QSizePolicy.Expanding))
399 
400  self.copyImagePushButton = QPushButton()
401  # self.copyImagePushButton.setText("Copy")
402  # self.copyImagePushButton.setMinimumWidth(1)
403  # self.copyImagePushButton.style().standardIcon(QStyle.SP_DialogOpenButton)
404  self.copyImagePushButton.setIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton))
405  self.toolLayout.addWidget(self.copyImagePushButton)
406  self.copyImagePushButton.clicked.connect(self.copyPlotToClipboard)
407 
408  downsampleLabel = QLabel()
409  downsampleLabel.setText("DS")
410  self.downSampleInput = QSpinBox()
411  self.downSampleInput.setValue(self.downsample)
412  self.toolLayout.addWidget(downsampleLabel)
413  self.toolLayout.addWidget(self.downSampleInput)
414  self.downSampleInput.valueChanged.connect(self.changeDownSample)
415 
416  self.statusLabel = QLabel()
417  self.toolLayout.addWidget(self.statusLabel)
418 
419  def changeDownSample(self, val):
420  self.downsample = val
421  self.plotter.setDownSample(self.downsample)
422  self.updatePlot()
423 
425  # pixmap = QPixmap.grabWidget(self.canvas)
426  # QApplication.clipboard().setPixmap(pixmap)
427  # pixmap.save('test.png')
428 
429  # store the image in a buffer using savefig(), this has the
430  # advantage of applying all the default savefig parameters
431  # such as background color; those would be ignored if you simply
432  # grab the canvas using Qt
433  buf = io.BytesIO()
434  self.figure.savefig(buf)
435 
436  QApplication.clipboard().setImage(QImage.fromData(buf.getvalue()))
437  buf.close()
438 
440  self.loadingIndictator.setMovie(self.loadingMovie)
441  self.loadingMovie.start()
442 
443  def dragEnterEvent(self, e):
444  if (e.mimeData().hasUrls()):
445  e.acceptProposedAction()
446 
447 
448  def dropEvent(self, e):
449  try:
450  directory = e.mimeData().urls()[0].toLocalFile()
451  self.load(directory)
452  except Exception as e:
453  self.showError(e)
454 
455  def showError(self, e):
456  msg = QMessageBox()
457  msg.setIcon(QMessageBox.Critical)
458  msg.setText("Unable to load log: " + e.__str__())
459  msg.setDetailedText(traceback.format_exc())
460  msg.exec()
461 
462  def createFileTree(self):
463  self.dirModel = QFileSystemModel()
464  self.dirModel.setRootPath(self.config["logs_directory"])
465  self.dirModel.setFilter(QtCore.QDir.Dirs | QtCore.QDir.NoDotAndDotDot)
466  self.dirLineEdit = QLineEdit()
467  self.dirLineEdit.setText(self.config["logs_directory"])
468  self.dirLineEdit.setFixedHeight(25)
469  self.dirLineEdit.returnPressed.connect(self.handleTreeDirChange)
470  self.fileTree = QTreeView()
471  self.fileTree.setModel(self.dirModel)
472  self.fileTree.setRootIndex(self.dirModel.index(self.config['logs_directory']))
473  self.fileTree.setColumnHidden(1, True)
474  self.fileTree.setColumnHidden(2, True)
475  self.fileTree.setColumnHidden(3, True)
476  self.fileTree.setMinimumWidth(300)
477  self.fileTree.clicked.connect(self.handleTreeViewClick)
478  self.fileTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
479  self.fileTree.setSelectionMode(QAbstractItemView.SingleSelection)
480  self.fileTree.customContextMenuRequested.connect(self.handleTreeViewRightClick)
481  # self.populateRMSCheck(self.config['logs_directory'])
482 
483  def updateFileTree(self):
484  self.dirModel.setRootPath(self.config["logs_directory"])
485  self.fileTree.setRootIndex(self.dirModel.index(self.config['logs_directory']))
486 
487  def populateRMSCheck(self, directory):
488  for subdir in os.listdir(directory):
489  path = os.path.join(directory, subdir)
490  if os.path.isdir(path):
491  self.populateRMSCheck(path)
492  elif 'RMS' in subdir:
493  f = open(path)
494  rms_report = f.read()
495  p = re.compile(r'(?<=^PASS/FAIL).*\n', re.M)
496  line = re.search(p, rms_report).group()
497  failed = True if "FAIL" in line else False
498  if failed:
499  pass
500  else:
501  pass
502 
504  self.config["logs_directory"] = self.dirLineEdit.text()
505  self.updateFileTree()
506 
507  file = open(self.configFilePath, 'w')
508  yaml.dump(self.config, file)
509  file.close()
510 
512  selected_directory = self.fileTree.model().filePath(self.fileTree.selectedIndexes()[0])
513  for fname in os.listdir(selected_directory):
514  if fname.endswith('.dat'):
515  try:
516  self.load(selected_directory)
517  except Exception as e:
518  self.showError(e)
519  break
520 
521  def handleTreeViewRightClick(self, event):
522  selected_directory = os.path.normpath(self.fileTree.model().filePath(self.fileTree.selectedIndexes()[0]))
523  menu = QMenu(self)
524  copyAction = menu.addAction("Copy path")
525  nppActionHot = menu.addAction("Run NPP - Start Hot")
526  nppActionCold = menu.addAction("Run NPP - Start Cold")
527  nppActionFactory = menu.addAction("Run NPP - Start Factory")
528  setDataInfoDirAction = menu.addAction("Set as dataInfo.json directory")
529  openAction = menu.addAction("Open folder")
530  cleanFolderAction = menu.addAction("Clean folder")
531  deleteFolderAction = menu.addAction("Delete folder")
532  action = menu.exec_(self.fileTree.viewport().mapToGlobal(event))
533  if action == copyAction:
534  cb = QApplication.clipboard()
535  cb.clear(mode=cb.Clipboard )
536  cb.setText(selected_directory, mode=cb.Clipboard)
537  if action == nppActionHot:
538  cleanFolder(selected_directory)
539  setDataInformationDirectory(selected_directory, startMode=START_MODE_HOT)
540  from supernpp.supernpp import SuperNPP
541  spp = SuperNPP(selected_directory, self.config['serials'])
542  spp.run()
543  if action == nppActionCold:
544  cleanFolder(selected_directory)
545  setDataInformationDirectory(selected_directory, startMode=START_MODE_COLD)
546  from supernpp.supernpp import SuperNPP
547  spp = SuperNPP(selected_directory, self.config['serials'], startMode=START_MODE_COLD)
548  spp.run()
549  if action == nppActionFactory:
550  cleanFolder(selected_directory)
551  setDataInformationDirectory(selected_directory, startMode=START_MODE_FACTORY)
552  from supernpp.supernpp import SuperNPP
553  spp = SuperNPP(selected_directory, self.config['serials'], startMode=START_MODE_FACTORY)
554  spp.run()
555  if action == setDataInfoDirAction:
556  setDataInformationDirectory(selected_directory)
557  if action == openAction:
558  openFolderWithFileBrowser(selected_directory)
559  if action == cleanFolderAction:
560  cleanFolder(selected_directory)
561  if action == deleteFolderAction:
562  msg = QMessageBox(self)
563  msg.setIcon(QMessageBox.Question)
564  msg.setText("Are you sure you want to delete this folder?\n\n" + selected_directory)
565  msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
566  result = msg.exec()
567  if result == QMessageBox.Yes:
568  removeDirectory(selected_directory)
569 
571  self.loadingMovie.stop()
572  self.loadingIndictator.clear()
573  self.loadingIndictator.setPicture(self.emptyLoadingPicture)
574 
575  def showDeviceInfo(self):
576  dlg = DeviceInfoDialog(self.log, self)
577  dlg.show()
578  dlg.exec_()
579 
580  def showFlashConfig(self):
581  dlg = FlashConfigDialog(self.log, self)
582  dlg.show()
583  dlg.exec_()
584 
585 
586  def plot(self, func, args=None):
587  print("plotting " + func)
588  self.currently_selected = func
589  self.plotargs = args
590 
591  self.figure.clear()
592 
593  if hasattr(self, 'plotter'):
594  if args is not None:
595  getattr(self.plotter, func)(*args, self.figure)
596  else:
597  getattr(self.plotter, func)(self.figure)
598 
599  self.canvas.draw()
600  self.stopLoadingIndicator()
601  print("done plotting")
602 
603 if __name__ == '__main__':
604  app = QApplication(sys.argv)
605  MainWindow = QMainWindow()
606 
607  configFilePath = os.path.join(os.path.expanduser("~"), "Documents", "Inertial_Sense", "config.yaml")
608 
609  main = LogInspectorWindow(configFilePath, MainWindow)
610  main.setupUi()
611  # main.load(directory)
612  main.show()
613 
614  if len(sys.argv) > 1:
615  directory = sys.argv[1]
616  main.load(directory)
617 
618  app.exec_()
def dateTimeArrayToString(date, time)
size_t count(InputIterator first, InputIterator last, T const &item)
Definition: catch.hpp:3206
def cleanFolder(path, toplevel=True)
Definition: logInspector.py:45
GeneratorWrapper< T > range(T const &start, T const &end, T const &step)
Definition: catch.hpp:4141
def setDataInformationDirectory(path, startMode=START_MODE_HOT)
Definition: logInspector.py:80
def __init__(self, configFilePath, parent=None)
def addButton(self, name, function, multithreaded=True, layout=None)


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04