def __init__(self, action_space, action_space_converter=None, **kwargs_converter): self.action_space_converter = action_space_converter self.init_action_space = action_space if action_space_converter is None: Agent.__init__(self, action_space) else: if isinstance(action_space_converter, type): if issubclass(action_space_converter, Converter): Agent.__init__(self, action_space_converter(action_space)) else: raise Grid2OpException( "Impossible to make an Agent with a converter of type {}. " "Please use a converter deriving from grid2op.ActionSpaceConverter.Converter." "".format(action_space_converter)) elif isinstance(action_space_converter, Converter): if isinstance(action_space_converter.template_act, self.init_action_space.template_act): Agent.__init__(self, action_space_converter) else: raise Grid2OpException( "Impossible to make an Agent with the provided converter of type {}. " "It doesn't use the same type of action as the Agent's action space." "".format(action_space_converter)) else: raise Grid2OpException( "You try to initialize and Agent with an invalid converter \"{}\". It must" "either be a type deriving from \"Converter\", or an instance of a class" "deriving from it." "".format(action_space_converter)) self.action_space.init_converter(**kwargs_converter)
def from_disk(cls, agent_path, name=str(1)): if agent_path is None: # TODO: proper exception raise Grid2OpException("A path to an episode should be provided") episode_path = os.path.abspath(os.path.join(agent_path, name)) try: with open(os.path.join(episode_path, EpisodeData.PARAMS)) as f: _parameters = json.load(fp=f) with open(os.path.join(episode_path, EpisodeData.META)) as f: episode_meta = json.load(fp=f) with open(os.path.join(episode_path, EpisodeData.TIMES)) as f: episode_times = json.load(fp=f) with open(os.path.join(episode_path, EpisodeData.OTHER_REWARDS)) as f: other_rewards = json.load(fp=f) times = np.load( os.path.join(episode_path, EpisodeData.AG_EXEC_TIMES)) actions = np.load(os.path.join(episode_path, EpisodeData.ACTIONS)) env_actions = np.load( os.path.join(episode_path, EpisodeData.ENV_ACTIONS)) observations = np.load( os.path.join(episode_path, EpisodeData.OBSERVATIONS)) disc_lines = np.load( os.path.join(episode_path, EpisodeData.LINES_FAILURES)) rewards = np.load(os.path.join(episode_path, EpisodeData.REWARDS)) except FileNotFoundError as ex: raise Grid2OpException(f"EpisodeData file not found \n {str(ex)}") observation_space = ObservationSpace.from_dict( os.path.join(agent_path, EpisodeData.OBS_SPACE)) action_space = ActionSpace.from_dict( os.path.join(agent_path, EpisodeData.ACTION_SPACE)) helper_action_env = ActionSpace.from_dict( os.path.join(agent_path, EpisodeData.ENV_MODIF_SPACE)) return cls(actions, env_actions, observations, rewards, disc_lines, times, _parameters, episode_meta, episode_times, observation_space, action_space, helper_action_env, agent_path, name=name, get_dataframes=True, other_rewards=other_rewards)
def extract_from_dict(dict_, key, converter): if not key in dict_: raise Grid2OpException( "Impossible to find key \"{}\" while loading the dictionnary.". format(key)) try: res = converter(dict_[key]) except: raise Grid2OpException( "Impossible to convert \"{}\" into class {}".format( key, converter)) return res
def __getitem__(self, i): if isinstance(i, slice) or i < len(self): return self.objects[i] else: raise Grid2OpException( f"Trying to reach {self.elem_name} {i + 1} but " f"there are only {len(self)} {self.collection_name}.")
def initialize(self, env): if not env.redispatching_unit_commitment_availble: raise Grid2OpException("Impossible to use the EconomicReward reward with an environment without generators" "cost. Please make sure env.redispatching_unit_commitment_availble is available.") self.worst_cost = np.sum(env.gen_cost_per_MW *env.gen_pmax) self.reward_min = -1. self.reward_max = self.worst_cost
def save_to_dict(res_dict, me, key, converter): if not key in me.__dict__: raise Grid2OpException( "Impossible to find key \"{}\" while loading the dictionnary.". format(key)) try: res = converter(me.__dict__[key]) except: raise Grid2OpException( "Impossible to convert \"{}\" into class {}".format( key, converter)) if key in res_dict: msg_err_ = "Key \"{}\" is already present in the result dictionnary. This would override it" \ " and is not supported." raise Grid2OpException(msg_err_.format(key)) res_dict[key] = res
def __init__(self, legalActClass=AllwaysLegal): """ Parameters ---------- legalActClass: ``type`` The class that will be used to tell if the actions are legal or not. The class must be given, and not an object of this class. It should derived from :class:`LegalAction`. """ if not isinstance(legalActClass, type): raise Grid2OpException( "Parameter \"legalActClass\" used to build the GameRules should be a type (a class) and not an object (an instance of a class). It is currently \"{}\"" .format(type(rewardClass))) if not issubclass(legalActClass, LegalAction): raise Grid2OpException( "Gamerules: legalActClass should be initialize with a class deriving from LegalAction and not {}" .format(type(legalActClass))) self.legal_action = legalActClass()
def initialize(self, env): if not env.redispatching_unit_commitment_availble: raise Grid2OpException("Impossible to use the RedispReward reward with an environment without generators" "cost. Please make sure env.redispatching_unit_commitment_availble is available.") worst_marginal_cost = np.max(env.gen_cost_per_MW) worst_load = np.sum(env.gen_pmax) worst_losses = 0.05 * worst_load # it's not the worst, but definitely an upper bound worst_redisp = self.alpha_redisph * np.sum(env.gen_pmax) # not realistic, but an upper bound self.max_regret = (worst_losses + worst_redisp)*worst_marginal_cost self.reward_min = -10 least_loads = (worst_load * 0.5) # half the capacity of the grid least_losses = 0.015 * least_loads # 1.5% of losses least_redisp = 0. # lower_bound is 0 base_marginal_cost = np.min(env.gen_cost_per_MW[env.gen_cost_per_MW > 0.]) min_regret = (least_losses + least_redisp) * base_marginal_cost self.reward_max = (self.max_regret - min_regret) / least_loads
def __init__(self, collection, helper, collection_name): self.collection = collection if not hasattr(helper, "from_vect"): raise Grid2OpException(f"Object {helper} must implement a " f"from_vect methode.") self.helper = helper self.collection_name = collection_name self.elem_name = self.collection_name[:-1] self.i = 0 self._game_over = None self.objects = [] for i, elem in enumerate(self.collection): try: self.objects.append( self.helper.from_vect(self.collection[i, :])) except AmbiguousAction: self._game_over = i break
def __init__(self, substation_layout, observation_space, radius_sub=20., load_prod_dist=70., bus_radius=6.): if substation_layout is None: raise Grid2OpException( "Impossible to use plotting abilities without specifying a layout (coordinates) " "of the substations.") GridObjects.__init__(self) self.init_grid(observation_space) self.observation_space = observation_space self._layout = {} self._layout["substations"] = self._get_sub_layout(substation_layout) self.radius_sub = radius_sub self.load_prod_dist = load_prod_dist # distance between load and generator to the center of the substation self.bus_radius = bus_radius self.subs_elements = [None for _ in self.observation_space.sub_info] # get the element in each substation for sub_id in range(self.observation_space.sub_info.shape[0]): this_sub = {} objs = self.observation_space.get_obj_connect_to( substation_id=sub_id) for c_id in objs["loads_id"]: c_nm = self._get_load_name(sub_id, c_id) this_load = {} this_load["type"] = "load" this_load["sub_pos"] = self.observation_space.load_to_sub_pos[ c_id] this_sub[c_nm] = this_load for g_id in objs["generators_id"]: g_nm = self._get_gen_name(sub_id, g_id) this_gen = {} this_gen["type"] = "gen" this_gen["sub_pos"] = self.observation_space.gen_to_sub_pos[ g_id] this_sub[g_nm] = this_gen for lor_id in objs["lines_or_id"]: ext_id = self.observation_space.line_ex_to_subid[lor_id] l_nm = self._get_line_name(sub_id, ext_id, lor_id) this_line = {} this_line["type"] = "line" this_line[ "sub_pos"] = self.observation_space.line_or_to_sub_pos[ lor_id] this_sub[l_nm] = this_line for lex_id in objs["lines_ex_id"]: or_id = self.observation_space.line_or_to_subid[lex_id] l_nm = self._get_line_name(or_id, sub_id, lex_id) this_line = {} this_line["type"] = "line" this_line[ "sub_pos"] = self.observation_space.line_ex_to_sub_pos[ lex_id] this_sub[l_nm] = this_line self.subs_elements[sub_id] = this_sub self._compute_layout()