def test_config_unchangeable(): c = Config({"aaa": 100}, unchangeable=True) try: c['aaa'] = 1000 except ValueError as e: print('Great! ', e) assert c['aaa'] == 100
def merge_config(old_dict, new_dict, new_keys_allowed=False): from pgdrive.utils import Config if isinstance(old_dict, Config): old_dict = old_dict.get_dict() if isinstance(new_dict, Config): new_dict = new_dict.get_dict() merged = merge_dicts(old_dict, new_dict, allow_new_keys=new_keys_allowed) return Config(merged)
def test_base_vehicle(): env = PGDriveEnv() try: env.reset() engine = env.engine map = env.current_map # v_config = BaseVehicle.get_vehicle_config(dict()) v_config = Config(BASE_DEFAULT_CONFIG["vehicle_config"]).update( PGDriveEnv_DEFAULT_CONFIG["vehicle_config"]) v = engine.spawn_object(DefaultVehicle, vehicle_config=v_config, random_seed=0) v.add_navigation() v.add_navigation() v.navigation.set_force_calculate_lane_index(True) v.update_map_info(map) for heading in [-1.0, 0.0, 1.0]: for pos in [[0., 0.], [-100., -100.], [100., 100.]]: v.reset(pos=pos, heading=heading) np.testing.assert_almost_equal(_get_heading_deg( v.heading_theta), heading, decimal=3) v_pos = v.position # v_pos[1] = -v_pos[1], this position is converted to pg_position in reset() now np.testing.assert_almost_equal(v_pos, pos) v.set_position(pos) v_pos = v.position np.testing.assert_almost_equal(v_pos, pos) v.after_step() v.reset(pos=np.array([10, 0])) for a_x in [-1, 0, 0.5, 1]: for a_y in [-1, 0, 0.5, 1]: v.before_step([a_x, a_y]) v._set_action([a_x, a_y]) _assert_vehicle(v) v._set_incremental_action([a_x, a_y]) _assert_vehicle(v) state = v.get_state() v.set_state(state) assert _get_heading_deg(v.heading_theta) == _get_heading_deg( state["heading"]) np.testing.assert_almost_equal(v.position, state["position"]) v.projection([a_x, a_y]) _nan_speed(env) v.destroy() del v finally: env.close()
def _create_vehicle(): v_config = Config(BASE_DEFAULT_CONFIG["vehicle_config"]).update( PGDriveEnv_DEFAULT_CONFIG["vehicle_config"]) v_config.update({"use_render": False, "offscreen_render": False}) config = Config(BASE_DEFAULT_CONFIG) config.update({ "use_render": False, "pstats": False, "offscreen_render": False, "debug": False, "vehicle_config": v_config }) initialize_engine(config) v = DefaultVehicle(vehicle_config=v_config, random_seed=0) return v
def _update_dict_item(self, k, v, allow_overwrite): if not isinstance(v, (dict, Config)): if allow_overwrite: return False else: raise TypeError( "Type error! The item {} has original type {} and updating type {}.".format( k, type(self[k]), type(v) ) ) if not isinstance(self[k], Config): self._set_item(k, Config(self[k]), allow_overwrite) self[k].update(v, allow_add_new_key=allow_overwrite) return True
def _auto_fill_spawn_roads_randomly(self, spawn_roads): """It is used for shuffling the config""" num_slots = int( floor(self.exit_length / SpawnManager.RESPAWN_REGION_LONGITUDE)) interval = self.exit_length / num_slots self._longitude_spawn_interval = interval if self.num_agents is not None: assert self.num_agents > 0 or self.num_agents == -1 assert self.num_agents <= self.max_capacity( spawn_roads, self.exit_length + FirstPGBlock.ENTRANCE_LENGTH, self.lane_num ), ("Too many agents! We only accepet {} agents, but you have {} agents!" .format(self.lane_num * len(spawn_roads) * num_slots, self.num_agents)) # We can spawn agents in the middle of road at the initial time, but when some vehicles need to be respawn, # then we have to set it to the farthest places to ensure safety (otherwise the new vehicles may suddenly # appear at the middle of the road!) target_vehicle_configs = [] safe_spawn_places = [] for i, road in enumerate(spawn_roads): for lane_idx in range(self.lane_num): for j in range(num_slots): long = 1 / 2 * self.RESPAWN_REGION_LONGITUDE + j * self.RESPAWN_REGION_LONGITUDE lane_tuple = road.lane_index( lane_idx) # like (>>>, 1C0_0_, 1) and so on. target_vehicle_configs.append( Config(dict( identifier="|".join( (str(s) for s in lane_tuple + (j, ))), config={ "spawn_lane_index": lane_tuple, "spawn_longitude": long, "spawn_lateral": 0 }, ), unchangeable=True)) # lock the spawn positions if j == 0: safe_spawn_places.append( copy.deepcopy(target_vehicle_configs[-1])) return target_vehicle_configs, safe_spawn_places
def update(self, new_dict: Union[dict, "Config"], allow_add_new_key=True, stop_recursive_update=None): """ Update this dict with extra configs :param new_dict: extra configs :param allow_add_new_key: whether allowing to add new keys to existing configs or not :param stop_recursive_update: Deep update and recursive-check will NOT be applied to keys in stop_recursive_update """ stop_recursive_update = stop_recursive_update or [] new_dict = new_dict or dict() new_dict = copy.deepcopy(new_dict) if not allow_add_new_key: old_keys = set(self._config) new_keys = set(new_dict) diff = new_keys.difference(old_keys) if len(diff) > 0: raise KeyError( "'{}' does not exist in existing config. " "Please use config.update(...) to update the config. Existing keys: {}.".format( diff, self._config.keys() ) ) for k, v in new_dict.items(): if k not in self: if isinstance(v, dict): v = Config(v) self._config[k] = v # Placeholder success = False if isinstance(self._config[k], (dict, Config)): if k not in stop_recursive_update: success = self._update_dict_item(k, v, allow_add_new_key) else: self._set_item(k, v, allow_add_new_key) success = True if not success: self._update_single_item(k, v, allow_add_new_key) if k in self._config and not hasattr(self, k): self.__setattr__(k, self._config[k]) return self
def default_config(cls) -> "Config": return Config(BASE_DEFAULT_CONFIG)
def __init__(self, config: dict = None): self.default_config_copy = Config(self.default_config(), unchangeable=True) super(PGDriveEnv, self).__init__(config)
def copy(self, unchangeable=None): """If unchangeable is None, then just following the original config's setting.""" if unchangeable is None: unchangeable = self._unchangeable return Config(self, unchangeable)