def __init__(self, env_init): check_gym_version() self.init_env = env_init.copy() self.action_space = GymActionSpace(self.init_env) self.observation_space = GymObservationSpace(self.init_env) self.reward_range = self.init_env.reward_range self.metadata = self.init_env.metadata
def __init__(self, dict_gym_space, dict_variables=None): check_gym_version() spaces.Dict.__init__(self, dict_gym_space) self._keys_encoding = {} if dict_variables is not None: for k, v in dict_variables.items(): self._keys_encoding[k] = v self.__func = {}
def __init__(self, space=None, gym_to_g2op=None, g2op_to_gym=None): check_gym_version() self.__is_init_super = False # is the "super" class initialized, do not modify in child class self._is_init_space = False # is the instance initialized self._my_gym_to_g2op = None self._my_g2op_to_gym = None self.my_space = None if self.my_space is not None: self.base_initialize(space, gym_to_g2op, g2op_to_gym)
def __init__(self, grid2op_observation_space, attr_to_keep=ALL_ATTR_OBS, subtract=None, divide=None, functs=None): check_gym_version() if not isinstance(grid2op_observation_space, ObservationSpace): raise RuntimeError( f"Impossible to create a BoxGymObsSpace without providing a " f"grid2op observation. You provided {type(grid2op_observation_space)}" f"as the \"grid2op_observation_space\" attribute.") self._attr_to_keep = sorted(attr_to_keep) ob_sp = grid2op_observation_space tol_redisp = ob_sp.obs_env._tol_poly # add to gen_p otherwise ... well it can crash extra_for_losses = _compute_extra_power_for_losses(ob_sp) self.dict_properties = { "year": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 2200, (1, ), dt_int), "month": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 12, (1, ), dt_int), "day": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 31, (1, ), dt_int), "hour_of_day": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 24, (1, ), dt_int), "minute_of_hour": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 60, (1, ), dt_int), "day_of_week": (np.zeros(1, dtype=dt_int), np.zeros(1, dtype=dt_int) + 7, (1, ), dt_int), "gen_p": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float) - tol_redisp - extra_for_losses, ob_sp.gen_pmax + tol_redisp + extra_for_losses, (ob_sp.n_gen, ), dt_float), "gen_q": (np.full(shape=(ob_sp.n_gen, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_gen, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_gen, ), dt_float), "gen_v": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_gen, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_gen, ), dt_float), "load_p": (np.full(shape=(ob_sp.n_load, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_load, ), fill_value=+np.inf, dtype=dt_float), (ob_sp.n_load, ), dt_float), "load_q": (np.full(shape=(ob_sp.n_load, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_load, ), fill_value=+np.inf, dtype=dt_float), (ob_sp.n_load, ), dt_float), "load_v": (np.full(shape=(ob_sp.n_load, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_load, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_load, ), dt_float), "p_or": (np.full(shape=(ob_sp.n_line, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "q_or": (np.full(shape=(ob_sp.n_line, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "a_or": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "v_or": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "p_ex": (np.full(shape=(ob_sp.n_line, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "q_ex": (np.full(shape=(ob_sp.n_line, ), fill_value=-np.inf, dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "a_ex": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "v_ex": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "rho": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), "line_status": (np.full(shape=(ob_sp.n_line, ), fill_value=0, dtype=dt_int), np.full(shape=(ob_sp.n_line, ), fill_value=1, dtype=dt_int), (ob_sp.n_line, ), dt_int), "timestep_overflow": (np.full(shape=(ob_sp.n_line, ), fill_value=np.iinfo(dt_int).min, dtype=dt_int), np.full(shape=(ob_sp.n_line, ), fill_value=np.iinfo(dt_int).max, dtype=dt_int), (ob_sp.n_line, ), dt_int), "topo_vect": (np.full(shape=(ob_sp.dim_topo, ), fill_value=-1, dtype=dt_int), np.full(shape=(ob_sp.dim_topo, ), fill_value=2, dtype=dt_int), (ob_sp.dim_topo, ), dt_int), "time_before_cooldown_line": (np.full(shape=(ob_sp.n_line, ), fill_value=0, dtype=dt_int), np.full(shape=(ob_sp.n_line, ), fill_value=np.iinfo(dt_int).max, dtype=dt_int), (ob_sp.n_line, ), dt_int), "time_before_cooldown_sub": (np.full(shape=(ob_sp.n_sub, ), fill_value=0, dtype=dt_int), np.full(shape=(ob_sp.n_sub, ), fill_value=np.iinfo(dt_int).max, dtype=dt_int), (ob_sp.n_sub, ), dt_int), "time_next_maintenance": (np.full(shape=(ob_sp.n_line, ), fill_value=-1, dtype=dt_int), np.full(shape=(ob_sp.n_line, ), fill_value=np.iinfo(dt_int).max, dtype=dt_int), (ob_sp.n_line, ), dt_int), "duration_next_maintenance": (np.full(shape=(ob_sp.n_line, ), fill_value=0, dtype=dt_int), np.full(shape=(ob_sp.n_line, ), fill_value=np.iinfo(dt_int).max, dtype=dt_int), (ob_sp.n_line, ), dt_int), "target_dispatch": (np.minimum(ob_sp.gen_pmin, -ob_sp.gen_pmax), np.maximum(-ob_sp.gen_pmin, +ob_sp.gen_pmax), (ob_sp.n_gen, ), dt_float), "actual_dispatch": (np.minimum(ob_sp.gen_pmin, -ob_sp.gen_pmax), np.maximum(-ob_sp.gen_pmin, +ob_sp.gen_pmax), (ob_sp.n_gen, ), dt_float), "storage_charge": (np.full(shape=(ob_sp.n_storage, ), fill_value=0, dtype=dt_float), 1.0 * ob_sp.storage_Emax, (ob_sp.n_storage, ), dt_float), "storage_power_target": (-1.0 * ob_sp.storage_max_p_prod, 1.0 * ob_sp.storage_max_p_absorb, (ob_sp.n_storage, ), dt_float), "storage_power": (-1.0 * ob_sp.storage_max_p_prod, 1.0 * ob_sp.storage_max_p_absorb, (ob_sp.n_storage, ), dt_float), "curtailment": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_gen, ), fill_value=1.0, dtype=dt_float), (ob_sp.n_gen, ), dt_float), "curtailment_limit": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_gen, ), fill_value=1.0, dtype=dt_float), (ob_sp.n_gen, ), dt_float), "curtailment_mw": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float), 1.0 * ob_sp.gen_pmax, (ob_sp.n_gen, ), dt_float), "curtailment_limit_mw": (np.full(shape=(ob_sp.n_gen, ), fill_value=0., dtype=dt_float), 1.0 * ob_sp.gen_pmax, (ob_sp.n_gen, ), dt_float), "thermal_limit": (np.full(shape=(ob_sp.n_line, ), fill_value=0., dtype=dt_float), np.full(shape=(ob_sp.n_line, ), fill_value=np.inf, dtype=dt_float), (ob_sp.n_line, ), dt_float), } self.dict_properties["prod_p"] = self.dict_properties["gen_p"] self.dict_properties["prod_q"] = self.dict_properties["gen_q"] self.dict_properties["prod_v"] = self.dict_properties["gen_v"] self.dict_properties["gen_p_before_curtail"] = self.dict_properties[ "gen_p"] if functs is None: functs = {} for key in functs.keys(): if key not in self._attr_to_keep: raise RuntimeError( f"The key {key} is present in the \"functs\" dictionary but not in the " f"\"attr_to_keep\". This is not consistent: either ignore this function, " f"in that case remove \"{key}\" from \"functs\" or you want to add " f"something to your observation, in that case add it to \"attr_to_keep\"" ) if subtract is None: subtract = {} self._subtract = subtract if divide is None: divide = {} self._divide = divide # handle the "functional" part self._template_obs = ob_sp._template_obj.copy() self.__func = {} self._dims = None low, high, shape, dtype = self._get_info(functs) # initialize the base container Box.__init__(self, low=low, high=high, shape=shape, dtype=dtype)
def __init__(self, grid2op_action_space, attr_to_keep=ALL_ATTR, nb_bins=None): check_gym_version() if not isinstance(grid2op_action_space, ActionSpace): raise RuntimeError( f"Impossible to create a BoxGymActSpace without providing a " f"grid2op action_space. You provided {type(grid2op_action_space)}" f"as the \"grid2op_action_space\" attribute.") if nb_bins is None: nb_bins = { "redispatch": 7, "set_storage": 7, "curtail": 7, "curtail_mw": 7 } if attr_to_keep == ALL_ATTR: # by default, i remove all the attributes that are not supported by the action type # i do not do that if the user specified specific attributes to keep. This is his responsibility in # in this case attr_to_keep = { el for el in attr_to_keep if grid2op_action_space.supports_type(el) } for el in attr_to_keep: if el not in ATTR_DISCRETE: warnings.warn( f"The class \"MultiDiscreteActSpace\" should mainly be used to consider only discrete " f"actions (eg. set_line_status, set_bus or change_bus). Though it is possible to use " f"\"{el}\" when building it, be aware that this continuous action will be treated " f"as discrete by splitting it into bins. " f"Consider using the \"BoxGymActSpace\" for these attributes." ) self._attr_to_keep = sorted(attr_to_keep) act_sp = grid2op_action_space self._act_space = copy.deepcopy(grid2op_action_space) low_gen = -1.0 * act_sp.gen_max_ramp_down high_gen = 1.0 * act_sp.gen_max_ramp_up low_gen[~act_sp.gen_redispatchable] = 0. high_gen[~act_sp.gen_redispatchable] = 0. # nb, dim, [] self.dict_properties = { "set_line_status": ([3 for _ in range(act_sp.n_line)], act_sp.n_line, self.ATTR_SET), "change_line_status": ([2 for _ in range(act_sp.n_line)], act_sp.n_line, self.ATTR_CHANGE), "set_bus": ([4 for _ in range(act_sp.dim_topo)], act_sp.dim_topo, self.ATTR_SET), "change_bus": ([2 for _ in range(act_sp.dim_topo)], act_sp.dim_topo, self.ATTR_CHANGE), "sub_set_bus": (None, act_sp.n_sub, self.ATTR_NEEDBUILD ), # dimension will be computed on the fly, if the stuff is used "sub_change_bus": (None, act_sp.n_sub, self.ATTR_NEEDBUILD ), # dimension will be computed on the fly, if the stuff is used "one_sub_set": (None, 1, self.ATTR_NEEDBUILD ), # dimension will be computed on the fly, if the stuff is used "one_sub_change": (None, 1, self.ATTR_NEEDBUILD ), # dimension will be computed on the fly, if the stuff is used } self._nb_bins = nb_bins for el in ["redispatch", "set_storage", "curtail", "curtail_mw"]: if el in attr_to_keep: if el not in nb_bins: raise RuntimeError( f"The attribute you want to keep \"{el}\" is not present in the " f"\"nb_bins\". This attribute is continuous, you have to specify in how " f"how to convert it to a discrete space. See the documentation " f"for more information.") if el == "redispatch": self.dict_properties[el] = ([ nb_bins[el] if redisp else 1 for redisp in act_sp.gen_redispatchable ], act_sp.n_gen, self.ATTR_NEEDBINARIZED) elif el == "curtail" or el == "curtail_mw": self.dict_properties[el] = ([ nb_bins[el] if renew else 1 for renew in act_sp.gen_renewable ], act_sp.n_gen, self.ATTR_NEEDBINARIZED) elif el == "set_storage": self.dict_properties[el] = ([ nb_bins[el] for _ in range(act_sp.n_storage) ], act_sp.n_gen, self.ATTR_NEEDBINARIZED) else: raise RuntimeError(f"Unknown attribute \"{el}\"") self._dims = None self._functs = None # final functions that is applied to the gym action to map it to a grid2Op action self._binarizers = None # contains all the stuff to binarize the data self._types = None nvec = self._get_info() # initialize the base container MultiDiscrete.__init__(self, nvec=nvec)
def __init__(self, grid2op_action_space, attr_to_keep=ALL_ATTR, add=None, multiply=None, functs=None): if not isinstance(grid2op_action_space, ActionSpace): raise RuntimeError( f"Impossible to create a BoxGymActSpace without providing a " f"grid2op action_space. You provided {type(grid2op_action_space)}" f"as the \"grid2op_action_space\" attribute.") check_gym_version() if attr_to_keep == ALL_ATTR: # by default, i remove all the attributes that are not supported by the action type # i do not do that if the user specified specific attributes to keep. This is his responsibility in # in this case attr_to_keep = { el for el in attr_to_keep if grid2op_action_space.supports_type(el) } for el in ATTR_DISCRETE: if el in attr_to_keep: warnings.warn( f"The class \"BoxGymActSpace\" should mainly be used to consider only continuous " f"actions (eg. redispatch, set_storage or curtail). Though it is possible to use " f"\"{el}\" when building it, be aware that this discrete action will be treated " f"as continuous. Consider using the \"MultiDiscreteActSpace\" for these attributes." ) self._attr_to_keep = sorted(attr_to_keep) act_sp = grid2op_action_space self._act_space = copy.deepcopy(grid2op_action_space) low_gen = -1.0 * act_sp.gen_max_ramp_down high_gen = 1.0 * act_sp.gen_max_ramp_up low_gen[~act_sp.gen_redispatchable] = 0. high_gen[~act_sp.gen_redispatchable] = 0. curtail = np.full(shape=(act_sp.n_gen, ), fill_value=0., dtype=dt_float) curtail[~act_sp.gen_renewable] = 1.0 curtail_mw = np.full(shape=(act_sp.n_gen, ), fill_value=0., dtype=dt_float) curtail_mw[~act_sp.gen_renewable] = act_sp.gen_pmax[~act_sp. gen_renewable] self.dict_properties = { "set_line_status": (np.full(shape=(act_sp.n_line, ), fill_value=-1, dtype=dt_int), np.full(shape=(act_sp.n_line, ), fill_value=1, dtype=dt_int), (act_sp.n_line, ), dt_int), "change_line_status": (np.full(shape=(act_sp.n_line, ), fill_value=0, dtype=dt_int), np.full(shape=(act_sp.n_line, ), fill_value=1, dtype=dt_int), (act_sp.n_line, ), dt_int), "set_bus": (np.full(shape=(act_sp.dim_topo, ), fill_value=-1, dtype=dt_int), np.full(shape=(act_sp.dim_topo, ), fill_value=1, dtype=dt_int), (act_sp.dim_topo, ), dt_int), "change_bus": (np.full(shape=(act_sp.dim_topo, ), fill_value=0, dtype=dt_int), np.full(shape=(act_sp.dim_topo, ), fill_value=1, dtype=dt_int), (act_sp.dim_topo, ), dt_int), "redispatch": (low_gen, high_gen, (act_sp.n_gen, ), dt_float), "set_storage": (-1.0 * act_sp.storage_max_p_prod, 1.0 * act_sp.storage_max_p_absorb, (act_sp.n_storage, ), dt_float), "curtail": (curtail, np.full(shape=(act_sp.n_gen, ), fill_value=1., dtype=dt_float), (act_sp.n_gen, ), dt_float), "curtail_mw": (curtail_mw, 1.0 * act_sp.gen_pmax, (act_sp.n_gen, ), dt_float), } self._key_dict_to_proptype = { "set_line_status": dt_int, "change_line_status": dt_bool, "set_bus": dt_int, "change_bus": dt_bool, "redispatch": dt_float, "set_storage": dt_float, "curtail": dt_float, "curtail_mw": dt_float } if add is not None: self._add = add else: self._add = {} if multiply is not None: self._multiply = multiply else: self._multiply = {} # handle the "functional" part self.__func = {} self._dims = None self._dtypes = None if functs is None: functs = {} low, high, shape, dtype = self._get_info(functs) # initialize the base container Box.__init__(self, low=low, high=high, shape=shape, dtype=dtype)