예제 #1
0
def test_simulation_dataset_build(zarr_cat_dataset: ChunkedDataset,
                                  dmg: LocalDataManager, cfg: dict,
                                  tmp_path: Path) -> None:
    # modify one frame to ensure everything works also when scenes are different
    zarr_cat_dataset.frames = np.asarray(zarr_cat_dataset.frames)
    for scene_idx in range(len(zarr_cat_dataset.scenes)):
        frame_slice = get_frames_slice_from_scenes(zarr_cat_dataset.scenes)
        zarr_cat_dataset.frames[
            frame_slice.start]["ego_translation"] += np.random.randn(3)

    rasterizer = build_rasterizer(cfg, dmg)
    ego_dataset = EgoDataset(cfg, zarr_cat_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=False,
                               distance_th_far=30,
                               distance_th_close=10)
    # we should be able to create the same object by using both constructor and factory
    scene_indices = list(range(len(zarr_cat_dataset.scenes)))

    scene_dataset_batch: Dict[int, EgoDataset] = {}
    for scene_idx in scene_indices:
        scene_dataset = ego_dataset.get_scene_dataset(scene_idx)
        scene_dataset_batch[scene_idx] = scene_dataset
    sim_1 = SimulationDataset(scene_dataset_batch, sim_cfg)

    sim_2 = SimulationDataset.from_dataset_indices(ego_dataset, scene_indices,
                                                   sim_cfg)

    for (k_1, v_1), (k_2, v_2) in zip(sim_1.scene_dataset_batch.items(),
                                      sim_2.scene_dataset_batch.items()):
        assert k_1 == k_2
        assert np.allclose(v_1.dataset.frames["ego_translation"],
                           v_2.dataset.frames["ego_translation"])
예제 #2
0
    def update_agents(dataset: SimulationDataset, frame_idx: int,
                      input_dict: Dict[str, np.ndarray],
                      output_dict: Dict[str, np.ndarray]) -> None:
        """Update the agents in frame_idx (across scenes) using agents_output_dict

        :param dataset: the simulation dataset
        :param frame_idx: index of the frame to modify
        :param input_dict: the input to the agent model
        :param output_dict: the output of the agent model
        :return:
        """

        agents_update_dict: Dict[Tuple[int, int], np.ndarray] = {}

        world_from_agent = input_dict["world_from_agent"]
        yaw = input_dict["yaw"]
        pred_trs = transform_points(output_dict["positions"][:, :1],
                                    world_from_agent)[:, 0]
        pred_yaws = yaw + output_dict["yaws"][:, 0, 0]

        next_agents = np.zeros(len(yaw), dtype=AGENT_DTYPE)
        next_agents["centroid"] = pred_trs
        next_agents["yaw"] = pred_yaws
        next_agents["track_id"] = input_dict["track_id"]
        next_agents["extent"] = input_dict["extent"]

        next_agents["label_probabilities"][:, PERCEPTION_LABEL_TO_INDEX[
            "PERCEPTION_LABEL_CAR"]] = 1

        for scene_idx, next_agent in zip(input_dict["scene_index"],
                                         next_agents):
            agents_update_dict[(scene_idx,
                                next_agent["track_id"])] = np.expand_dims(
                                    next_agent, 0)
        dataset.set_agents(frame_idx, agents_update_dict)
예제 #3
0
def calculate_non_kinematic_rescale_params(sim_dataset: SimulationDataset) -> NonKinematicActionRescaleParams:
    """Calculate the action un-normalization parameters from the simulation dataset for non-kinematic model.

    :param sim_dataset: the input dataset to calculate the action rescale parameters
    :return: the unnormalized action
    """
    x_component_frames = []
    y_component_frames = []
    yaw_component_frames = []

    for index in range(1, len(sim_dataset) - 1):
        ego_input = sim_dataset.rasterise_frame_batch(index)
        x_component_frames.append([scene['target_positions'][0, 0] for scene in ego_input])
        y_component_frames.append([scene['target_positions'][0, 1] for scene in ego_input])
        yaw_component_frames.append([scene['target_yaws'][0, 0] for scene in ego_input])

    x_components = np.concatenate(x_component_frames)
    y_components = np.concatenate(y_component_frames)
    yaw_components = np.concatenate(yaw_component_frames)

    x_mu, x_std = np.mean(x_components), np.std(x_components)
    y_mu, y_std = np.mean(y_components), np.std(y_components)
    yaw_mu, yaw_std = np.mean(yaw_components), np.std(yaw_components)

    # Keeping scale = 10 * std so that extreme values are not clipped
    return NonKinematicActionRescaleParams(x_mu, 10 * x_std, y_mu, 10 * y_std, yaw_mu, 10 * yaw_std)
예제 #4
0
    def update_ego(dataset: SimulationDataset, frame_idx: int, input_dict: Dict[str, np.ndarray],
                   output_dict: Dict[str, np.ndarray]) -> None:
        """Update ego across scenes for the given frame index.

        :param dataset: The simulation dataset
        :param frame_idx: index of the frame to modify
        :param input_dict: the input to the ego model
        :param output_dict: the output of the ego model
        :return:
        """
        world_from_agent = input_dict["world_from_agent"]
        yaw = input_dict["yaw"]
        pred_trs = transform_points(output_dict["positions"][:, :1], world_from_agent)
        pred_yaws = np.expand_dims(yaw, -1) + output_dict["yaws"][:, :1, 0]

        dataset.set_ego(frame_idx, 0, pred_trs, pred_yaws)
예제 #5
0
def test_invalid_simulation_dataset(zarr_cat_dataset: ChunkedDataset,
                                    dmg: LocalDataManager, cfg: dict,
                                    tmp_path: Path) -> None:
    rasterizer = build_rasterizer(cfg, dmg)

    scene_indices = [0, len(zarr_cat_dataset.scenes)]

    ego_dataset = EgoDataset(cfg, zarr_cat_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=False,
                               distance_th_far=30,
                               distance_th_close=10)
    with pytest.raises(ValueError):
        SimulationDataset.from_dataset_indices(ego_dataset, scene_indices,
                                               sim_cfg)
예제 #6
0
def test_simulation_agents_mock_insert(dmg: LocalDataManager, cfg: dict,
                                       tmp_path: Path) -> None:
    zarr_dataset = _mock_dataset()
    rasterizer = build_rasterizer(cfg, dmg)

    ego_dataset = EgoDataset(cfg, zarr_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=True,
                               distance_th_far=100,
                               distance_th_close=10)
    dataset = SimulationDataset.from_dataset_indices(ego_dataset, [0], sim_cfg)

    _ = dataset.rasterise_agents_frame_batch(0)

    # insert (0, 1) in following frames
    next_agent = np.zeros(1, dtype=AGENT_DTYPE)
    next_agent["centroid"] = (-1, -1)
    next_agent["yaw"] = -0.5
    next_agent["track_id"] = 1
    next_agent["extent"] = (1, 1, 1)
    next_agent["label_probabilities"][:, 3] = 1

    for frame_idx in [1, 2, 3]:
        dataset.set_agents(frame_idx, {(0, 1): next_agent})

        agents_dict = dataset.rasterise_agents_frame_batch(frame_idx)
        assert len(agents_dict) == 1 and (0, 1) in agents_dict
        assert np.allclose(agents_dict[(0, 1)]["centroid"], (-1, -1))
        assert np.allclose(agents_dict[(0, 1)]["yaw"], -0.5)
예제 #7
0
def test_simulation_agents_mock_disable(dmg: LocalDataManager, cfg: dict,
                                        tmp_path: Path) -> None:
    zarr_dataset = _mock_dataset()
    rasterizer = build_rasterizer(cfg, dmg)

    ego_dataset = EgoDataset(cfg, zarr_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=True,
                               distance_th_far=100,
                               distance_th_close=10)
    dataset = SimulationDataset.from_dataset_indices(ego_dataset, [0], sim_cfg)

    # nothing should be tracked
    assert len(dataset._agents_tracked) == 0

    agents_dict = dataset.rasterise_agents_frame_batch(0)

    # only (0, 1) should be in
    assert len(agents_dict) == 1 and (0, 1) in agents_dict
    assert len(dataset._agents_tracked) == 1

    agents_dict = dataset.rasterise_agents_frame_batch(1)

    # again, only (0, 1) should be in
    assert len(agents_dict) == 1
    assert (0, 1) in agents_dict
    assert len(dataset._agents_tracked) == 1

    agents_dict = dataset.rasterise_agents_frame_batch(2)
    assert len(agents_dict) == 0
    assert len(dataset._agents_tracked) == 0
예제 #8
0
def test_simulation_agents(zarr_cat_dataset: ChunkedDataset,
                           dmg: LocalDataManager, cfg: dict,
                           tmp_path: Path) -> None:
    rasterizer = build_rasterizer(cfg, dmg)

    scene_indices = list(range(len(zarr_cat_dataset.scenes)))

    ego_dataset = EgoDataset(cfg, zarr_cat_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=False,
                               distance_th_far=100,
                               distance_th_close=30)
    dataset = SimulationDataset.from_dataset_indices(ego_dataset,
                                                     scene_indices, sim_cfg)

    # nothing should be tracked
    assert len(dataset._agents_tracked) == 0

    agents_dict = dataset.rasterise_agents_frame_batch(0)

    # we should have the same agents in each scene
    for k in agents_dict:
        assert (0, k[1]) in agents_dict

    # now everything should be tracked
    assert len(dataset._agents_tracked) == len(agents_dict)
예제 #9
0
    def unroll(self, scene_indices: List[int]) -> List[SimulationOutput]:
        """
        Simulate the dataset for the given scene indices
        :param scene_indices: the scene indices we want to simulate
        :return: the simulated dataset
        """
        sim_dataset = SimulationDataset.from_dataset_indices(self.dataset, scene_indices, self.sim_cfg)

        agents_ins_outs: DefaultDict[int, List[List[UnrollInputOutput]]] = defaultdict(list)
        ego_ins_outs: DefaultDict[int, List[UnrollInputOutput]] = defaultdict(list)

        for frame_index in tqdm(range(len(sim_dataset)), disable=not self.sim_cfg.show_info):
            next_frame_index = frame_index + 1
            should_update = next_frame_index != len(sim_dataset)

            # AGENTS
            if not self.sim_cfg.use_agents_gt:
                agents_input = sim_dataset.rasterise_agents_frame_batch(frame_index)
                if len(agents_input):  # agents may not be available
                    agents_input_dict = default_collate(list(agents_input.values()))
                    agents_output_dict = self.model_agents(move_to_device(agents_input_dict, self.device))

                    # for update we need everything as numpy
                    agents_input_dict = move_to_numpy(agents_input_dict)
                    agents_output_dict = move_to_numpy(agents_output_dict)

                    if should_update:
                        self.update_agents(sim_dataset, next_frame_index, agents_input_dict, agents_output_dict)

                    # update input and output buffers
                    agents_frame_in_out = self.get_agents_in_out(agents_input_dict, agents_output_dict,
                                                                 self.keys_to_exclude)
                    for scene_idx in scene_indices:
                        agents_ins_outs[scene_idx].append(agents_frame_in_out.get(scene_idx, []))

            # EGO
            if not self.sim_cfg.use_ego_gt:
                ego_input = sim_dataset.rasterise_frame_batch(frame_index)
                ego_input_dict = default_collate(ego_input)
                ego_output_dict = self.model_ego(move_to_device(ego_input_dict, self.device))

                ego_input_dict = move_to_numpy(ego_input_dict)
                ego_output_dict = move_to_numpy(ego_output_dict)

                if should_update:
                    self.update_ego(sim_dataset, next_frame_index, ego_input_dict, ego_output_dict)

                ego_frame_in_out = self.get_ego_in_out(ego_input_dict, ego_output_dict, self.keys_to_exclude)
                for scene_idx in scene_indices:
                    ego_ins_outs[scene_idx].append(ego_frame_in_out[scene_idx])

        simulated_outputs: List[SimulationOutput] = []
        for scene_idx in scene_indices:
            simulated_outputs.append(SimulationOutput(scene_idx, sim_dataset, ego_ins_outs, agents_ins_outs))
        return simulated_outputs
예제 #10
0
    def reset(self) -> Dict[str, np.ndarray]:
        """ Resets the environment and outputs first frame of a new scene sample.

        :return: the observation of first frame of sampled scene index
        """
        # Define in / outs for new episode scene
        self.agents_ins_outs: DefaultDict[
            int, List[List[UnrollInputOutput]]] = defaultdict(list)
        self.ego_ins_outs: DefaultDict[
            int, List[UnrollInputOutput]] = defaultdict(list)

        # Select Scene ID
        self.scene_index = self.np_random.randint(0, self.max_scene_id)
        if self.reset_scene_id is not None:
            self.scene_index = min(self.reset_scene_id, self.max_scene_id - 1)
            self.reset_scene_id += 1

        # Select Frame ID (within bounds of the scene)
        if self.randomize_start_frame:
            scene_length = len(self.dataset.get_scene_indices(
                self.scene_index))
            self.eps_length = self.sim_cfg.num_simulation_steps or scene_length
            end_frame = scene_length - self.eps_length
            self.sim_cfg.start_frame_index = self.np_random.randint(
                0, end_frame + 1)

        # Prepare episode scene
        self.sim_dataset = SimulationDataset.from_dataset_indices(
            self.dataset, [self.scene_index], self.sim_cfg)

        # Reset CLE evaluator
        self.reward.reset()

        # Output first observation
        self.frame_index = 1  # Frame_index 1 has access to the true ego speed
        ego_input = self.sim_dataset.rasterise_frame_batch(self.frame_index)
        self.ego_input_dict = {
            k: np.expand_dims(v, axis=0)
            for k, v in ego_input[0].items()
        }

        # Reset Kinematic model
        if self.use_kinematic:
            init_kin_state = np.array(
                [0.0, 0.0, 0.0, self.step_time * ego_input[0]['curr_speed']])
            self.kin_model.reset(init_kin_state)

        # Only output the image attribute
        obs = {'image': ego_input[0]["image"]}
        return obs
예제 #11
0
def test_visualise(ego_cat_dataset: EgoDataset) -> None:
    mapAPI = ego_cat_dataset.rasterizer.sem_rast.mapAPI  # type: ignore
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=False,
                               distance_th_far=1,
                               distance_th_close=0,
                               num_simulation_steps=10)
    sim_dataset = SimulationDataset.from_dataset_indices(
        ego_cat_dataset, [0, 1], sim_cfg)
    sim_out = SimulationOutput(0,
                               sim_dataset,
                               ego_ins_outs=defaultdict(list),
                               agents_ins_outs=defaultdict(list))

    # ensure we can call the visualize
    visualize(0, simulation_out_to_visualizer_scene(sim_out, mapAPI))
예제 #12
0
    def _get_non_kin_rescale_params(self,
                                    max_num_scenes: int = 10
                                    ) -> NonKinematicActionRescaleParams:
        """Determine the action un-normalization parameters for the non-kinematic model
        from the current dataset in the L5Kit environment.

        :param max_num_scenes: maximum number of scenes to consider to determine parameters
        :return: Tuple of the action un-normalization parameters for non-kinematic model
        """
        scene_ids = list(range(self.max_scene_id)) if not self.overfit else [
            self.overfit_scene_id
        ]
        if len(scene_ids) > max_num_scenes:  # If too many scenes, CPU crashes
            scene_ids = scene_ids[:max_num_scenes]
        sim_dataset = SimulationDataset.from_dataset_indices(
            self.dataset, scene_ids, self.sim_cfg)
        return calculate_non_kinematic_rescale_params(sim_dataset)
예제 #13
0
def test_simulation_ego(zarr_cat_dataset: ChunkedDataset,
                        dmg: LocalDataManager, cfg: dict,
                        tmp_path: Path) -> None:
    rasterizer = build_rasterizer(cfg, dmg)

    scene_indices = list(range(len(zarr_cat_dataset.scenes)))

    ego_dataset = EgoDataset(cfg, zarr_cat_dataset, rasterizer)
    sim_cfg = SimulationConfig(use_ego_gt=True,
                               use_agents_gt=True,
                               disable_new_agents=False,
                               distance_th_far=30,
                               distance_th_close=10)
    dataset = SimulationDataset.from_dataset_indices(ego_dataset,
                                                     scene_indices, sim_cfg)

    # this also ensure order is checked
    assert list(dataset.scene_dataset_batch.keys()) == scene_indices

    # ensure we can call the aggregated get frame
    out_0 = dataset.rasterise_frame_batch(0)
    assert len(out_0) == len(scene_indices)
    out_last = dataset.rasterise_frame_batch(len(dataset) - 1)
    assert len(out_last) == len(scene_indices)
    with pytest.raises(IndexError):
        _ = dataset.rasterise_frame_batch(len(dataset))

    # ensure we can set the ego in multiple frames for all scenes
    frame_indices = np.random.randint(0, len(dataset), 10)
    for frame_idx in frame_indices:
        mock_tr = np.random.rand(len(scene_indices), 12, 2)
        mock_yaw = np.random.rand(len(scene_indices), 12)

        dataset.set_ego(frame_idx, 0, mock_tr, mock_yaw)

        for scene_idx in scene_indices:
            scene_zarr = dataset.scene_dataset_batch[scene_idx].dataset
            ego_tr = scene_zarr.frames["ego_translation"][frame_idx]
            ego_yaw = rotation33_as_yaw(
                scene_zarr.frames["ego_rotation"][frame_idx])

            assert np.allclose(mock_tr[scene_idx, 0], ego_tr[:2])
            assert np.allclose(mock_yaw[scene_idx, 0], ego_yaw)