Exemplo n.º 1
0
def car_dir(tmpdir_factory, base_config, imu_fields) -> str:
    """ Creating car dir with sub dirs and extracting tub """
    car_dir = tmpdir_factory.mktemp('mycar')
    os.mkdir(os.path.join(car_dir, 'models'))
    # extract tub.tar.gz into car_dir/tub
    this_dir = os.path.dirname(os.path.abspath(__file__))
    with tarfile.open(os.path.join(this_dir, 'tub', 'tub.tar.gz')) as file:
        file.extractall(car_dir)
    # now create a second tub with additonal imu data
    tub_dir = os.path.join(car_dir, 'tub')
    tub = Tub(base_path=tub_dir)
    full_dir = os.path.join(car_dir, 'tub_full')
    tub_full = Tub(base_path=full_dir,
                   inputs=tub.manifest.inputs + imu_fields +
                   ['behavior/one_hot_state_array', 'localizer/location'],
                   types=tub.manifest.types + ['float'] * 6 + ['list', 'int'])
    count = 0
    for record in tub:
        t = TubRecord(base_config, tub.base_path, record)
        img = t.image()
        record['cam/image_array'] = img
        for field in imu_fields:
            record[field] = np.random.rand()
        # add behavioural input
        bhv = [1., 0.] if count < len(tub) // 2 else [0., 1.]
        record["behavior/one_hot_state_array"] = bhv
        record['localizer/location'] = 3 * count // len(tub)
        tub_full.write_record(record)
        count += 1
    return car_dir
Exemplo n.º 2
0
def benchmark():
    # Change to a non SSD storage path
    path = Path('/media/rahulrav/Cruzer/benchmark')

    # Recreate paths
    if os.path.exists(path.absolute().as_posix()):
        shutil.rmtree(path)

    inputs = ['input']
    types = ['int']
    tub = Tub(path.as_posix(), inputs, types, max_catalog_len=1000)
    write_count = 1000
    for i in range(write_count):
        record = {'input': i}
        tub.write_record(record)

    deletions = np.random.randint(0, write_count, 100)
    for index in deletions:
        index = int(index)
        tub.delete_record(index)
 
    for record in tub:
        print('Record %s' % record)

    tub.close()
Exemplo n.º 3
0
    def run(self, args, parser):
        '''
        Load the images from a tub and create a movie from them.
        Movie
        '''

        if args.tub is None:
            print("ERR>> --tub argument missing.")
            parser.print_help()
            return

        conf = os.path.expanduser(args.config)
        if not os.path.exists(conf):
            print("No config file at location: %s. Add --config to specify\
                 location or run from dir containing config.py." % conf)
            return

        self.cfg = dk.load_config(conf)

        if args.type is None and args.model is not None:
            args.type = self.cfg.DEFAULT_MODEL_TYPE
            print("Model type not provided. Using default model type from config file")

        if args.salient:
            if args.model is None:
                print("ERR>> salient visualization requires a model. Pass with the --model arg.")
                parser.print_help()

            if args.type not in ['linear', 'categorical']:
                print("Model type {} is not supported. Only linear or categorical is supported for salient visualization".format(args.type))
                parser.print_help()
                return

        self.tub = Tub(args.tub)

        start = args.start
        self.end_index = args.end if args.end != -1 else len(self.tub)
        num_frames = self.end_index - start

        # Move to the correct offset
        self.current = 0
        self.iterator = self.tub.__iter__()
        while self.current < start:
            self.iterator.next()
            self.current += 1

        self.scale = args.scale
        self.keras_part = None
        self.do_salient = False
        self.user = args.draw_user_input
        if args.model is not None:
            self.keras_part = get_model_by_type(args.type, cfg=self.cfg)
            self.keras_part.load(args.model)
            if args.salient:
                self.do_salient = self.init_salient(self.keras_part.model)

        print('making movie', args.out, 'from', num_frames, 'images')
        clip = mpy.VideoClip(self.make_frame, duration=((num_frames - 1) / self.cfg.DRIVE_LOOP_HZ))
        clip.write_videofile(args.out, fps=self.cfg.DRIVE_LOOP_HZ)
Exemplo n.º 4
0
 def __init__(self, tub_paths, test_size=0.2, shuffle=True):
     self.tub_paths = tub_paths
     self.test_size = test_size
     self.shuffle = shuffle
     self.tubs = [
         Tub(tub_path, read_only=True) for tub_path in self.tub_paths
     ]
     self.records = list()
Exemplo n.º 5
0
def convert_to_tub_v2(paths, output_path):
    """
    Convert from old tubs to new one

    :param paths:               legacy tub paths
    :param output_path:         new tub output path
    :return:                    None
    """
    empty_record = {'__empty__': True}
    if type(paths) is str:
        paths = [paths]
    legacy_tubs = [LegacyTub(path) for path in paths]
    print(f'Total number of tubs: {len(legacy_tubs)}')

    for legacy_tub in legacy_tubs:
        # add input and type for empty records recording
        inputs = legacy_tub.inputs + ['__empty__']
        types = legacy_tub.types + ['boolean']
        output_tub = Tub(output_path, inputs, types,
                         list(legacy_tub.meta.items()))
        record_paths = legacy_tub.gather_records()
        bar = IncrementalBar('Converting', max=len(record_paths))
        previous_index = None
        for record_path in record_paths:
            try:
                contents = Path(record_path).read_text()
                record = json.loads(contents)
                image_path = record['cam/image_array']
                ms = record['milliseconds']
                current_index = int(image_path.split('_')[0])
                image_path = os.path.join(legacy_tub.path, image_path)
                image_data = Image.open(image_path)
                record['cam/image_array'] = image_data
                # first record or they are continuous, just append
                if not previous_index or current_index == previous_index + 1:
                    output_tub.write_record(record, ms)
                    previous_index = current_index
                # otherwise fill the gap with empty records
                else:
                    # Skipping over previous record here because it has
                    # already been written.
                    previous_index += 1
                    # Adding empty record nodes, and marking them deleted
                    # until the next valid record.
                    delete_list = []
                    while previous_index < current_index:
                        idx = output_tub.manifest.current_index
                        output_tub.write_record(empty_record, ms)
                        delete_list.append(idx)
                        previous_index += 1
                    output_tub.delete_records(delete_list)
                bar.next()
            except Exception as exception:
                print(f'Ignoring record path {record_path}\n', exception)
                traceback.print_exc()
        # writing session id into manifest metadata
        output_tub.close()
Exemplo n.º 6
0
 def __init__(self,
              config: Config,
              tub_paths: List[str],
              shuffle: bool = True) -> None:
     self.config = config
     self.tub_paths = tub_paths
     self.shuffle = shuffle
     self.tubs: List[Tub] = [
         Tub(tub_path, read_only=True) for tub_path in self.tub_paths
     ]
     self.records: List[TubRecord] = list()
Exemplo n.º 7
0
    def clips_of_tub(self, tub_path):
        tub = Tub(tub_path)

        clips = []
        for record in tub:
            index = record['_index']
            images_relative_path = os.path.join(Tub.images(),
                                                record['cam/image_array'])
            record['cam/image_array'] = images_relative_path
            clips.append(record)

        return [clips]
Exemplo n.º 8
0
 def __init__(self,
              config: Config,
              tub_paths: List[str],
              shuffle: bool = True) -> None:
     self.config = config
     self.tub_paths = tub_paths
     self.shuffle = shuffle
     self.tubs: List[Tub] = [
         Tub(tub_path, read_only=True) for tub_path in self.tub_paths
     ]
     self.records: List[TubRecord] = list()
     self.train_filter = getattr(config, 'TRAIN_FILTER', None)
    def update_tub(self, reload=False):
        if not self.base_path or not self.app.config_loader.config:
            return
        if not os.path.exists(os.path.join(self.base_path, 'manifest.json')):
            self.app.update_status(
                f'Path {self.base_path} is not a valid tub.')
            return
        try:
            self.tub = Tub(self.base_path)
        except Exception as e:
            self.app.update_status(f'Failed loading tub: {str(e)}')
            return

        # Use filter, this defines the function
        def select(underlying):
            if self.app.tub_manipulator.filter_expression is None:
                return True
            else:
                record = TubRecord(self.app.config_loader.config,
                                   self.tub.base_path, underlying)
                res = eval(self.app.tub_manipulator.filter_expression)
                return res

        self.records = [
            TubRecord(self.app.config_loader.config, self.tub.base_path,
                      record) for record in self.tub if select(record)
        ]
        self.len = len(self.records)
        self.state.i = 0
        self.label.config(text=self.base_path)
        if self.len > 0:
            self.state.record = self.records[self.state.i]
            # update app components, manipulator, slider and plot
            self.app.tub_manipulator.set_lr(is_l=True)
            self.app.tub_manipulator.set_lr(is_l=False)
            # clear bars for new tub only but not for reloading existing tub
            if not reload:
                self.app.data_panel.clear()
            self.app.slider.slider.configure(to=self.len - 1)
            # update graph
            self.app.data_plot.update_dataframe_from_tub()
            msg = f'Loaded tub {self.base_path} with {self.len} records'
        else:
            msg = f'No records in tub {self.base_path}'
        if self.app.tub_manipulator.record_filter:
            msg += f' using filter {self.app.tub_manipulator.record_filter}'
        self.app.update_status(msg)
Exemplo n.º 10
0
    def __init__(self, path):
        DriveFormat.__init__(self)

        if not os.path.exists(path):
            raise IOError(
                "Tubv2Format directory does not exist: {}".format(path))
        if not os.path.isdir(path):
            raise IOError(
                "Tubv2Format path is not a directory: {}".format(path))

        self.path = path
        self.tub = Tub(path, read_only=False)
        self.meta = self.tub.manifest.metadata  # Bug. tub.metadata doesn't get updated with info from disc
        self.deleted_indexes = self.tub.manifest.deleted_indexes
        print(f"Deleted: {self.deleted_indexes}")
        self.edit_list = set()
        self.shape = None
Exemplo n.º 11
0
    def update_tub(self, event=None):
        if not self.file_path:
            return False
        # If config not yet loaded return
        cfg = tub_screen().ids.config_manager.config
        if not cfg:
            return False
        # At least check if there is a manifest file in the tub path
        if not os.path.exists(os.path.join(self.file_path, 'manifest.json')):
            tub_screen().status(f'Path {self.file_path} is not a valid tub.')
            return False
        try:
            self.tub = Tub(self.file_path)
        except Exception as e:
            tub_screen().status(f'Failed loading tub: {str(e)}')
            return False
        # Check if filter is set in tub screen
        expression = tub_screen().ids.tub_filter.filter_expression

        # Use filter, this defines the function
        def select(underlying):
            if not expression:
                return True
            else:
                try:
                    record = TubRecord(cfg, self.tub.base_path, underlying)
                    res = eval(expression)
                    return res
                except KeyError as err:
                    Logger.error(f'Filter: {err}')
                    return True

        self.records = [TubRecord(cfg, self.tub.base_path, record)
                        for record in self.tub if select(record)]
        self.len = len(self.records)
        if self.len > 0:
            tub_screen().index = 0
            tub_screen().ids.data_plot.update_dataframe_from_tub()
            msg = f'Loaded tub {self.file_path} with {self.len} records'
        else:
            msg = f'No records in tub {self.file_path}'
        if expression:
            msg += f' using filter {tub_screen().ids.tub_filter.record_filter}'
        tub_screen().status(msg)
        return True
Exemplo n.º 12
0
def tubs_from_directory(tub_dir, verbose=False):
    """ Load all tubs in the given directory """
    tubs = []
    count = 0
    root_path = Path(tub_dir)
    for item in root_path.iterdir():
        if item.is_dir():
            try:
                t = Tub(str(item), read_only=True)
                count += len(t)
            except FileNotFoundError as ex:
                continue
            except ValueError as ex:
                # In case the catalog file is empty
                continue
            tubs.append(t)
    if verbose:
        print(f"Loaded {count} records.")

    return tubs
Exemplo n.º 13
0
def tubs_from_filelist(file_list, verbose=False):
    """ Load all tubs listed in all files in file_list """
    tub_dirs = preprocessFileList(file_list)
    tubs = []
    count = 0
    root_path = Path("data")
    for item in tub_dirs:
        if Path(item).is_dir():
            try:
                t = Tub(str(item), read_only=True)
            except FileNotFoundError as ex:
                continue
            except ValueError as ex:
                # In case the catalog file is empty
                continue
            tubs.append(t)
            count += len(t)
    if verbose:
        print(f"Loaded {count} records.")

    return tubs
Exemplo n.º 14
0
    def post(self, tub_id):
        tub_path = os.path.join(self.data_path, tub_id)
        tub = Tub(tub_path)
        old_clips = self.clips_of_tub(tub_path)
        new_clips = tornado.escape.json_decode(self.request.body)

        import itertools
        old_frames = list(itertools.chain(*old_clips))
        old_indexes = set()
        for frame in old_frames:
            old_indexes.add(frame['_index'])

        new_frames = list(itertools.chain(*new_clips['clips']))
        new_indexes = set()
        for frame in new_frames:
            new_indexes.add(frame['_index'])

        frames_to_delete = [
            index for index in old_indexes if index not in new_indexes
        ]
        tub.delete_records(frames_to_delete)
Exemplo n.º 15
0
    def __init__(self, config: Any, tub_paths: List[str], transform=None):
        """Create a PyTorch Lightning Data Module to contain all data loading logic

        Args:
            config (object): the configuration information
            tub_paths (List[str]): a list of paths to the tubs to use (minimum size of 1).
                                   Each tub path corresponds to another training run.
            transform (function, optional): a transform to apply to the data
        """
        super().__init__()

        self.config = config
        self.tub_paths = tub_paths

        # Handle the transforms
        if transform:
            self.transform = transform
        else:
            self.transform = get_default_transform()

        self.tubs: List[Tub] = [
            Tub(tub_path, read_only=True) for tub_path in self.tub_paths
        ]
        self.records: List[TubRecord] = []
Exemplo n.º 16
0
    def plot_predictions(self, cfg, tub_paths, model_path, limit, model_type):
        '''
        Plot model predictions for angle and throttle against data from tubs.

        '''
        import matplotlib.pyplot as plt
        import pandas as pd

        model_path = os.path.expanduser(model_path)
        model = dk.utils.get_model_by_type(model_type, cfg)
        # This just gets us the text for the plot title:
        if model_type is None:
            model_type = cfg.DEFAULT_MODEL_TYPE
        model.load(model_path)

        user_angles = []
        user_throttles = []
        pilot_angles = []
        pilot_throttles = []

        from donkeycar.parts.tub_v2 import Tub
        from pathlib import Path

        base_path = Path(os.path.expanduser(tub_paths)).absolute().as_posix()
        tub = Tub(base_path)
        records = list(tub)
        records = records[:limit]
        bar = IncrementalBar('Inferencing', max=len(records))

        for record in records:
            img_filename = os.path.join(base_path, Tub.images(),
                                        record['cam/image_array'])
            img = load_image(img_filename, cfg)
            user_angle = float(record["user/angle"])
            user_throttle = float(record["user/throttle"])
            pilot_angle, pilot_throttle = model.run(img)

            user_angles.append(user_angle)
            user_throttles.append(user_throttle)
            pilot_angles.append(pilot_angle)
            pilot_throttles.append(pilot_throttle)
            bar.next()

        angles_df = pd.DataFrame({
            'user_angle': user_angles,
            'pilot_angle': pilot_angles
        })
        throttles_df = pd.DataFrame({
            'user_throttle': user_throttles,
            'pilot_throttle': pilot_throttles
        })

        fig = plt.figure()

        title = "Model Predictions\nTubs: " + tub_paths + "\nModel: " + model_path + "\nType: " + model_type
        fig.suptitle(title)

        ax1 = fig.add_subplot(211)
        ax2 = fig.add_subplot(212)

        angles_df.plot(ax=ax1)
        throttles_df.plot(ax=ax2)

        ax1.legend(loc=4)
        ax2.legend(loc=4)

        plt.savefig(model_path + '_pred.png')
        plt.show()
Exemplo n.º 17
0
 def setUp(self):
     self._path = tempfile.mkdtemp()
     inputs = ['input']
     types = ['int']
     self.tub = Tub(self._path, inputs, types)
Exemplo n.º 18
0
 def setUpClass(cls) -> None:
     cls._path = tempfile.mkdtemp()
     inputs = ['input']
     types = ['int']
     cls.tub = Tub(cls._path, inputs, types)