예제 #1
0
    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)
예제 #2
0
    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)