Skip to content

Commit

Permalink
Merge pull request #454 from BDonnot/TimeOutEnv
Browse files Browse the repository at this point in the history
Adding support for TimeOutEnv
  • Loading branch information
BDonnot committed May 23, 2023
2 parents 8f19d96 + 0a34f7b commit 91ae444
Show file tree
Hide file tree
Showing 19 changed files with 740 additions and 38 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ requirements_issue_389.txt
test_multi_step_for.py
test_vecenv.7z
test_vecenv.py
test_timeout_env.py
test_pp_networks.py
test_timeout_env.py
test_timeout_env.py
test_pp_networks.py
test_timeout_env.py
test_pp_dc.py
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Change Log
directly from the grid2op action, see `obs.change_forecast_parameters()`
- [ADDED] possibility to retrieve a "forecast environment" with custom forecasts, see
`obs.get_env_from_external_forecasts(...)`
- [ADDED] adding the `TimedOutEnvironment` that takes "do nothing" actions when the agent
takes too much time to compute. This involves quite some changes in the runner too.
- [IMPROVED] possibility to "chain" the call to simulate when multiple forecast
horizon are available.
- [IMPROVED] the `GridStateFromFileWithForecasts` is now able to read forecast from multiple steps
Expand Down
10 changes: 6 additions & 4 deletions grid2op/Chronics/gridValue.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@ class GridValue(RandomObject, ABC):
given in :func:`GridValue.get_hazard_duration_1d`.
"""

NAN_BUT_IN_INT = -9999999

def __init__(
self,
time_interval=timedelta(minutes=5),
Expand Down Expand Up @@ -280,7 +283,7 @@ def get_maintenance_time_1d(maintenance):
"""

res = np.full(maintenance.shape, fill_value=np.NaN, dtype=dt_int)
res = np.full(maintenance.shape, fill_value=GridValue.NAN_BUT_IN_INT, dtype=dt_int)
maintenance = np.concatenate((maintenance, (0, 0)))
a = np.diff(maintenance)
# +1 is because numpy does the diff `t+1` - `t` so to get index of the initial array
Expand Down Expand Up @@ -354,8 +357,7 @@ def get_maintenance_duration_1d(maintenance):
assert np.all(maintenance_duration == np.array([3,3,3,3,3,3,2,1,2,2,2,2,2,1,0,0,0]))
"""

res = np.full(maintenance.shape, fill_value=np.NaN, dtype=dt_int)
res = np.full(maintenance.shape, fill_value=GridValue.NAN_BUT_IN_INT, dtype=dt_int)
maintenance = np.concatenate((maintenance, (0, 0)))
a = np.diff(maintenance)
# +1 is because numpy does the diff `t+1` - `t` so to get index of the initial array
Expand Down Expand Up @@ -433,7 +435,7 @@ def get_hazard_duration_1d(hazard):
"""

res = np.full(hazard.shape, fill_value=np.NaN, dtype=dt_int)
res = np.full(hazard.shape, fill_value=GridValue.NAN_BUT_IN_INT, dtype=dt_int)
hazard = np.concatenate((hazard, (0, 0)))
a = np.diff(hazard)
# +1 is because numpy does the diff `t+1` - `t` so to get index of the initial array
Expand Down
4 changes: 2 additions & 2 deletions grid2op/Converter/IdToAct.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from grid2op.Action import BaseAction
from grid2op.Converter.Converters import Converter
from grid2op.Exceptions.Grid2OpException import Grid2OpException
from grid2op.dtypes import dt_float, dt_int
from grid2op.dtypes import dt_float, dt_int, int_types


class IdToAct(Converter):
Expand Down Expand Up @@ -453,7 +453,7 @@ def convert_action_from_gym(self, gymlike_action):
"""
res = gymlike_action["action"]
if not isinstance(res, (int, dt_int, np.int, np.int64)):
if not isinstance(res, int_types):
raise RuntimeError("TODO")
return int(res)

Expand Down
1 change: 1 addition & 0 deletions grid2op/Environment/BaseEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class BaseEnv(GridObjects, RandomObject, ABC):
"""

ALARM_FILE_NAME = "alerts_info.json"
CAN_SKIP_TS = False # each step is exactly one time step

def __init__(
self,
Expand Down
69 changes: 69 additions & 0 deletions grid2op/Environment/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,75 @@ def get_params_for_runner(self):
res["_is_test"] = self._is_test # TODO not implemented !!
return res

@classmethod
def init_obj_from_kwargs(cls,
other_env_kwargs,
init_env_path,
init_grid_path,
chronics_handler,
backend,
parameters,
name,
names_chronics_to_backend,
actionClass,
observationClass,
rewardClass,
legalActClass,
voltagecontrolerClass,
other_rewards,
opponent_space_type,
opponent_action_class,
opponent_class,
opponent_init_budget,
opponent_budget_per_ts,
opponent_budget_class,
opponent_attack_duration,
opponent_attack_cooldown,
kwargs_opponent,
with_forecast,
attention_budget_cls,
kwargs_attention_budget,
has_attention_budget,
logger,
kwargs_observation,
observation_bk_class,
observation_bk_kwargs,
_raw_backend_class,
_read_from_local_dir):
res = Environment(init_env_path=init_env_path,
init_grid_path=init_grid_path,
chronics_handler=chronics_handler,
backend=backend,
parameters=parameters,
name=name,
names_chronics_to_backend=names_chronics_to_backend,
actionClass=actionClass,
observationClass=observationClass,
rewardClass=rewardClass,
legalActClass=legalActClass,
voltagecontrolerClass=voltagecontrolerClass,
other_rewards=other_rewards,
opponent_space_type=opponent_space_type,
opponent_action_class=opponent_action_class,
opponent_class=opponent_class,
opponent_init_budget=opponent_init_budget,
opponent_budget_per_ts=opponent_budget_per_ts,
opponent_budget_class=opponent_budget_class,
opponent_attack_duration=opponent_attack_duration,
opponent_attack_cooldown=opponent_attack_cooldown,
kwargs_opponent=kwargs_opponent,
with_forecast=with_forecast,
attention_budget_cls=attention_budget_cls,
kwargs_attention_budget=kwargs_attention_budget,
has_attention_budget=has_attention_budget,
logger=logger,
kwargs_observation=kwargs_observation,
observation_bk_class=observation_bk_class,
observation_bk_kwargs=observation_bk_kwargs,
_raw_backend_class=_raw_backend_class,
_read_from_local_dir=_read_from_local_dir)
return res

def generate_data(self, nb_year=1, nb_core=1, seed=None, **kwargs):
"""This function uses the chronix2grid package to generate more data that will then
be available locally. You need to install it independently (see https://github.com/BDonnot/ChroniX2Grid#installation
Expand Down
2 changes: 2 additions & 0 deletions grid2op/Environment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"SingleEnvMultiProcess",
"MultiEnvMultiProcess",
"MultiMixEnvironment",
"TimedOutEnvironment"
]

from grid2op.Environment.BaseEnv import BaseEnv
Expand All @@ -13,3 +14,4 @@
from grid2op.Environment.SingleEnvMultiProcess import SingleEnvMultiProcess
from grid2op.Environment.MultiEnvMultiProcess import MultiEnvMultiProcess
from grid2op.Environment.MultiMixEnv import MultiMixEnvironment
from grid2op.Environment.timedOutEnv import TimedOutEnvironment

0 comments on commit 91ae444

Please sign in to comment.