Esempio n. 1
0
    def __init__(self, parent=None):
        self.parent = parent
        self.fs = main_config['fs']
        self.n_channels = main_config['n_channels']
        self.t0 = 0
        self.last_ts = 0

        # Game log reader (separate thread)
        self.game_logs_path = game_config['game_logs_path']
        self.game_log_reader = None
        self._expected_action = (0, 'Rest')
        self.thread_log = QtCore.QThreadPool()

        # Game window (separate process)
        clean_log_directory(self.game_logs_path)
        self.game = None

        # Port event sender
        self.micro_path = main_config['micro_path']
        self.port_sender = None

        # Game player
        self.game_path = game_config['game_path']
        self.player_idx = game_config['player_idx']
        self.game_start_time = None

        # Chronogram
        self.chrono_source = ColumnDataSource(dict(ts=[],
                                                   y_true=[],
                                                   y_pred=[]))
        self.pred_decoding = main_config['pred_decoding']

        # LSL stream reader
        self.lsl_reader = None
        self.lsl_start_time = None
        self.thread_lsl = QtCore.QThreadPool()
        self.channel_source = ColumnDataSource(dict(ts=[], eeg=[]))
        self._lsl_data = (None, None)

        # LSL stream recorder
        if not os.path.isdir(main_config['record_path']):
            os.mkdir(main_config['record_path'])
        self.record_path = main_config['record_path']
        self.record_name = game_config['record_name']
        self.lsl_recorder = None

        # Predictor
        self.models_path = main_config['models_path']
        self.input_signal = np.zeros((self.n_channels, 4 * self.fs))
        self.predictor = None
        self.thread_pred = QtCore.QThreadPool()
        self._pred_action = (0, 'Rest')
Esempio n. 2
0
    def __init__(self, files, pxSize, crop, gaussSigma, intThres, cArgs):
        super().__init__()

        self.files = files
        self.pxSize = pxSize
        self.crop = crop
        self.gaussSigma = gaussSigma / self.pxSize
        self.intThres = intThres
        self.cArgs = cArgs

        self.pool = QtCore.QThreadPool()
        self.pool.setMaxThreadCount(1)

        self.nfiles = len(files)
        self.subimgPxSize = 1000 / self.pxSize

        # Get data shape and derivates
        im = Image.open(self.files[0])
        inputData = np.array(im).astype(np.float64)
        initShape = inputData.shape
        self.bound = (np.array(inputData.shape) - self.crop).astype(np.int)
        inputData = inputData[self.crop:self.bound[0], self.crop:self.bound[1]]
        dataShape = inputData.shape
        self.n = (np.array(dataShape) / self.subimgPxSize).astype(int)
        self.mag = np.array(dataShape) / self.n
        self.corrArray = np.zeros((self.nfiles, self.n[0], self.n[1]))
        self.path = os.path.split(self.files[0])[0]
        self.corrExp = np.empty((self.nfiles, initShape[0], initShape[1]),
                                dtype=np.single)
        self.corrExp[:] = np.nan
        self.ringsExp = np.empty((self.nfiles, initShape[0], initShape[1]),
                                 dtype=np.single)
        self.ringsExp[:] = np.nan
Esempio n. 3
0
    def __init__(self, *args, **kwargs):
        super(Sim, self).__init__()
        self.cp = get_cmap('inferno')
        self.cam = cv2.VideoCapture(0)
        self.win = pg.GraphicsLayoutWidget()
        self.win.show()
        self.view = self.win.addViewBox()
        ret, frame = self.cam.read()
        self.view.setAspectLocked(True)

        self.img = pg.ImageItem(border='w')
        self.view.addItem(self.img)

        self.view.setRange(QtCore.QRectF(0, 0, 640, 480))

        self.threadpool = QtCore.QThreadPool()
        self.threadpool.setMaxThreadCount(2)  #n of threads running
        ##modify when add the marker feature

        self.loc = [2, 2]

        self.cam_frame = np.zeros([480, 640, 3]).astype(np.uint8)
        self.roach_frame = np.zeros([480, 640, 3]).astype(np.uint8)
        self.superposition = np.zeros([480, 640, 3]).astype(np.uint8)
        self.Update()
Esempio n. 4
0
    def __init__(self, parent=None):
        self.parent = parent
        self.fs = main_config['fs']
        self.n_channels = main_config['n_channels']
        self.t0 = 0
        self.last_ts = 0
        self.game_is_on = False

        # Chronogram
        self.chrono_source = ColumnDataSource(dict(ts=[], y_pred=[]))
        self.pred_decoding = main_config['pred_decoding']

        # LSL stream reader
        self.lsl_reader = None
        self.lsl_start_time = None
        self._lsl_data = (None, None)
        self.thread_lsl = QtCore.QThreadPool()
        self.channel_source = ColumnDataSource(dict(ts=[], eeg=[]))
        self.buffer_size_s = 10

        # LSL stream recorder
        if not os.path.isdir(main_config['record_path']):
            os.mkdir(main_config['record_path'])
        self.record_path = main_config['record_path']
        self.record_name = warmup_config['record_name']
        self.lsl_recorder = None

        # Predictor
        self.models_path = main_config['models_path']
        self.input_signal = np.zeros((self.n_channels, 4 * self.fs))
        self.predictor = None
        self.thread_pred = QtCore.QThreadPool()
        self._pred_action = (0, 'Rest')

        # Feedback images
        self.static_folder = warmup_config['static_folder']
        self.action2image = warmup_config['action2image']
Esempio n. 5
0
 def __init__(self, player_idx):
     # Send commands using a separate thread
     self.thread_game = QtCore.QThreadPool()
Esempio n. 6
0
    def __init__(self, *args, **kwargs):
        super(SensorApplication, self).__init__(*args, **kwargs)

        # logger properties setup
        self.folder_name = "logs/"
        traces_name = self.folder_name + dt.datetime.now().strftime(
            "%d-%m-%Y %Hh%Mm%Ss")
        self.cvs_name = traces_name + ".csv"
        self.logfile_name = traces_name + ".txt"
        os.makedirs(os.path.dirname(self.logfile_name), exist_ok=True)
        logging.basicConfig(filename=self.logfile_name,
                            level=logging.DEBUG,
                            datefmt="%H:%M:%S",
                            format=LOG_FORMAT)
        self.logger1 = logging.getLogger('RawData')
        self.logger2 = logging.getLogger('ProgFlow')

        # Thread poll for getting serial line
        self.thread_pool = QtCore.QThreadPool()
        self.thread_pool.setMaxThreadCount(20)
        self.logger2.info("Multithreading with maximum %d threads" %
                          self.thread_pool.maxThreadCount())

        # Serial properties setup
        self.serial_dev = serial.Serial()
        self.serial_dev.port = 'COM4'
        self.serial_dev.baudrate = 115200
        self.serial_dev.timeout = 2

        # graphic properties setup
        self.win = QtGui.QMainWindow()
        self.area = DockArea()
        self.win.setCentralWidget(self.area)
        self.win.resize(1200, 650)
        self.win.setWindowTitle('IMU signal viewer')
        # Note that size arguments are only a suggestion; docks will still have to
        # fill the entire dock area and obey the limits of their internal widgets
        self.d1 = Dock("Accelerometer", size=(400, 400))
        self.d2 = Dock("Magnetometer", size=(400, 400))
        self.d3 = Dock("Gyroscope", size=(400, 400))
        self.d4 = Dock("LinearAcc", size=(800, 250))
        self.d5 = Dock("Position", size=(800, 400))
        self.d6 = Dock("Euler", size=(800, 250))
        self.d7 = Dock("Menu", size=(50, 50))
        self.d8 = Dock("Calibration", size=(400, 400))
        self.d9 = Dock("Graph", size=(CANVAS_LENGTH, CANVAS_HEIGHT))
        self.d10 = Dock("Word", size=(800, 250))
        self.d11 = Dock("Clasification", size=(400, 400))
        self.area.addDock(
            self.d4, 'left')  # place self.d6 at left edge of dock self.area
        self.area.addDock(self.d10, 'above', self.d4)
        self.area.addDock(self.d6, 'above', self.d10)
        self.area.addDock(self.d5, 'bottom',
                          self.d6)  # place self.d9 bottom edge of self.d6
        self.area.addDock(self.d9, 'above', self.d5)
        self.area.addDock(self.d1, 'right')
        self.area.addDock(self.d3, 'bottom', self.d1)
        self.area.addDock(self.d8, 'bottom', self.d3)
        self.area.addDock(self.d11, 'above', self.d8)
        self.area.addDock(self.d2, 'above', self.d11)
        self.area.addDock(self.d7, 'bottom', self.d2)
        plot_acc = pg.PlotWidget(title="Accelerometer m/s^2")
        plot_acc.addLegend()
        plot_acc.setLabel('bottom', 'Time', units='s')
        plot_acc.setYRange(-60, 60)
        self.acc_x = plot_acc.plot(pen=pg.mkPen('r', width=2), name='x')
        self.acc_y = plot_acc.plot(pen=pg.mkPen('b', width=2), name='y')
        self.acc_z = plot_acc.plot(pen=pg.mkPen('g', width=2), name='z')
        self.d1.addWidget(plot_acc)
        plot_mag = pg.PlotWidget(title="Magnetometer uT")
        plot_mag.addLegend()
        plot_mag.setLabel('bottom', 'Time', units='s')
        plot_mag.setYRange(-90, 90)
        self.mag_x = plot_mag.plot(pen=pg.mkPen('r', width=2), name='x')
        self.mag_y = plot_mag.plot(pen=pg.mkPen('b', width=2), name='y')
        self.mag_z = plot_mag.plot(pen=pg.mkPen('g', width=2), name='z')
        self.d2.addWidget(plot_mag)
        plot_gyr = pg.PlotWidget(title="Gyroscope rad/s")
        plot_gyr.addLegend()
        plot_gyr.setLabel('bottom', 'Time', units='s')
        plot_gyr.setYRange(-1500, 1500)
        self.gyr_x = plot_gyr.plot(pen=pg.mkPen('r', width=2), name='x')
        self.gyr_y = plot_gyr.plot(pen=pg.mkPen('b', width=2), name='y')
        self.gyr_z = plot_gyr.plot(pen=pg.mkPen('g', width=2), name='z')
        self.d3.addWidget(plot_gyr)
        plot_lin = pg.PlotWidget(title="Linear Accelerometer m/s^2")
        plot_lin.addLegend()
        plot_lin.setLabel('bottom', 'Time', units='s')
        plot_lin.setYRange(-60, 60)
        self.lin_x = plot_lin.plot(pen=pg.mkPen('r', width=2), name='x')
        self.lin_y = plot_lin.plot(pen=pg.mkPen('b', width=2), name='y')
        self.lin_z = plot_lin.plot(pen=pg.mkPen('g', width=2), name='z')
        self.d4.addWidget(plot_lin)
        plot_eul = pg.PlotWidget(title="Euler degrees")
        plot_eul.addLegend()
        plot_eul.setLabel('bottom', 'Time', units='s')
        plot_eul.setYRange(-200, 200)
        self.eul_x = plot_eul.plot(pen=pg.mkPen('r', width=2), name='x')
        self.eul_y = plot_eul.plot(pen=pg.mkPen('b', width=2), name='y')
        self.eul_z = plot_eul.plot(pen=pg.mkPen('g', width=2), name='z')
        self.d6.addWidget(plot_eul)

        # canvas dock
        self.label = QtWidgets.QLabel()
        self.canvas = QtGui.QPixmap(800, 400)
        self.canvas.fill(QtCore.Qt.white)
        self.label.setPixmap(self.canvas)
        self.d9.addWidget(self.label)
        self.last_x, self.last_y = CANVAS_LENGTH / 2, CANVAS_HEIGHT / 2
        self.last_ang_x, self.last_ang_y = 0.0, 0.0

        # display word dock
        layout_word = pg.LayoutWidget()
        self.label_word = QtGui.QLabel()
        layout_word.addWidget(self.label_word, row=0, col=0)
        self.d10.addWidget(layout_word)

        # plot position dock
        self.plot_position_wg = pg.PlotWidget(title="Character Display")
        self.plot_position_wg.setYRange(-0.50, 0.50)
        self.plot_position_wg.setXRange(-0.50, 0.50)
        self.plot_position_wg.addLegend()
        self.position_coord = self.plot_position_wg.plot(
            pen=pg.mkPen('r', width=5))
        self.d5.addWidget(self.plot_position_wg)

        # calibration window dock
        layout_calibration = pg.LayoutWidget()
        label_calib = QtGui.QLabel("Calibration:")
        self.label_calib_acc = QtGui.QLabel("ACC: 0")
        self.label_calib_gyr = QtGui.QLabel("GYR: 0")
        self.label_calib_mag = QtGui.QLabel("MAG: 0")
        self.label_calib_sys = QtGui.QLabel("SYS: 0")
        label_quat = QtGui.QLabel("Quaternion:")
        label_eul = QtGui.QLabel("Euler:")
        self.label_quaternion = QtGui.QLabel("W: 0.0\tX: 0.0\tY: 0.0\tZ: 0.0")
        self.label_euler = QtGui.QLabel("X: 0.0\tY: 0.0\tZ: 0.0")
        layout_calibration.addWidget(label_calib, row=0, col=0)
        layout_calibration.addWidget(self.label_calib_acc, row=1, col=0)
        layout_calibration.addWidget(self.label_calib_gyr, row=2, col=0)
        layout_calibration.addWidget(self.label_calib_mag, row=3, col=0)
        layout_calibration.addWidget(self.label_calib_sys, row=4, col=0)
        layout_calibration.addWidget(label_quat, row=5, col=0)
        layout_calibration.addWidget(self.label_quaternion, row=5, col=1)
        layout_calibration.addWidget(label_eul, row=6, col=0)
        layout_calibration.addWidget(self.label_euler, row=6, col=1)
        self.d8.addWidget(layout_calibration)

        # classification window dock
        layout_letter = pg.LayoutWidget()
        self.label_letter = QtGui.QLabel("")
        self.label_letter.setFont(QtGui.QFont('Arial', 50))
        layout_letter.addWidget(self.label_letter, row=0, col=0)
        self.d11.addWidget(layout_letter)

        # Menu window dock
        layout_buttons = pg.LayoutWidget()
        connect_b = QtGui.QPushButton(
            "Connect")  # To start listening to Serial port
        self.record_b = QtGui.QPushButton("Record")  # To start Recording data
        self.stop_b = QtGui.QPushButton("Stop")  # To start Recording data
        self.disconnect_b = QtGui.QPushButton(
            "Disconnect Device")  # To start Recording data
        self.change_name_b = QtGui.QPushButton(
            "Set log name")  # To start Recording data
        recenter_b = QtGui.QPushButton(
            "Re-Center")  # Re-center pointer position
        self.textbox = QtGui.QLineEdit()
        label_1 = QtGui.QLabel("""Orientation Mode: """)
        self.mode_box = QtGui.QComboBox()
        self.mode_box.addItems(
            ["complementary_filter", "Madgwick", "sensor_ahrs"])
        label_2 = QtGui.QLabel("""Word Mode: """)
        self.word_box = QtGui.QComboBox()
        self.word_box.addItems(["OFF", "ON"])
        label_3 = QtGui.QLabel("""Word command: """)
        self.start_b = QtGui.QPushButton(
            "Start")  # To start listening to Serial port
        self.next_b = QtGui.QPushButton("Next")  # To start Recording data
        self.end_b = QtGui.QPushButton("End")  # To start Recording data
        layout_buttons.addWidget(connect_b, row=0, col=0)
        layout_buttons.addWidget(self.record_b, row=0, col=1)
        layout_buttons.addWidget(self.stop_b, row=0, col=2)
        layout_buttons.addWidget(self.disconnect_b, row=0, col=3)
        layout_buttons.addWidget(self.change_name_b, row=1, col=0)
        layout_buttons.addWidget(self.textbox, row=1, col=1, colspan=3)
        layout_buttons.addWidget(label_1, row=2, col=0)
        layout_buttons.addWidget(self.mode_box, row=2, col=1, colspan=2)
        layout_buttons.addWidget(recenter_b, row=2, col=3)
        layout_buttons.addWidget(label_2, row=3, col=0)
        layout_buttons.addWidget(self.word_box, row=3, col=1, colspan=2)
        layout_buttons.addWidget(label_3, row=4, col=0)
        layout_buttons.addWidget(self.start_b, row=4, col=1)
        layout_buttons.addWidget(self.next_b, row=4, col=2)
        layout_buttons.addWidget(self.end_b, row=4, col=3)
        connect_b.pressed.connect(self.listen)
        self.record_b.pressed.connect(self.record)
        self.stop_b.pressed.connect(self.stop_recording)
        self.disconnect_b.pressed.connect(self.disconnect)
        self.change_name_b.pressed.connect(self.change_name)
        self.start_b.pressed.connect(self.start_letter)
        self.next_b.pressed.connect(self.next_letter)
        self.end_b.pressed.connect(self.end_letter)
        recenter_b.pressed.connect(self.recenter_pointer)
        self.mode_box.currentIndexChanged.connect(self.mode_change)
        self.word_box.currentIndexChanged.connect(self.word_mode_change)
        self.start_b.setEnabled(False)
        self.next_b.setEnabled(False)
        self.end_b.setEnabled(False)
        self.d7.addWidget(layout_buttons)

        self.mutex = QtCore.QMutex()  # mutex to control raw_data access
        self.mutex_line = QtCore.QMutex()  # mutex to control raw_line access
        self.raw_line = []  # This list will keep the incoming lines to process
        self.imu_struct = {
            "TIME": [],
            "ELAPSED_SECONDS": [],
            "PSTATE": [],
            "acc_x": [],
            "acc_y": [],
            "acc_z": [],
            "mag_x": [],
            "mag_y": [],
            "mag_z": [],
            "gyr_x": [],
            "gyr_y": [],
            "gyr_z": [],
            "lin_x": [],
            "lin_y": [],
            "lin_z": [],
            "eul_x": [],
            "eul_y": [],
            "eul_z": [],
            "qua_w": [],
            "qua_x": [],
            "qua_y": [],
            "qua_z": []
        }
        # Prettier and better solution would be to include this values to
        # imu_struct but that would imply REFACTORING the code to calculate
        # the x & y position in the fill table thread instead of the plotting thread
        self.empty_xy_points = {"x": [], "y": []}
        self.canvas_xy_points = copy.deepcopy(self.empty_xy_points)
        ##########################################################################################
        #  The rate of receiving RAW data depends on how much data is being transmitted
        # ########################################################################################
        #  Data received            |   Possible Calculation Methods    |   speed
        #  --------------------------------------------------------------------------------
        #  acc + gyr + quat         |   comp. filter                    |   Hz = 33  period = 30ms
        ##########################################################################################
        #  Orientation Modes:
        #   complementary_filter    Not working correctlty, can be improved or removed
        #   Madgwick                Using Madgwick's Sensor Fusion Algorithm
        #   sensor_ahrs             Using the Orientation provided by the sensor
        ##########################################################################################
        self.mode = "sensor_ahrs"
        self.period = 0.035  # The period depends on the transmission rate from the finger wearable
        self.rate = 1 / self.period
        # this is the structure where the las 50 samples are stored for displaying on the real-time
        # plots on screen.
        self.raw_data = copy.deepcopy(self.imu_struct)
        # empty structure, must be keep that way
        self.data_struct = copy.deepcopy(self.imu_struct)
        # This is the structure where the data is stored for storing the online data after completing
        # the finger-movement.
        self.to_save_data = copy.deepcopy(self.raw_data)

        # Display the GUI
        self.win.show()

        # Calibration from BNO055 IMU sensor
        self.accel_calibration = 0
        self.gyro_calibration = 0
        self.magnet_calibration = 0
        self.system_calibration = 0

        # PyQt timer
        self.timer = pg.QtCore.QTimer()
        self.timer.timeout.connect(self.update_graph)

        #flags to control de state machine (see Thesis Document chapter 3.4)
        self.first_angle_measure = True
        self.first_line = True
        self.first_update = True
        self.first_graph_update = True
        self.stop_threads = False
        self.init_time = 0
        self.recording = False
        self.word_mode = False
        self.recording_word = False
        self.word_letter_number = 0
        # Madgwick variable
        # By Increasing the value of Beta(magnetic & acc correction to gyro) is faster but more unstable
        self.madgwick_ahrs = skin.imus.Madgwick(rate=self.rate, Beta=0.10)
        self.prediction_model = None
        self.load_model()
        self.word_prediction = ""