class Listener(QWidget): def __init__(self, core_file_name): super(Listener, self).__init__() self.core_file_name = core_file_name self.setup_ui() self.setup_timers() port = SERIAL_PORT self.serial = serial.Serial(port, BAUDE_RATE, timeout=0) self.incoming_data = [] self.imu = IMU(PLATFORM_SPECIFIC_QUOTIENTS['stm']) self.stroke = Stroke() self.selector = Selector(self.core_file_name) self.acceleration_filter = AperiodicFilter(ACCELERATION_TIME_CONST) self.stroke.widget = self.display self.stroke.on_done = self.get_stroke self.previous_time = None self.data_buffer = '' self.init_selector() def setup_ui(self): self.resize(500, 500) self.out = QLabel(self) self.out.setMinimumHeight(100) font = QFont() font.setPixelSize(80) self.out.setFont(font) self.grid = QGridLayout(self) self.display = StrokeWidget() self.letter_selector = QComboBox() self.grid.addWidget(self.display, 0, 0, 1, 1) self.grid.addWidget(self.letter_selector, 1, 0, 1, 1) self.grid.addWidget(self.out, 2, 0, 1, 1) def setup_timers(self): self.serial_timer = QTimer() self.serial_timer.setInterval(SERIAL_INTERVAL) self.serial_timer.timeout.connect(self.get_data) self.serial_timer.start() self.process_timer = QTimer() self.process_timer.setInterval(PROCESS_INTERVAL) self.process_timer.timeout.connect(self.process) self.process_timer.start() self.display_timer = QTimer() self.display_timer.setInterval(DISPLAY_TIMEOUT) self.display_timer.setSingleShot(True) self.display_timer.timeout.connect(self.set_background) def init_selector(self): sel_lines = self.selector.letters_dict.keys() sel_lines.insert(0, 'new strokes') sel_lines.insert(0, 'free run') self.letter_selector.addItems(sel_lines) self.letter_selector.currentIndexChanged.connect(self.set_background) def set_background(self): letter = str(self.letter_selector.currentText()) self.display.set_background(self.core_file_name, letter) def store_stroke(self, key, stroke, existing=True): file_name = '{key}{time}.txt'.format(key=key, time=int(time())) file_path = os.path.join(LEARNED_FOLDER, file_name) np.savetxt(file_path, stroke) if existing: self.display.set_background(self.core_file_name, key, color='g') self.display_timer.start() def get_stroke(self, data): stroke = data['stroke'] dimention = data['dimention'] if dimention < MIN_DIMENTION: print 'too small' return letter = str(self.letter_selector.currentText()) if letter == 'new strokes': self.store_stroke('_', stroke, existing=False) print 'recorded' try: letters = self.selector.check_stroke(stroke) except: #TODO: check unify_stroke return if letters: self.out.setText(self.out.text()+letters[0]) if letter == 'free run' and letters: self.store_stroke(letters[0], stroke) elif letter in letters: self.store_stroke(letter, stroke) def process(self): local_data_storage = deepcopy(self.incoming_data) self.incoming_data = [] for data in local_data_storage: if self.previous_time is None: self.previous_time = data[0] continue data[0], self.previous_time = data[0] - self.previous_time, data[0] if data[0] < MAX_DATA_TIMELAPSE: self.imu.calc(data) gyro = np.linalg.norm(np.array([data[7:]])) accel = self.imu.get_global_acceleration() accel = self.acceleration_filter.set_input(accel, data[0]) accel_magnitude = np.linalg.norm(accel) if accel_magnitude > ACCELERATION_RESET: self.execute_spell() Yr = self.imu.get_y_direction() self.stroke.set_data(Yr, gyro) self.stroke.process_size(data[0], accel) self.setVisible(not self.imu.in_calibration) def execute_spell(self): self.out.setText('') def get_data(self): try: self.data_buffer += self.serial.read(self.serial.inWaiting()) if self.data_buffer == '': return data_pieces = self.data_buffer.split(BUFFER_DELIMITER) # Put incomplete piece back to the buffer self.data_buffer = data_pieces.pop(-1) # If there are no complete data pieces - return from function if not data_pieces: return # Else - get the last of the pieces and discard the rest line = data_pieces[-1] result = [float(d) for d in line.split()] if len(result) != 9: raise ValueError('Nine pieces of data should be provided.') new_line = [time()] + result self.incoming_data.append(new_line) except KeyboardInterrupt: raise except Exception as e: # Something went wrong... nobody cares. print e