Exemplo n.º 1
0
    def do_predict(self, args=''):
        '''
        Start prediction

        Passing received frames through neural network and printing results.
        Listener should be started before using this command.
        Use <Ctrl-C> to stop this command.

        Usage:
        >> predict
        '''
        if args != '':
            error('Unknown arguments.')
            return

        with self.listening_lock:
            if not self.listening:
                error('Listener not started.')
                return

        if not self.__model_loaded():
            self.model.load()
            print()

        with self.predicting_lock:
            self.predicting = True

        self.__predict_thread()

        self.console_queue.get()

        with self.predicting_lock:
            self.predicting = False

        self.model_queue.put(None)
Exemplo n.º 2
0
 def postloop(self):
     '''
     Take care of any unfinished business.
     Despite the claims in the Cmd documentation, Cmd.postloop() is not a
     stub.
     '''
     Cmd.postloop(self)  # Clean up command completion
     print('Exiting...')
Exemplo n.º 3
0
    def discard_last_sample(self):
        last_sample = self.get_last_sample(self.gesture)
        if last_sample is None:
            print('No files.')
            return

        os.remove(last_sample)
        print('File deleted.')
Exemplo n.º 4
0
    def __set_file(self):
        last_sample = self.get_last_sample(self.gesture)
        if last_sample is None:
            self.log_file = os.path.join(last_sample, 'sample_1.csv')
            return

        save_dir = os.path.dirname(last_sample)
        last_sample_name = os.path.splitext(last_sample)[0]
        num = int(os.path.basename(last_sample_name).split('_')[1]) + 1
        self.log_file = os.path.join(save_dir, 'sample_' + str(num) + '.csv')
        print(f'Sample number: {num}')
Exemplo n.º 5
0
    def do_send(self, args=''):
        '''
        Sending configuration to mmWave

        Configuring mmWave with given configuration file. All configuration
        files should be placed in \'mmwave/communication/profiles\' folder.
        Use <Tab> for autocompletion on available configuration files.
        All configuration files should have .cfg extension.
        If no configuration is provided, default configuration file will be
        used.

        Usage:
        >> send
        >> send profile
        '''
        if args == '':
            args = self.default_config

        if len(args.split()) > 1:
            error('Too many arguments.')
            return

        if not self.__is_connected():
            error('Not connected.')
            return

        cfg = os.path.join(self.config_dir, args + '.cfg')
        if cfg not in glob.glob(os.path.join(self.config_dir, '*.cfg')):
            print('Unknown profile.')
            return

        mmwave_configured = False
        cnt = 0
        while not mmwave_configured and cnt < 5:
            mmwave_configured = self.mmwave.configure(cfg)
            if not mmwave_configured:
                signal_cnt = 0
                while signal_cnt < 5:
                    if not self.console_queue.empty():
                        self.console_queue.get()
                        return
                    time.sleep(.2)
                    signal_cnt += 1
            cnt += 1

        if not mmwave_configured:
            return

        if os.path.basename(cfg) == 'stop.cfg':
            self.configured = False
        else:
            self.configured = True
        self.config = cfg
Exemplo n.º 6
0
    def do_get_model(self, args=''):
        '''
        Get current model type.

        Usage:
        >> get_model
        '''

        if args != '':
            error('Unknown arguments.')
            return

        print(f'Current model type: {self.model_type}')
Exemplo n.º 7
0
    def __mmwave_init(self):
        self.mmwave = None
        if self.cli_port is None or self.data_port is None:
            print('Looking for ports...', end='')
            ports = mmWave.find_ports()

            if len(ports) < 2:
                print(f'{Fore.RED}Ports not found!')
                print(f'{Fore.YELLOW}Auto-detection is only applicable for',
                      f'{Fore.YELLOW}eval boards with XDS110.')
                return

            if len(ports) > 2:
                print(
                    f'{Fore.YELLOW}Multiple ports detected.',
                    f'{Fore.YELLOW}Selecting ports {ports[0]} and {ports[1]}.')
                ports = ports[:2]

            if platform.system() == 'Windows':
                ports.sort(reverse=True)

            self.cli_port = ports[0]
            self.data_port = ports[1]

        self.mmwave = mmWave(self.cli_port,
                             self.data_port,
                             cli_rate=self.default_cli_rate,
                             data_rate=self.default_data_rate)
        self.mmwave.connect()
        if self.mmwave.connected():
            self.flasher = Flasher(self.mmwave.cli_port)
Exemplo n.º 8
0
    def __listen_thread(self):
        print(f'{Fore.CYAN}=== Listening ===')
        while True:
            with self.listening_lock:
                if not self.listening:
                    return

            data = self.mmwave.get_data()

            if data is None:
                time.sleep(.5)
                continue

            self.data_queue.put(data)
            time.sleep(.05)
Exemplo n.º 9
0
    def pprint(frame):
        if frame is None:
            print(f'{Fore.MAGENTA}Frame: {Fore.RED}None')
            return

        print(Fore.CYAN + '='*85)
        Parser.__pprint_struct(frame)
        print(Fore.CYAN + '='*85)
        print()
Exemplo n.º 10
0
    def do_connect(self, args=''):
        '''
        Manually connecting to mmWave

        Command will ask you to manualy type ports and baudrates.
        Use <Tab> for autocompletion on available ports and baudrates.
        Type \'exit\' for exiting manual connection.
        If you only press enter on baudrates, console will try to find
        baudrate automatically. Note that this will work only if connection
        is already opened from both sides. (On mmWave startup only cli port
        is open, and data port will open only after \'senstrStart\' command)

        Look \'autoconnect\' command for automatic connection.

        Usage:
        >> connect
        cli port: /dev/ttyACM0
        cli rate: 115200
        data port: /dev/ttyACM1
        data rate: 921600
        '''

        if args != '':
            error('Unknown arguments.')
            return

        if self.__is_connected():
            self.mmwave.disconnect()
            print()

        port = self.__get_user_port('cli')
        if port is not None:
            self.cli_port = port
            self.cli_rate = self.__get_user_rate('cli', port)
        else:
            return

        port = self.__get_user_port('data')
        if port is not None:
            self.data_port = port
            self.data_rate = self.__get_user_rate('data', port)
        else:
            return

        self.__mmwave_init()
Exemplo n.º 11
0
 def get_all_data(refresh_data=False):
     X_file = os.path.join(os.path.dirname(__file__), '.X_data')
     y_file = os.path.join(os.path.dirname(__file__), '.y_data')
     if refresh_data:
         X = []
         y = []
         for gesture in tqdm(GESTURE, desc='Gestures'):
             for sample in Logger.get_data(gesture):
                 X.append(sample)
                 y.append(gesture.value)
         pickle.dump(X, open(X_file, 'wb'))
         pickle.dump(y, open(y_file, 'wb'))
     else:
         print('Loading cached data...', end='')
         X = pickle.load(open(X_file, 'rb'))
         y = pickle.load(open(y_file, 'rb'))
         print(f'{Fore.GREEN}Done.')
     return X, y
Exemplo n.º 12
0
    def precmd(self, line):
        '''
        This method is called after the line has been input but before
        it has been interpreted. If you want to modify the input line
        before execution (for example, variable substitution) do it here.
        '''
        self._hist += [line.strip()]

        try:
            info = self.plotter_queues['info'].get(False)
            if info == 'closed':
                print(f'{Fore.YELLOW}Plotter closed.\n')
                with self.plotting_lock:
                    if self.plotting:
                        self.plotting = False
        except queue.Empty:
            pass

        return line
Exemplo n.º 13
0
    def assemble(self, data):
        if data is None:
            return None

        start_idx = data.find(self.formats.MAGIC_NUMBER)
        if start_idx == 0:
            # Save return value, and start capturing new frame
            frame = deepcopy(self.buffer)
            self.buffer = bytearray(data)

            self.sync_time = time.perf_counter()
            if self.sync is False:
                print(f'{Fore.GREEN}Sync received!\n')
                self.sync = True
                return None
            return frame

        elif self.sync is False:
            if self.sync_time == 0:
                self.sync_time = time.perf_counter()
                print(f'{Fore.YELLOW}Waiting for sync...')

            # Capture long sync time
            if time.perf_counter() - self.sync_time > self.sync_timeout:
                print(f'{Fore.RED}No sync received.')
                print('Please check your board.\n')
                self.sync_time = 0

        else:
            # Wait for rest of the frame
            self.buffer.extend(bytearray(data))

            # Capture long no data time
            if data == b'':
                if time.perf_counter() - self.sync_time > self.sync_timeout:
                    print(f'{Fore.RED}Not receiving data. Resyncing...')
                    self.sync_time = 0
                    self.sync = False
Exemplo n.º 14
0
    def __init__(self, plotter_queues):
        super().__init__()

        # Connection
        self.cli_port = None
        self.cli_rate = None
        self.data_port = None
        self.data_rate = None

        self.default_cli_rate = 115200
        self.default_data_rate = 921600

        self.firmware_dir = 'firmware/'
        self.flasher = None

        self.__mmwave_init()
        if self.mmwave is None or self.mmwave.connected() is False:
            print(
                'Try connecting manually. Type \'help connect\' for more info.\n'
            )

        # Configuration
        self.config_dir = 'mmwave/communication/profiles/'
        self.configured = False
        self.default_config = 'profile'
        self.config = None

        self.logger = Logger()

        self.model_type = 'lstm'
        self.__set_model(self.model_type)

        # Catching signals
        self.console_queue = Queue()
        SignalHandler(self.console_queue)

        # Threading stuff
        self.listening_lock = Lock()
        self.printing_lock = Lock()
        self.plotting_lock = Lock()
        self.predicting_lock = Lock()
        self.logging_lock = Lock()

        self.listening = False
        self.printing = False
        self.plotting = False
        self.predicting = False
        self.logging = False

        self.logging_queue = Queue()
        self.data_queue = Queue()
        self.model_queue = Queue()
        self.plotter_queues = plotter_queues

        self.__set_prompt()
        print(f'{Fore.GREEN}Init done.\n')
        print(f'{Fore.MAGENTA}--- mmWave console ---')
        warning('Type \'help\' for more information.')
Exemplo n.º 15
0
    def do_start(self, args=''):
        '''
        Start listener, plotter and prediction.

        If mmWave is not configured, default configuration will be send
        first. Use <Ctrl-C> to stop this command.

        Usage:
        >> start
        '''
        if args != '':
            error('Unknown arguments.')
            return

        if not self.__model_loaded():
            self.model.load()
            print()

        self.do_send(self.default_config)
        self.do_listen()
        self.do_plot()
        self.do_predict()
        self.do_stop()
Exemplo n.º 16
0
    def do_autoconnect(self, args=''):
        '''
        Auto connecting to mmWave

        Automatically looking for \'XDS\' ports and connecting with default
        baudrates. Auto-detection is only applicable for eval boards with
        XDS110.

        Look \'connect\' command for manual connection.

        Usage:
        >> autoconnect
        '''
        if args != '':
            error('Unknown arguments.')
            return

        if self.__is_connected():
            warning('Already connected.')
            print('Reconnecting...')

        self.cli_port = None
        self.data_port = None
        self.__mmwave_init()
Exemplo n.º 17
0
    def log(self, frame):
        if not self.logging:
            self.__set_file()
            self.logging = True
            self.detected_time = time.perf_counter()
            print('Saving...')

        if (frame is not None and frame.get('tlvs') is not None
                and frame['tlvs'].get(1) is not None):
            self.detected_time = time.perf_counter()
            with open(self.log_file, 'a') as f:
                if self.frame_num == 0:
                    f.write(
                        'frame,x,y,range_idx,peak_value,doppler_idx,xyz_q_format\n'
                    )

                for obj in frame['tlvs'][1]['values']['objs']:
                    f.write(self.empty_frames)
                    f.write(str(self.frame_num) + ',')
                    f.write(str(obj['x_coord']) + ',')
                    f.write(str(obj['y_coord']) + ',')
                    f.write(str(obj['range_idx']) + ',')
                    f.write(str(obj['peak_value']) + ',')
                    f.write(str(obj['doppler_idx']) + ',')
                    f.write(
                        str(frame['tlvs'][1]['values']['descriptor']
                            ['xyz_q_format']) + '\n')
                    self.empty_frames = ''

            self.frame_num += 1

        elif self.frame_num != 0:
            self.empty_frames = (self.empty_frames + str(self.frame_num) + ',')
            self.empty_frames = (self.empty_frames +
                                 'None, None, None, None, None\n')
            self.frame_num += 1

        if time.perf_counter() - self.detected_time > .5:
            if os.path.isfile(self.log_file):
                print('Sample saved.\n')
            else:
                print('Nothing to save.\n')
            self.empty_frames = ''

            self.logging = False
            self.frame_num = 0
            return True

        return False
Exemplo n.º 18
0
    def do_stop(self, args=''):
        '''
        Stopping mmwave, listener and plotter.

        Possible options: \'mmwave\', \'listen\' and \'plot\'.
            \'mmwave\': Sending \'sensorStop\' command to mmWave. This option
                        will also stop listener and plotter.
            \'listen\': Stopping listener and parser threads. This option
                        will also stop plotter.
            \'plot\': Closing plotter.
         If nothing is provided as a argument, \'mmwave\' will be used.

        Usage:
        >> stop
        >> stop plot
        '''
        if args == '' or 'mmwave' in args.split():
            opts = ['plot', 'listen', 'mmwave']
        elif 'listen' in args.split():
            opts = ['plot', 'listen']
        else:
            opts = args.split()

        if 'plot' in opts:
            with self.plotting_lock:
                if self.plotting:
                    self.plotting = False
                    print('Plotter stopped.')
            self.plotter_queues['cli'].put('close')
            opts.remove('plot')

        if 'listen' in opts:
            with self.listening_lock:
                if self.listening:
                    self.listening = False
                    self.data_queue.put(None)
                    print('Listener stopped.')
            opts.remove('listen')

        if 'mmwave' in opts:
            if self.configured:
                self.do_send('stop')
            print('mmWave stopped.')
            opts.remove('mmwave')

        for opt in opts:
            warning(f'Unknown option: {opt}. Skipped.')
Exemplo n.º 19
0
    def get_stats(X, y):
        num_of_classes = len(set(y))
        print(f'Number of classes: {num_of_classes}')
        sample_with_max_num_of_frames = max(X, key=lambda sample: len(sample))

        max_num_of_frames = len(sample_with_max_num_of_frames)
        print(f'Maximum number of frames: {max_num_of_frames}')

        sample_with_max_num_of_objs = max(
            X, key=lambda sample: [len(frame) for frame in sample])

        frame_with_max_num_of_objs = max(sample_with_max_num_of_objs,
                                         key=lambda obj: len(obj))

        max_num_of_objs = len(frame_with_max_num_of_objs)
        print(f'Maximum num of objects: {max_num_of_objs}')

        return max_num_of_frames, max_num_of_objs, num_of_classes
Exemplo n.º 20
0
 def do_history(self, args):
     '''Print a list of commands that have been entered'''
     if args != '':
         error('Unknown arguments.')
         return
     print(self._hist)
Exemplo n.º 21
0
    def do_eval(self, args=''):
        '''
        Evaluate neural network

        Command will first load cached X and y data located in
        \'mmwave/data/.X_data\' and \'mmwave/data/.y_data\' files. This data
        will be used for the evaluating process. If you want to read raw .csv
        files, provide \'refresh\' (this will take few minutes).

        Usage:
        >> eval
        >> eval refresh
        '''

        if len(args.split()) > 1:
            error('Unknown arguments.')
            return

        if args == '':
            refresh_data = False
        elif args == 'refresh':
            refresh_data = True
        else:
            warning(f'Unknown argument: {args}')
            return

        X, y = Logger.get_all_data(refresh_data=refresh_data)
        Logger.get_stats(X, y)

        X_train, X_val, y_train, y_val = train_test_split(X,
                                                          y,
                                                          test_size=.3,
                                                          stratify=y,
                                                          random_state=12)

        if not self.__model_loaded():
            self.model.load()
            print()

        print('Eval validation dataset:')
        self.model.evaluate(X_val, y_val)
        print()

        print('Eval train dataset:')
        self.model.evaluate(X_train, y_train)
        print()

        print('Eval full dataset:')
        self.model.evaluate(X, y)
        print()
Exemplo n.º 22
0
 def __header_frame_num_check(self, header, echo=False):
     if self.frame_num != 0 and self.frame_num + 1 != header['frame_num']:
         if echo:
             num_of_missed_frames = header['frame_num'] - self.frame_num - 1
             print(f'{Fore.YELLOW}WARNING: Missed {num_of_missed_frames} frames.')
     self.frame_num = header['frame_num']
Exemplo n.º 23
0
    def __pprint_struct(frame, indentation='', _recursive_call=False):
        identetion_marker = '|' + 3*' '

        if not _recursive_call:
            Parser.__pprint_struct.num = 1

        for key, value in frame.items():
            if isinstance(value, dict):
                print(indentation, end='')
                color = Parser.__pprint_get_color(Parser.__pprint_struct.num - 1)
                print(f'{color}{key}:')

                indentation += identetion_marker
                Parser.__pprint_struct.num += 1
                Parser.__pprint_struct(value, indentation, True)
                Parser.__pprint_struct.num -= 1
                indentation = indentation[:-4]

                if key != sorted(frame.keys())[-1]:
                    print(indentation)
            elif isinstance(value, list):
                print(indentation, end='')
                color = Parser.__pprint_get_color(Parser.__pprint_struct.num - 1)
                print(f'{color}{key}:')

                indentation += identetion_marker
                for obj in value:
                    Parser.__pprint_struct.num += 1
                    Parser.__pprint_struct(obj, indentation, True)
                    Parser.__pprint_struct.num -= 1
                    if obj != value[-1]:
                        print(indentation)
                indentation = indentation[:-4]
            else:
                if isinstance(value, tuple):
                    print(indentation, end='')
                    color = Parser.__pprint_get_color(Parser.__pprint_struct.num - 1)
                    print(f'{color}{key}:')
                    indentation += identetion_marker

                    with pd.option_context('display.max_rows', 10,
                                           'display.max_columns', 6,
                                           'precision', 2,
                                           'show_dimensions', False):
                        df = pd.DataFrame(value)
                        df = pformat(df)
                        for line_idx, line in enumerate(df.split('\n')):
                            print(indentation, end='')
                            for word_idx, word in enumerate(line.split(' ')):
                                color = ''
                                if word_idx == 0 or line_idx == 0:
                                    color = Fore.YELLOW
                                print(f'{color}{word}', end=' ')
                            print()
                    indentation = indentation[:-4]
                else:
                    print(indentation, end='')
                    color = Parser.__pprint_get_color(Parser.__pprint_struct.num - 1)
                    print(f'{color}{key}: {value}')
Exemplo n.º 24
0
    def do_flash(self, args=''):
        '''
        Sending .bin files to mmWave

        Flashing bin files to connected mmWave. It is possible to specify up to
        4 meta files. SOP0 and SOP2 have be closed and power reseted before
        running this command.

        Look \'connect\' and \'autoconnect\' command for connecting to mmWave.

        Usage:
        >> flash xwr16xx_mmw_demo.bin
        '''
        if len(args.split()) > 4:
            error('Too many arguments.')
            return

        if args == '':
            error('Too few arguments.')
            return

        filepaths = []
        for arg in args.split():
            filepath = os.path.join(self.firmware_dir, arg)
            if not os.path.isfile(filepath):
                error(f'File \'{filepath}\' doesn\'t exist.')
                return
            filepaths.append(filepath)

        if not self.__is_connected():
            error('Not connected.')
            return

        print('Ping mmWave...', end='')
        response = self.flasher.send_cmd(CMD(OPCODE.PING), resp=False)
        if response is None:
            warning('Check if SOP0 and SOP2 are closed, and reset the power.')
            return
        print(f'{Fore.GREEN}Done.')

        print('Get version...', end='')
        response = self.flasher.send_cmd(CMD(OPCODE.GET_VERSION))
        if response is None:
            return
        print(f'{Fore.GREEN}Done.')
        print(f'{Fore.BLUE}Version:', binascii.hexlify(response))
        print()

        self.flasher.flash(filepaths, erase=True)
        print(f'{Fore.GREEN}Done.')
Exemplo n.º 25
0
 def __len_check(self, received, expected, echo=False):
     if received < expected:
         if echo:
             print(f'{Fore.RED}ERROR: Corrupted frame.')
         return False
     return True