Exemple #1
0
    def __init__(self, client, vehicle_model, route, sensors,
                 scenario_definitions, exp_params, agent_name):
        """
        The experience is like a instance of the environment
         contains all the objects (vehicles, sensors) and scenarios of the the current experience
        :param vehicle_model: the model that is going to be used to spawn the ego CAR
        """

        # We save the agent name for data savings
        self._agent_name = agent_name

        # save all the experiment parameters to be used later
        self._exp_params = exp_params
        # carla recorder mode save the full carla logs to do some replays
        if self._exp_params['carla_recording']:
            client.start_recorder('env_{}_number_{}_batch_{:0>4d}.log'.format(
                self._exp_params['env_name'], self._exp_params['env_number'],
                self._exp_params['exp_number']))
        # this parameter sets all the sensor threads and the main thread into saving data
        self._save_data = exp_params['save_data']
        # we can also toogle if we want to save sensors or not.
        self._save_sensors = exp_params['save_sensors']
        # Start objects that are going to be created
        self.world = None
        # You try to reconnect a few times.
        self.MAX_CONNECTION_ATTEMPTS = 7
        # Scenario definitions to perform the scenario building
        self.scenario_definitions = scenario_definitions
        self._ego_actor = None
        self._instanced_sensors = []
        # set the client object connected to the
        self._client = client
        # We also set the town name to be used
        self._town_name = exp_params['town_name']

        self._vehicle_model = vehicle_model
        # if data is being saved we create the writer object

        # if we are going to save, we keep track of a dictionary with all the data
        self._writer = Writer(exp_params['package_name'],
                              exp_params['env_name'],
                              exp_params['env_number'],
                              exp_params['exp_number'],
                              agent_name,
                              other_vehicles=exp_params['save_opponents'],
                              walkers=exp_params['save_walkers'])

        self._environment_data = {
            'exp_measurements':
            None,  # The exp measurements are specific of the experience
            'ego_controls': None,
            'scenario_controls': None
        }
        # identify this exp
        self._exp_id = self._exp_params['exp_number']

        # We try running all the necessary initalization, if we fail we clean the
        try:
            # Sensor interface, a buffer that contains all the read sensors
            self._sensor_interface = SensorInterface(
                number_threads_barrier=len(sensors))
            # Load the world
            self._load_world()
            # Set the actor pool so the scenarios can prepare themselves when needed
            CarlaDataProvider.set_client(client)
            CarlaDataProvider.set_world(self.world)
            # Set the world for the global data provider
            CarlaDataProvider.set_world(self.world)
            # We get the lat lon ref that is important for the route
            self._lat_ref, self._lon_ref = _get_latlon_ref(self.world)
            # We instance the ego actor object
            _, self._route = interpolate_trajectory(self.world, route)
            # elevate the z transform to avoid spawning problems
            elevate_transform = self._route[0][0]
            elevate_transform.location.z += 0.5
            self._spawn_ego_car(elevate_transform)
            # We setup all the instanced sensors
            self._setup_sensors(sensors, self._ego_actor)
            # We set all the traffic lights to green to avoid having this traffic scenario.
            self._reset_map()
            # Data for building the master scenario
            self._timeout = estimate_route_timeout(self._route)
            self._master_scenario = self.build_master_scenario(
                self._route, exp_params['town_name'], self._timeout)
            other_scenarios = self.build_scenario_instances(
                scenario_definitions, self._timeout)
            self._list_scenarios = [self._master_scenario] + other_scenarios
            # Route statistics, when the route is finished there will
            # be route statistics on this object. and nothing else
            self._route_statistics = None
            # We tick the world to have some starting points
            self.tick_world()
        except RuntimeError as r:
            # We clean the dataset if there is any exception on creation
            traceback.print_exc()
            if self._save_data:
                self._clean_bad_dataset()
            # Re raise the exception
            raise r
Exemple #2
0
class Experience(object):
    def __init__(self, client, vehicle_model, route, sensors,
                 scenario_definitions, exp_params, agent_name):
        """
        The experience is like a instance of the environment
         contains all the objects (vehicles, sensors) and scenarios of the the current experience
        :param vehicle_model: the model that is going to be used to spawn the ego CAR
        """

        # We save the agent name for data savings
        self._agent_name = agent_name

        # save all the experiment parameters to be used later
        self._exp_params = exp_params
        # carla recorder mode save the full carla logs to do some replays
        if self._exp_params['carla_recording']:
            client.start_recorder('env_{}_number_{}_batch_{:0>4d}.log'.format(
                self._exp_params['env_name'], self._exp_params['env_number'],
                self._exp_params['exp_number']))
        # this parameter sets all the sensor threads and the main thread into saving data
        self._save_data = exp_params['save_data']
        # we can also toogle if we want to save sensors or not.
        self._save_sensors = exp_params['save_sensors']
        # Start objects that are going to be created
        self.world = None
        # You try to reconnect a few times.
        self.MAX_CONNECTION_ATTEMPTS = 7
        # Scenario definitions to perform the scenario building
        self.scenario_definitions = scenario_definitions
        self._ego_actor = None
        self._instanced_sensors = []
        # set the client object connected to the
        self._client = client
        # We also set the town name to be used
        self._town_name = exp_params['town_name']

        self._vehicle_model = vehicle_model
        # if data is being saved we create the writer object

        # if we are going to save, we keep track of a dictionary with all the data
        self._writer = Writer(exp_params['package_name'],
                              exp_params['env_name'],
                              exp_params['env_number'],
                              exp_params['exp_number'],
                              agent_name,
                              other_vehicles=exp_params['save_opponents'],
                              walkers=exp_params['save_walkers'])

        self._environment_data = {
            'exp_measurements':
            None,  # The exp measurements are specific of the experience
            'ego_controls': None,
            'scenario_controls': None
        }
        # identify this exp
        self._exp_id = self._exp_params['exp_number']

        # We try running all the necessary initalization, if we fail we clean the
        try:
            # Sensor interface, a buffer that contains all the read sensors
            self._sensor_interface = SensorInterface(
                number_threads_barrier=len(sensors))
            # Load the world
            self._load_world()
            # Set the actor pool so the scenarios can prepare themselves when needed
            CarlaDataProvider.set_client(client)
            CarlaDataProvider.set_world(self.world)
            # Set the world for the global data provider
            CarlaDataProvider.set_world(self.world)
            # We get the lat lon ref that is important for the route
            self._lat_ref, self._lon_ref = _get_latlon_ref(self.world)
            # We instance the ego actor object
            _, self._route = interpolate_trajectory(self.world, route)
            # elevate the z transform to avoid spawning problems
            elevate_transform = self._route[0][0]
            elevate_transform.location.z += 0.5
            self._spawn_ego_car(elevate_transform)
            # We setup all the instanced sensors
            self._setup_sensors(sensors, self._ego_actor)
            # We set all the traffic lights to green to avoid having this traffic scenario.
            self._reset_map()
            # Data for building the master scenario
            self._timeout = estimate_route_timeout(self._route)
            self._master_scenario = self.build_master_scenario(
                self._route, exp_params['town_name'], self._timeout)
            other_scenarios = self.build_scenario_instances(
                scenario_definitions, self._timeout)
            self._list_scenarios = [self._master_scenario] + other_scenarios
            # Route statistics, when the route is finished there will
            # be route statistics on this object. and nothing else
            self._route_statistics = None
            # We tick the world to have some starting points
            self.tick_world()
        except RuntimeError as r:
            # We clean the dataset if there is any exception on creation
            traceback.print_exc()
            if self._save_data:
                self._clean_bad_dataset()
            # Re raise the exception
            raise r

    def tick_scenarios(self):

        # We tick the scenarios to get them started
        for scenario in self._list_scenarios:
            scenario.scenario.scenario_tree.tick_once()

    def get_status(self):
        """
            Returns the current status of the vehicle
        """
        if self._master_scenario is None:
            raise ValueError(
                'You should not run a route without a master scenario')

        if self._master_scenario.scenario.scenario_tree.status == py_trees.common.Status.INVALID:
            logging.debug("Exp No:{} The current scenario is INVALID".format(
                self._exp_id))
            status = 'INVALID'
        elif self._master_scenario.scenario.scenario_tree.status == py_trees.common.Status.SUCCESS:
            logging.debug(
                "Exp No:{} The current scenario is SUCCESSFUL".format(
                    self._exp_id))
            status = 'SUCCESS'
        elif self._master_scenario.scenario.scenario_tree.status == py_trees.common.Status.FAILURE:
            logging.debug("Exp No:{} The current scenario is FAILURE".format(
                self._exp_id))
            status = 'FAILURE'
        else:
            status = 'RUNNING'

        return status

    def tick_scenarios_control(self, controls):
        """
        Here we tick the scenarios and also change the control based on the scenario properties
        """

        GameTime.on_carla_tick(self.world.get_snapshot().timestamp)
        CarlaDataProvider.on_carla_tick()

        for scenario in self._list_scenarios:  #
            scenario.scenario.scenario_tree.tick_once()
            controls = scenario.change_control(controls)

        if self._save_data:
            self._environment_data['ego_controls'] = controls

        return controls

    def apply_control(self, controls):
        # Add the control to the ego agent controls.

        if self._save_data:
            self._environment_data['scenario_controls'] = controls
        self._ego_actor.apply_control(controls)

        if self._exp_params['debug']:
            spectator = self.world.get_spectator()
            ego_trans = self._ego_actor.get_transform()
            spectator.set_transform(
                carla.Transform(ego_trans.location + carla.Location(z=50),
                                carla.Rotation(pitch=-90)))

    def tick_world(self):
        # Save all the measurements that are interesting

        if self._save_data:
            _, directions = self._get_current_wp_direction(
                self._ego_actor.get_transform().location, self._route)

            # HERE we may adapt the npc to stop dist_scenario3

            self._environment_data['exp_measurements'] = {
                'directions': directions
            }

        self._sync(self.world.tick())

    def _sync(self, frame):
        while frame > self.world.get_snapshot().timestamp.frame:
            pass
        assert frame == self.world.get_snapshot().timestamp.frame
        self.frame = frame

    def save_experience(self, affordances):

        if self._save_data:
            self._sensor_interface.wait_sensors_written(self._writer)
            self._writer.save_experience(self.world, self._environment_data,
                                         affordances)

    def is_running(self):
        """
            The master scenario tests if the route is still running for this experiment
        """
        if self._master_scenario is None:
            raise ValueError(
                'You should not run a route without a master scenario')

        return self._master_scenario.scenario.scenario_tree.status == py_trees.common.Status.RUNNING \
                or self._master_scenario.scenario.scenario_tree.status == py_trees.common.Status.INVALID

    """
        FUNCTIONS FOR BUILDING 
    """

    def _spawn_ego_car(self, start_transform):
        """
        Spawn or update all scenario actors according to
        a certain start position.
        """
        # If ego_vehicle already exists, just update location
        # Otherwise spawn ego vehicle
        self._ego_actor = CarlaDataProvider.request_new_actor(
            self._vehicle_model, start_transform)

        CarlaDataProvider.set_ego_vehicle_route(
            convert_transform_to_location(self._route))
        logging.debug("Created Ego Vehicle")

    def _setup_sensors(self, sensors, vehicle):
        """
        Create the sensors defined by the user and attach them to the ego-vehicle
        :param sensors: list of sensors
        :param vehicle: ego vehicle
        :return:
        """
        bp_library = self.world.get_blueprint_library()
        for sensor_spec in sensors:
            # These are the pseudosensors (not spawned)
            if sensor_spec['type'].startswith('sensor.can_bus'):
                # The speedometer pseudo sensor is created directly here
                sensor = CANBusSensor(vehicle,
                                      sensor_spec['reading_frequency'])
            # These are the sensors spawned on the carla world
            else:
                bp = bp_library.find(sensor_spec['type'])
                if sensor_spec['type'].startswith('sensor.camera'):
                    bp.set_attribute('image_size_x', str(sensor_spec['width']))
                    bp.set_attribute('image_size_y',
                                     str(sensor_spec['height']))
                    bp.set_attribute('fov', str(sensor_spec['fov']))
                    bp.set_attribute('sensor_tick', "0.05")
                    sensor_location = carla.Location(x=sensor_spec['x'],
                                                     y=sensor_spec['y'],
                                                     z=sensor_spec['z'])
                    sensor_rotation = carla.Rotation(
                        pitch=sensor_spec['pitch'],
                        roll=sensor_spec['roll'],
                        yaw=sensor_spec['yaw'])
                elif sensor_spec['type'].startswith('sensor.lidar'):
                    bp.set_attribute('range', '200')
                    bp.set_attribute('rotation_frequency', '10')
                    bp.set_attribute('channels', '32')
                    bp.set_attribute('upper_fov', '15')
                    bp.set_attribute('lower_fov', '-30')
                    bp.set_attribute('points_per_second', '500000')
                    bp.set_attribute('sensor_tick', "0.05")
                    sensor_location = carla.Location(x=sensor_spec['x'],
                                                     y=sensor_spec['y'],
                                                     z=sensor_spec['z'])
                    sensor_rotation = carla.Rotation(
                        pitch=sensor_spec['pitch'],
                        roll=sensor_spec['roll'],
                        yaw=sensor_spec['yaw'])
                elif sensor_spec['type'].startswith('sensor.other.gnss'):
                    sensor_location = carla.Location(x=sensor_spec['x'],
                                                     y=sensor_spec['y'],
                                                     z=sensor_spec['z'])
                    sensor_rotation = carla.Rotation()

                # create sensor
                sensor_transform = carla.Transform(sensor_location,
                                                   sensor_rotation)
                sensor = self.world.spawn_actor(bp, sensor_transform, vehicle)

            # setup callback
            if self._save_sensors or self._exp_params['make_videos']:
                # We have the options to not save sensors data unless it is to make video
                sensor.listen(
                    CallBack(sensor_spec['id'],
                             sensor,
                             self._sensor_interface,
                             writer=self._writer))
            else:
                sensor.listen(
                    CallBack(sensor_spec['id'],
                             sensor,
                             self._sensor_interface,
                             writer=None))
            self._instanced_sensors.append(sensor)

        # check that all sensors have initialized their data structure
        while not self._sensor_interface.all_sensors_ready():
            logging.debug(" waiting for one data reading from sensors...")
            self._sync(self.world.tick())

    def _get_current_wp_direction(self, vehicle_position, route):

        # for the current position and orientation try to get the closest one from the waypoints
        closest_id = 0
        closest_waypoint = None
        min_distance = 100000
        for index in range(len(route)):
            waypoint = route[index][0]
            computed_distance = distance_vehicle(waypoint, vehicle_position)
            if computed_distance < min_distance:
                min_distance = computed_distance
                closest_id = index
                closest_waypoint = waypoint

        direction = route[closest_id][1]
        if direction == RoadOption.LEFT:
            direction = 3.0
        elif direction == RoadOption.RIGHT:
            direction = 4.0
        elif direction == RoadOption.STRAIGHT:
            direction = 5.0
        else:
            direction = 2.0

        return closest_waypoint, direction

    def _reset_map(self):
        """
        We set all the traffic lights to green to avoid having this scenario.

        """
        ### This was used for L0

        #for actor in self.world.get_actors():
        #    if 'traffic_light' in actor.type_id:
        #        actor.set_state(carla.TrafficLightState.Green)
        #        actor.set_green_time(100000)
        pass
        # TODO for now we are just randomizing the seeds and that is it

    def build_master_scenario(self, route, town_name, timeout):
        # We have to find the target.
        # we also have to convert the route to the expected format
        master_scenario_configuration = ScenarioConfiguration()
        master_scenario_configuration.target = route[-1][
            0]  # Take the last point and add as target.
        master_scenario_configuration.route = convert_transform_to_location(
            route)

        master_scenario_configuration.town = town_name
        master_scenario_configuration.ego_vehicle = ActorConfigurationData(
            'vehicle.lincoln.mkz2017', self._ego_actor.get_transform())
        master_scenario_configuration.trigger_point = self._ego_actor.get_transform(
        )
        CarlaDataProvider.register_actor(self._ego_actor)

        return MasterScenario(self.world, [self._ego_actor],
                              master_scenario_configuration,
                              timeout=timeout)

    def _load_world(self):
        # time continues
        attempts = 0

        while attempts < self.MAX_CONNECTION_ATTEMPTS:
            try:
                self.world = self._client.load_world(self._town_name)
                logging.debug("=============================")
                logging.debug("---------New Episode---------")
                logging.debug("=============================")
                break
            except Exception:
                import traceback
                traceback.print_exc()
                attempts += 1
                print(
                    '======[WARNING] The server is not ready [{}/{} attempts]!!'
                    .format(attempts, self.MAX_CONNECTION_ATTEMPTS))
                time.sleep(2.0)
                continue

        settings = self.world.get_settings()
        settings.no_rendering_mode = self._exp_params['non_rendering_mode']
        settings.synchronous_mode = True
        settings.fixed_delta_seconds = 0.05  # 20 FPS here is fixed WARNING

        self.world.set_weather(self._exp_params['weather_profile'])
        self.world.apply_settings(settings)

    # Todo make a scenario builder class

    def _build_background(self, background_definition, timeout):
        """
        Build background scenario. Adding pedestrians and vehicles wandering
        around.
        :param background_definition:
        :param timeout:
        :return:
        """

        scenario_configuration = ScenarioConfiguration()
        scenario_configuration.route = None
        scenario_configuration.town = self._town_name
        # TODO The random seed should be set.
        # Also the crossing factor should be specified on the benchmark itself.
        configuration_instances_vehicles = []
        configuration_instances_walkers = []
        # If there are walkers there should be cross factors otherwise it is 0
        cross_factor = 0.0

        if 'walker.*' in background_definition:

            model = 'walker'
            transform = carla.Transform()
            autopilot = True
            random_location = True
            actor_configuration_instance = ActorConfigurationData(
                model,
                transform,
                autopilot=autopilot,
                random=random_location,
                amount=int(background_definition['walker.*']),
                category='walker')
            configuration_instances_walkers.append(
                actor_configuration_instance)

            if "cross_factor" not in background_definition:
                raise ValueError(
                    " If there are walkers on the json file "
                    "background scenario there must also be a cross factor")

            cross_factor = background_definition["cross_factor"]

        if 'vehicle.*' in background_definition:
            model = 'vehicle'
            transform = carla.Transform()
            autopilot = True
            random_location = True
            actor_configuration_instance = ActorConfigurationData(
                model,
                transform,
                autopilot=autopilot,
                random=random_location,
                amount=int(background_definition["vehicle.*"]),
                category='vehicle')
            configuration_instances_vehicles.append(
                actor_configuration_instance)

        scenario_configuration.other_actors = configuration_instances_vehicles + \
                                              configuration_instances_walkers

        return BackgroundActivity(self.world,
                                  self._ego_actor,
                                  scenario_configuration,
                                  cross_factor=cross_factor,
                                  timeout=timeout,
                                  debug_mode=False)

    def build_scenario_instances(self, scenario_definition_vec, timeout):
        """
            Based on the parsed route and possible scenarios, build all the scenario classes.
        :param scenario_definition_vec: the dictionary defining the scenarios
        :param town: the town where scenarios are going to be
        :return:
        """
        list_instanced_scenarios = []
        if scenario_definition_vec is None:
            return list_instanced_scenarios

        for scenario_name in scenario_definition_vec:
            # The BG activity encapsulates several scenarios that contain vehicles going arround
            if scenario_name == 'background_activity':  # BACKGROUND ACTIVITY SPECIAL CASE

                background_definition = scenario_definition_vec[scenario_name]
                background = self._build_background(background_definition,
                                                    timeout)

                list_instanced_scenarios.append(background)
            else:

                # Sample the scenarios to be used for this route instance.
                # tehre can be many instances of the same scenario
                scenario_definition_instances = scenario_definition_vec[
                    scenario_name]

                if scenario_definition_instances is None:
                    raise ValueError(" Not Implemented ")

                for scenario_definition in scenario_definition_instances:

                    # TODO scenario 4 is out

                    ScenarioClass = number_class_translation[scenario_name][0]
                    egoactor_trigger_position = convert_json_to_transform(
                        scenario_definition)
                    scenario_configuration = ScenarioConfiguration()
                    scenario_configuration.other_actors = None  # TODO the other actors are maybe needed
                    scenario_configuration.town = self._town_name
                    scenario_configuration.trigger_point = egoactor_trigger_position
                    scenario_configuration.ego_vehicle = ActorConfigurationData(
                        'vehicle.lincoln.mkz2017',
                        self._ego_actor.get_transform())
                    try:
                        scenario_instance = ScenarioClass(
                            self.world,
                            self._ego_actor,
                            scenario_configuration,
                            criteria_enable=False,
                            timeout=timeout)
                    except Exception as e:
                        print("Skipping scenario '{}' due to setup error: {}".
                              format('Scenario3', e))
                        continue
                    # registering the used actors on the data provider so they can be updated.

                    CarlaDataProvider.register_actors(
                        scenario_instance.other_actors)

                    list_instanced_scenarios.append(scenario_instance)

        return list_instanced_scenarios

    def get_summary(self):

        return self._route_statistics

    def record(self):
        self._route_statistics = record_route_statistics_default(
            self._master_scenario, self._exp_params['env_name'] + '_' +
            str(self._exp_params['env_number']) + '_' +
            str(self._exp_params['exp_number']))

        if self._save_data:
            self._writer.save_summary(self._route_statistics)
            if self._exp_params['remove_wrong_data']:
                if self._route_statistics['result'] == 'FAILURE':
                    self._clean_bad_dataset()

        if self._exp_params['make_videos']:
            delete_sensors = not self._exp_params['save_sensors']
            self._writer.make_video(self._sensors_dict)
            if delete_sensors:
                self._writer.delete_sensors()

        if self._exp_params['resize_images']:
            data_path = os.path.join(os.environ["SRL_DATASET_PATH"],
                                     self._exp_params['package_name'])
            save_path = os.path.join(
                os.environ["SRL_DATASET_PATH"],
                self._exp_params['package_name'] + '_resized')
            if not os.path.exists(save_path):
                os.mkdir(save_path)
            print('Resizing images in ', self._exp_params['env_name'])
            metadata_file = glob.glob(
                os.path.join(data_path, self._exp_params['env_name'],
                             '*.json'))
            metadata_name = metadata_file[0].split('/')[-1]
            if not os.path.exists(
                    os.path.join(save_path, self._exp_params['env_name'])):
                os.mkdir(os.path.join(save_path, self._exp_params['env_name']))
            shutil.copy(
                metadata_file[0],
                os.path.join(
                    os.path.join(save_path, self._exp_params['env_name']),
                    metadata_name))
            images_list = glob.glob(
                os.path.join(data_path, self._exp_params['env_name'],
                             '0_Agent', '0', '*.png'))
            files_list = glob.glob(
                os.path.join(data_path, self._exp_params['env_name'],
                             '0_Agent', '0', 'measurements*.json'))
            for image_path in images_list:
                image_name = image_path.split('/')[-1]
                image = scipy.misc.imread(image_path)
                image = image[65:460, :, :]
                image = scipy.misc.imresize(image, (88, 200))
                saving_img_dir = os.path.join(save_path,
                                              self._exp_params['env_name'],
                                              '0_Agent', '0')
                if not os.path.exists(saving_img_dir):
                    os.makedirs(saving_img_dir)
                scipy.misc.imsave(os.path.join(saving_img_dir, image_name),
                                  image)
            for file_path in files_list:
                file_name = file_path.split('/')[-1]
                saving_files_dir = os.path.join(save_path,
                                                self._exp_params['env_name'],
                                                '0_Agent', '0')
                if not os.path.exists(saving_files_dir):
                    os.makedirs(saving_files_dir)
                shutil.copy(file_path, os.path.join(saving_files_dir,
                                                    file_name))
            summary_file_path = os.path.join(data_path,
                                             self._exp_params['env_name'],
                                             '0_Agent', '0', 'summary.json')
            file_name = summary_file_path.split('/')[-1]
            shutil.copy(summary_file_path,
                        os.path.join(saving_files_dir, file_name))
            print('===> Resizing finished ', self._exp_params['env_name'])

    def cleanup(self, ego=True):
        """
        Remove and destroy all actors
        """

        for scenario in self._list_scenarios:
            # Reset scenario status for proper cleanup
            scenario.scenario.terminate()
            # Do not call del here! Directly enforce the actor removal
            scenario.remove_all_actors()
            scenario = None

        self._client.stop_recorder()
        # We need enumerate here, otherwise the actors are not properly removed
        for i, _ in enumerate(self._instanced_sensors):
            if self._instanced_sensors[i] is not None:
                self._instanced_sensors[i].stop()
                self._instanced_sensors[i].destroy()
                self._instanced_sensors[i] = None
        self._instanced_sensors = []
        self._sensor_interface.destroy()
        #  We stop the sensors first to avoid problems

        CarlaDataProvider.cleanup()

        if ego and self._ego_actor is not None:
            self._ego_actor.destroy()
            self._ego_actor = None
            logging.debug("Removed Ego Vehicle")

        if self.world is not None:
            self.world = None

    def _clean_bad_dataset(self):
        # TODO for now only deleting on failure.
        # Basically remove the folder associated with this exp if the status was not success,
        # or if did not achieve the correct ammount of points
        logging.debug("FAILED , DELETING")
        self._writer.delete()