def setupLive(self, firingLength): logger.log('Set up results view for live receiving. Max size: {}'.format(firingLength)) self.liveMode = True self.ui.groupBoxRecvResults.setVisible(True) self.ui.progressBarReceived.setMaximum(firingLength) self.ui.progressBarReceived.setValue(0) self.ui.widgetDataAge.start()
def setup(self, data): self.raw = {'time': [], 'force': [], 'pressure': []} rawFrames = [] minTime = 0 # Cut the data up into frames of the correct size for start in range(0, len(data), 16): rawFrames.append(data[start:start + 16]) logger.log('Frames: {}'.format(len(rawFrames))) # Separate the frames into time, force, and pressure for frame in rawFrames: # Account for (16 bit) time looping around t = minTime + int(frame[0:2], 16) + (256 * int(frame[2:4], 16)) if len(self.raw['time']) > 0 and t < self.raw['time'][-1]: minTime += 2**16 t += 2**16 self.raw['time'].append(t) self.raw['force'].append( int(frame[4:6], 16) + (int(frame[6:8], 16) << 8) + (int(frame[8:10], 16) << 16)) self.raw['pressure'].append( int(frame[10:12], 16) + (int(frame[12:14], 16) << 8) + (int(frame[14:16], 16) << 16)) self.ui.widgetTransducerSelector.reset() self.ui.motorData.setPreferences( QApplication.instance().getPreferences()) self.ui.motorData.loadProperties(MotorConfig({'cutoffThreshold': 5}))
def processRawData(self): path = QFileDialog.getOpenFileName(None, 'Load Raw Data', '', 'Raw Firing Data File (*.MFL)')[0] if path != '': logger.log('Loading raw data from "{}"'.format(path)) with open(path, 'rb') as fileData: self.showRawData.emit(binascii.hexlify(fileData.read()))
def _process_image(self, filename, label): image_string = tensorflow.read_file(filename) image_decoded = tensorflow.image.decode_jpeg(image_string, channels=3) logger.log("TRank", str(tensorflow.rank(image_decoded))) image_resized = tensorflow.image.resize_images(image_decoded, [self.x, self.y]) # Parameterize the size result = tensorflow.cast(image_resized, tensorflow.float64)/255.0 return result, label
def saveDatasheet(self): path = QFileDialog.getSaveFileName(None, 'Save Motor Datasheet', '', 'Portable Network Graphic Files (*.png);;Portable Document Format Files (*.pdf)')[0] if path is None or path == '': return if not path.endswith('.png') and not path.endswith('.pdf'): path += '.png' logger.log('Saving datasheet to "{}"'.format(path)) app = QApplication.instance() saveDatasheet(self.motorData, path, app.convertToUserAndFormat, app.convertAllToUserUnits, app.getUserUnit)
def fireButtonPressed(self): if self.firing is None: logger.error('Tried to fire without a firing!') return if not self.checkFireButtonEnabled(): # The UI should prevent this from happening, but this will catch it if that doesn't work logger.warn('Fire button pressed while not enabled!') return logger.log('Fire button pressed') self.firing.fire()
def stopButtonPressed(self): if self.firing is None: logger.error("Tried to stop without a firing!") return if not self.checkStopButtonEnabled(): # The UI should prevent this from happening, but this will catch it if that doesn't work logger.warn('Stop button pressed while not enabled!') return logger.log('Stop button pressed') self.toggleFields(self.firingFields, False) self.emptyFiringControls() self.firing.stop()
def newInfo(self, properties): if properties['type'] == 'Load Cell': self.baseUnit = 'N' field = 'Force' else: self.baseUnit = 'Pa' field = 'Pressure' logger.log('Set base unit to "{}"'.format(self.baseUnit)) self.ui.tableWidgetPoints.setHorizontalHeaderLabels([ 'Raw', '{} ({})'.format(field, self.app.getUserUnit(self.baseUnit)) ]) self.ui.widgetGraph.setUnit(field, self.baseUnit)
def __init__(self, args): super().__init__(args) self.setupFileIO() self.sensorProfileManager = SensorProfileManager() self.sensorProfileManager.loadProfiles() self.preferencesManager = PreferencesManager() self.preferencesManager.loadPreferences() logger.log('Application version: {}.{}.{}'.format(*self.VERSION)) self.window = MainWindow(self) logger.log('Showing window') self.window.show()
def cellChanged(self, row, col): if not self.clearing and col == 1: value = self.ui.tableWidgetPoints.item(row, col).text() try: conv = QApplication.instance().convertFromUserUnits( float(value), self.baseUnit) self.calibration.setReal(row, conv) except ValueError: logger.log( 'Invalid value "{}" entered to cell ({}, {})'.format( value, row, col)) self.ui.tableWidgetPoints.clearSelection() self.ui.pushButtonCapture.setFocus()
def call(self, inputs): logger.log(logger.CYAN + "Model Called" + logger.RESET, "") tensors = [] idx = 0 logger.log(logger.CYAN + "Model Called" + logger.RESET, "Layers Executed. Now doing final layer") result = self.lyr["lyr"][0](inputs) for i in range(1, len(self.lyr["lyr"])): result = self.lyr["lyr"][i](result) return result
def getResult(self, x, y, p, images): for t in self.parallelLayers: for i in self.parallelLayers[t]: try: img = i.call( images) #self.get_layer(index=i).call(images[0:20]) pyplot.subplot(x, y, p) pyplot.imshow(img[0]) logger.log("Model[" + str(t) + "]", str(logger.GREEN + "RENDER" + logger.RESET)) except Exception as e: logger.log("Model[" + str(t) + "]", str(logger.RED + str(e) + logger.RESET)) p += 1 p += 1 for t in self.lyr: for i in self.lyr[t]: try: img = i.call( images) #self.get_layer(index=i).call(images[0:20]) pyplot.subplot(x, y, p) pyplot.imshow(img[0]) logger.log("Model[" + str(t) + "]", str(logger.GREEN + "RENDER" + logger.RESET)) except Exception as e: logger.log("Model[" + str(t) + "]", str(logger.RED + str(e) + logger.RESET)) p += 1 p += 1
def saveFIRE(self): path = QFileDialog.getSaveFileName(None, 'Save FIRE', '', 'Firing Data File (*.fire)')[0] if path is None or path == '': return if not path.endswith('.fire'): path += '.fire' logger.log('Saving firing to {}'.format(path)) try: fileIO.save(FILE_TYPES.FIRING, self.motorData.toDictionary(), path) self.ui.labelFileName.setText(os.path.basename(path)) self.saved = True except Exception as err: logger.log('Failed to save firing data, err: {}'.format(repr(err))) QApplication.instance().outputException(err, 'Error saving file:')
def saveRawCSV(self): path = QFileDialog.getSaveFileName(None, 'Save Raw CSV', '', 'Comma Separated Values (*.csv)')[0] if path is None or path == '': return if not path.endswith('.csv'): path += '.csv' data = self.motorData.getRawCSV() logger.log('Saving raw CSV to {}'.format(path)) try: with open(path, 'w') as outFile: outFile.write(data) except Exception as err: logger.log('Failed to save firing data, err: {}'.format(repr(err))) QApplication.instance().outputException(err, 'Error saving file:')
def recordError(self, packet): newError = False for error in packet.getErrors(): if error not in self.errors: self.errors.append(error) newError = True if newError: logger.log('Got an error packet with details ({})'.format(packet)) output = "The RMTS board reported the following error(s):\n\n" output += "\n".join(self.errors) output += "\n\n Please resolve them and restart the device before continuing." QApplication.instance().outputMessage(output) self.newError.emit() if len(self.errors) > 0: self.hasError.emit()
def closeEvent(self, event=None): if (not self.ui.pageFire.exitCheck() or not self.ui.pageResults.unsavedCheck() or not self.ui.pageCalibration.unsavedCheck()): logger.log('Canceling close event') if event is not None and not isinstance(event, bool): event.ignore() return self.closed.emit() self.ui.pageFire.exit() self.ui.pageRecvResults.exit() self.ui.pageCalibrationSetup.exit() self.ui.pageAbout.exit() logger.log('Application exited') sys.exit()
def on_epoch_end(self, epoch, logs={}): global OLD_LOSS, OLD_ACC, OLD_VLOSS, OLD_VACC, LOSS_DELTA, ACC_DELTA global NPOS newLossDelta = OLD_LOSS - logs["loss"] newAccDelta = OLD_ACC - logs["accuracy"] lossDeltaPercentage = newLossDelta / LOSS_DELTA l1 = logger.YELLOW if (OLD_LOSS == logs["loss"]) else logger.GREEN if ( OLD_LOSS > logs["loss"]) else logger.RED l2 = logger.YELLOW if (OLD_ACC == logs["accuracy"]) else logger.GREEN if ( OLD_ACC < logs["accuracy"]) else logger.RED l3 = logger.YELLOW if ( OLD_VLOSS == logs["val_loss"]) else logger.GREEN if ( OLD_VLOSS > logs["val_loss"]) else logger.RED l4 = logger.YELLOW if ( OLD_VACC == logs["val_accuracy"]) else logger.GREEN if ( OLD_VACC < logs["val_accuracy"]) else logger.RED l5 = logger.YELLOW if ( lossDeltaPercentage == 1.0) else logger.CYAN if ( (lossDeltaPercentage > 1.2) or (lossDeltaPercentage < 0.8)) else logger.GREEN # logger.log(str(epoch), str("Loss: " + l1 + str(logs["loss"]).ljust(25) + logger.RESET + " Accuracy: " + l2 + str(logs["accuracy"]).ljust(15) + logger.RESET + " Val_Loss: " + l3 + str(logs["val_loss"]).ljust(25) + logger.RESET + " Val_Accuracy: " + l4 + str(logs["val_accuracy"]).ljust(15) + logger.RESET)) logger.log( logger.CYAN + str(epoch) + logger.RESET, str(", " + l1 + str(logs["loss"]) + logger.RESET + ", " + l2 + str(logs["accuracy"]) + logger.RESET + ", " + l3 + str(logs["val_loss"]) + logger.RESET + ", " + l4 + str(logs["val_accuracy"]) + logger.RESET) + ", " + l5 + str(lossDeltaPercentage) + logger.RESET) if (epoch % (EPOCHS / 10) == 0): prediction = model.predict(predictImages, steps=42) pyplot.subplot(4, 8, NPOS) pyplot.imshow(prediction[0]) NPOS += 1 LOSS_DELTA = newLossDelta ACC_DELTA = newAccDelta OLD_LOSS = logs["loss"] OLD_ACC = logs["accuracy"] OLD_VLOSS = logs["val_loss"] OLD_VACC = logs["val_accuracy"]
def on_epoch_end(self, epoch, logs={}): global OLD_LOSS, OLD_ACC, OLD_VLOSS, OLD_VACC, LOSS_DELTA, ACC_DELTA global NPOS newLossDelta = OLD_LOSS - logs["loss"] newAccDelta = OLD_ACC - logs["accuracy"] if (LOSS_DELTA == 0): lossDeltaPercentage = 0 else: lossDeltaPercentage = newLossDelta / LOSS_DELTA l1 = logger.YELLOW if (OLD_LOSS == logs["loss"]) else logger.GREEN if ( OLD_LOSS > logs["loss"]) else logger.RED l2 = logger.YELLOW if (OLD_ACC == logs["accuracy"]) else logger.GREEN if ( OLD_ACC < logs["accuracy"]) else logger.RED l3 = logger.YELLOW if ( OLD_VLOSS == logs["val_loss"]) else logger.GREEN if ( OLD_VLOSS > logs["val_loss"]) else logger.RED l4 = logger.YELLOW if ( OLD_VACC == logs["val_accuracy"]) else logger.GREEN if ( OLD_VACC < logs["val_accuracy"]) else logger.RED l5 = logger.YELLOW if ( lossDeltaPercentage == 1.0) else logger.CYAN if ( (lossDeltaPercentage > 1.2) or (lossDeltaPercentage < 0.8)) else logger.GREEN # logger.log(str(epoch), str("Loss: " + l1 + str(logs["loss"]).ljust(25) + logger.RESET + " Accuracy: " + l2 + str(logs["accuracy"]).ljust(15) + logger.RESET + " Val_Loss: " + l3 + str(logs["val_loss"]).ljust(25) + logger.RESET + " Val_Accuracy: " + l4 + str(logs["val_accuracy"]).ljust(15) + logger.RESET)) logger.log( logger.CYAN + str(epoch) + logger.RESET, str(", " + l1 + str(logs["loss"]) + logger.RESET + ", " + l2 + str(logs["accuracy"]) + logger.RESET + ", " + l3 + str(logs["val_loss"]) + logger.RESET + ", " + l4 + str(logs["val_accuracy"]) + logger.RESET) + ", " + l5 + str(lossDeltaPercentage) + logger.RESET) LOSS_DELTA = newLossDelta ACC_DELTA = newAccDelta OLD_LOSS = logs["loss"] OLD_ACC = logs["accuracy"] OLD_VLOSS = logs["val_loss"] OLD_VACC = logs["val_accuracy"]
def unsavedCheck(self): if self.calibration is None or len(self.calibration.points) == 0: return True msg = QMessageBox() msg.setText("The calibration has not been saved. Close anyway?") msg.setWindowTitle("Close without saving?") msg.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) res = msg.exec_() if res == QMessageBox.Discard: logger.log('User chose to discard results') return True if res == QMessageBox.Save: logger.log('User chose to save first') self.save() return True return False
def call(self, inputs): logger.log(logger.CYAN + "Model Called" + logger.RESET, "") tensors = [] idx = 0 for t in self.parallelLayers: tensors.append(self.parallelLayers[t][0](inputs)) for i in range(1, len(self.parallelLayers[t])): tensors[idx] = self.parallelLayers[t][i](tensors[idx]) idx += 1 combined = tensorflow.concat(tensors, 3) logger.log(logger.CYAN + "Model Called" + logger.RESET, "Layers Executed. Now doing final layer") result = self.lyr["lyr"][0](combined) for i in range(1, len(self.lyr["lyr"])): result = self.lyr["lyr"][i](result) return result
def nextPressed(self): forceConv, pressConv = self.ui.widgetTransducerSelector.getConverters() if forceConv == None and pressConv == None: QApplication.instance().outputMessage( 'At least one transducer must be used.') logger.log('Both transducers set to "None", cancelling') return # TODO: Validate motor data object try: motorData = MotorConfig() motorData.setProperties(self.ui.motorData.getProperties()) motor = processRawData(self.raw, forceConv, pressConv, motorData) QApplication.instance().newResult(motor) self.nextPage.emit() except Exception as err: QApplication.instance().outputException(err, 'Could not load motor') logger.error('Could not load motor. Error: {}'.format( format_exc()))
def showSavedResultsPressed(self): path = QFileDialog.getOpenFileName(None, 'Load FIRE', '', 'Firing Data File (*.fire)')[0] if path != '': try: data = fileIO.load(FILE_TYPES.FIRING, path) except Exception as err: logger.log('Failed to load firing, err: {}'.format(repr(err))) QApplication.instance().outputException( err, 'Error loading file:') return try: motor = processRawData( data['rawData'], None if data['forceConv'] is None else Converter(data['forceConv']), None if data['pressureConv'] is None else Converter( data['pressureConv']), FiringConfig(data['motorInfo'])) except Exception as err: logger.log('Failed to process firing, err: {}'.format( repr(err))) QApplication.instance().outputException( err, 'Error loading file:') return logger.log('Loaded saved firing data from "{}"'.format(path)) QApplication.instance().newResult(motor, os.path.basename(path)) self.showResultsPage.emit()
def _buildDataSet(self): labelset = {} files = {} labelArray = [] resultNormalArray = [] imgset = [] for r, d, f in os.walk(self.path): logger.log(logger.MAGENTA + "READING FILES" + logger.RESET, str(r)) for file in f: if '.png' in file: logger.log(logger.GREEN + "FILE" + logger.RESET, str(file)) path = os.path.join(r, file) if(file[0:3] == "SRC"): img = matplotlib.image.imread(path) imgset.append(img) elif(file[0:3] == "TAR"): labelArray.append(matplotlib.image.imread(path)) else: pass imgsetNPARR = numpy.asarray(imgset) labelsetNPARR = numpy.asarray(labelArray) pos = self.path.rfind('\\') + 1 labelGroup = self.path[pos:] numpy.save('data\\' + labelGroup + '_images', imgsetNPARR) numpy.save('data\\' + labelGroup + '_labels', labelsetNPARR) # Map labelset with resultNormalArray images_tensor = tensorflow.convert_to_tensor(imgsetNPARR) labels_tensor = tensorflow.convert_to_tensor(labelsetNPARR) ## USE INTEGER self.setDataSet(images_tensor, labels_tensor) label_names = sorted(list(labelset)) label_to_index = dict((index, name) for name, index in enumerate(label_names)) return images_tensor, labels_tensor
def connect(self): self.forceConv, self.pressConv = self.ui.widgetTransducerSelector.getConverters( ) if self.forceConv == None and self.pressConv == None: QApplication.instance().outputMessage( 'At least one transducer must be used.') logger.log('Both transducers set to "None", cancelling') return port = self.ui.widgetPortSelector.getPort() motorConfig = MotorConfig() motorConfig.setProperties(self.ui.widgetMotorConfig.getProperties()) self.ui.pushButtonConnect.setEnabled(False) self.firing = Firing(self.forceConv, self.pressConv, motorConfig, port) self.firing.newGraph.connect(QApplication.instance().newResult) self.firing.fullSizeKnown.connect(self.gotoResults) self.firing.newResultsPacket.connect( QApplication.instance().newResultsPacket) self.firing.initialResultsTime.connect(self.initialResultsTime)
def exportENG(self, config): title = 'Save ENG' formats = 'RASP ENG File (*.eng)' if config['append'] == 'Append': mode = 'a' path = QFileDialog.getSaveFileName(None, title, '', formats, options=QFileDialog.DontConfirmOverwrite)[0] else: mode = 'w' path = QFileDialog.getSaveFileName(None, title, '', formats)[0] if path is None or path == '': return if not path.endswith('.eng'): path += '.eng' logger.log('Saving ENG to {} (Mode={})'.format(path, config['append'])) with open(path, mode) as outFile: propMass = self.motorData.getPropMass() contents = ' '.join([config['designation'], str(round(config['diameter'] * 1000, 6)), str(round(config['length'] * 1000, 6)), 'P', str(round(propMass, 6)), str(round(config['totalMass'], 6)), config['manufacturer'] ]) + '\n' timeData = self.motorData.getTime() forceData = self.motorData.getForce() # Add on a 0-thrust datapoint right after the burn to satisfy RAS Aero if forceData[-1] != 0: timeData.append(timeData[-1] + 0.01) forceData.append(0) for time, force in zip(timeData, forceData): if time == 0 and force == 0: # Increase the first point so it isn't 0 thrust force += 0.01 contents += str(round(time, 4)) + ' ' + str(round(force, 4)) + '\n' contents += ';\n;\n' outFile.write(contents)
def connect(self): logger.log('Connect clicked, setting up firing') port = self.ui.widgetPortSelector.getPort() self.forceConv, self.pressConv = self.ui.widgetTransducerSelector.getConverters( ) if self.forceConv == None and self.pressConv == None: QApplication.instance().outputMessage( 'At least one transducer must be used.') logger.log('Both transducers set to "None", canceling') return forceConvName = 'None' if self.forceConv is not None: forceConvName = self.forceConv.getProperty('name') pressureConvName = 'None' if self.pressConv is not None: pressureConvName = self.pressConv.getProperty('name') logger.log('Using LC profile: "{}", PT: "{}"'.format( forceConvName, pressureConvName)) fireData = FiringConfig() fireData.setProperties(self.ui.firingConfig.getProperties()) logger.log('Firing properties: {}'.format(fireData.getProperties())) self.firing = Firing(self.forceConv, self.pressConv, fireData, port) self.firing.newSetupPacket.connect(self.newSetupPacket) self.firing.newErrorPacket.connect(self.errorCollector.recordError) self.firing.newFiringPacket.connect(self.newFiringPacket) self.firing.fullSizeKnown.connect(self.gotoResults) self.firing.newResultsPacket.connect( QApplication.instance().newResultsPacket) self.firing.newGraph.connect(QApplication.instance().newResult) self.firing.stopped.connect( lambda: self.toggleFields(self.resultsFields, True)) self.firing.initialResultsTime.connect(self.initialResultsTime) self.ui.widgetDataAge.start() self.firing.newSetupPacket.connect(self.ui.widgetDataAge.reset) self.firing.newErrorPacket.connect(self.ui.widgetDataAge.reset) self.firing.newFiringPacket.connect(self.ui.widgetDataAge.reset) self.toggleFields(self.setupFields, False) self.toggleFields(self.firingFields, True)
def exitCheck(self): if self.firing is None or self.firing.onResultsView: return True logger.log('Checking if user really wants to exit firing widget') msg = QMessageBox() msg.setText("The radio is currently connected. Close anyway?") msg.setWindowTitle("Close while connected?") msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) res = msg.exec_() if res == QMessageBox.Yes: logger.log('User chose to close') return True if res == QMessageBox.No: logger.log('User chose to stay on page') return False return False
def unsavedCheck(self): if not self.liveMode or self.saved: return True logger.log('Checking if user wants to save before exiting results widget') msg = QMessageBox() msg.setText("The received results have not been saved. Close anyway?") msg.setWindowTitle("Close without saving?") msg.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) res = msg.exec_() if res == QMessageBox.Discard: logger.log('User chose to discard results') return True if res == QMessageBox.Save: logger.log('User chose to save first') self.saveFIRE() return self.saved return False
def newSetupPacket(self, packet): if self.tared: if self.forceConv is not None: realForce = self.forceConv.convert( self.forceBuff.addData( packet.force)) - self.tareOffsetForce self.ui.lineEditForce.setText( QApplication.instance().convertToUserAndFormat( realForce, 'N', 1)) else: self.ui.lineEditForce.setText('N/A') if self.pressConv is not None: realPressure = self.pressConv.convert( self.pressureBuff.addData( packet.pressure)) - self.tareOffsetPressure self.ui.lineEditPressure.setText( QApplication.instance().convertToUserAndFormat( realPressure, 'Pa', 1)) else: self.ui.lineEditPressure.setText('N/A') else: self.tareDataForce.append(packet.force) self.tareDataPressure.append(packet.pressure) if len(self.tareDataForce) == 10: logger.log('Tare complete') self.tared = True if self.forceConv is not None: tareAvgForce = sum(self.tareDataForce) / len( self.tareDataForce) self.tareOffsetForce = self.forceConv.convert(tareAvgForce) logger.log( '\tForce offset = ({:.4f} conv, {:.4f} raw)'.format( self.tareOffsetForce, tareAvgForce)) if self.pressConv is not None: tareAvgPressure = sum(self.tareDataPressure) / len( self.tareDataPressure) self.tareOffsetPressure = self.pressConv.convert( tareAvgPressure) logger.log( '\tPressure offset = ({:.4f} conv, {:.4f} raw)'.format( self.tareOffsetPressure, tareAvgPressure)) self.ui.lineEditContinuity.setText( "Yes" if packet.continuity else "No")
def saveENG(self): logger.log('Showing ENG exporter') self.engExporter.show()