Skip to content

Commit 4d303cd

Browse files
committed
fixing some issues
Signed-off-by: DONNOT Benjamin <[email protected]>
1 parent ef2b98c commit 4d303cd

File tree

8 files changed

+41
-12
lines changed

8 files changed

+41
-12
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ Native multi agents support:
142142
different than "env.step" (with the same action)
143143
- [FIXED] a powerflow is run when the environment is first created even before the initial "env.step"
144144
function is called. This is to ensure proper behaviour if env is used without being reset.
145+
- [FIXED] no error was catched if the backend could not properly apply the action sent by the environment.
145146
- [ADDED] possibility to set the "thermal limits" when calling `env.reset(..., options={"thermal limit": xxx})`
146147
- [ADDED] possibility to retrieve some structural information about elements with
147148
with `gridobj.get_line_info(...)`, `gridobj.get_load_info(...)`, `gridobj.get_gen_info(...)`

grid2op/Environment/_obsEnv.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ def reset(self):
447447
"environment that cannot be copied.")
448448
super().reset()
449449
self.current_obs = self.current_obs_init
450+
# force the checking of the rules for the action
451+
self._called_from_reset = False
450452

451453
def simulate(self, action : "grid2op.Action.BaseAction") -> Tuple["grid2op.Observation.BaseObservation", float, bool, STEP_INFO_TYPING]:
452454
"""

grid2op/Environment/baseEnv.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
SomeGeneratorAbovePmax,
4545
SomeGeneratorBelowPmin,
4646
SomeGeneratorAboveRampmax,
47-
SomeGeneratorBelowRampmin)
47+
SomeGeneratorBelowRampmin,
48+
BackendError)
4849
from grid2op.Parameters import Parameters
4950
from grid2op.Reward import BaseReward, RewardHelper
5051
from grid2op.Opponent import OpponentSpace, NeverAttackBudget, BaseOpponent
@@ -671,6 +672,9 @@ def __init__(
671672
self._previous_conn_state = None
672673
self._cst_prev_state_at_init = None
673674

675+
# 1.11: do not check rules if first observation
676+
self._called_from_reset = True
677+
674678
@property
675679
def highres_sim_counter(self):
676680
return self._highres_sim_counter
@@ -994,6 +998,9 @@ def _custom_deepcopy_for_copy(self, new_obj, dict_=None):
994998
new_obj._previous_conn_state = copy.deepcopy(self._previous_conn_state)
995999
new_obj._cst_prev_state_at_init = self._cst_prev_state_at_init # no need to deep copy this
9961000

1001+
1002+
new_obj._called_from_reset = self._called_from_reset
1003+
9971004
def get_path_env(self):
9981005
"""
9991006
Get the path that allows to create this environment.
@@ -1550,6 +1557,7 @@ def reset(self,
15501557
f"can be used.")
15511558

15521559
self.__is_init = True
1560+
self._called_from_reset = True
15531561
# current = None is an indicator that this is the first step of the environment
15541562
# so don't change the setting of current_obs = None unless you are willing to change that
15551563
self.current_obs = None
@@ -3550,7 +3558,8 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation,
35503558
# and this regardless of the
35513559
_ = action.get_topological_impact(powerline_status, _store_in_cache=True, _read_from_cache=False)
35523560

3553-
if self._last_obs is not None:
3561+
if not self._called_from_reset:
3562+
# avoid checking this at first environment "step" which is a "reset"
35543563
is_legal, reason = self._game_rules(action=action, env=self)
35553564
else:
35563565
is_legal = True
@@ -3634,6 +3643,10 @@ def step(self, action: BaseAction) -> Tuple[BaseObservation,
36343643
is_done = True
36353644
# TODO in this case: cancel the topological action of the agent
36363645
# and continue instead of "game over"
3646+
except BackendError as exc_:
3647+
has_error = True
3648+
except_.append(exc_)
3649+
is_done = True
36373650
self._time_apply_act += time.perf_counter() - beg_
36383651

36393652
# now it's time to run the powerflow properly

grid2op/Environment/environment.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ def _init_backend(
490490
# thermal limits are set AFTER this initial step
491491
_no_overflow_disconnection = self._no_overflow_disconnection
492492
self._no_overflow_disconnection = True
493+
self._last_obs = None
493494
*_, fail_to_start, info = self.step(do_nothing)
494495
self._no_overflow_disconnection = _no_overflow_disconnection
495496

@@ -1336,6 +1337,7 @@ def reset(self,
13361337
# process the "options" kwargs
13371338
# (if there is an init state then I need to process it to remove the
13381339
# some keys)
1340+
self._called_from_reset = False
13391341
self._max_step = None
13401342
method = "combine"
13411343
init_state = None
@@ -1416,6 +1418,8 @@ def reset(self,
14161418
self._init_obs = None
14171419
if init_dt is not None:
14181420
self.chronics_handler.set_current_datetime(init_dt)
1421+
self._last_obs = None # properly initialize the last observation
1422+
self._called_from_reset = True
14191423
self.step(self.action_space())
14201424
elif skip_ts == 2:
14211425
self.fast_forward_chronics(1, init_dt)
@@ -1436,6 +1440,9 @@ def reset(self,
14361440
# and reset also the "simulated env" in the observation space
14371441
self._observation_space.reset(self)
14381442
self._observation_space.set_real_env_kwargs(self)
1443+
self._called_from_reset = False
1444+
# force the first observation to be generated properly
1445+
self._last_obs = None
14391446
return self.get_obs()
14401447

14411448
def render(self, mode="rgb_array"):

grid2op/Observation/observationSpace.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,8 @@ def _custom_deepcopy_for_copy(self, new_obj, env=None):
495495

496496
# real env kwargs, these is a "pointer" anyway
497497
if env is not None:
498-
from grid2op.Environment import Environment
499-
new_obj._real_env_kwargs = Environment.get_kwargs(env, False, False)
498+
new_obj._real_env_kwargs = {}
499+
new_obj.set_real_env_kwargs(env)
500500
else:
501501
new_obj._real_env_kwargs = self._real_env_kwargs
502502
new_obj._observation_bk_class = self._observation_bk_class

grid2op/tests/test_AlarmFeature.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def test_alarm_obs_whenalarm(self):
217217
obs = self.env.reset()
218218
nb_th = 3
219219
assert abs(self.env._attention_budget._current_budget - nb_th) <= 1e-6
220-
assert abs(obs.attention_budget - nb_th) <= 1e-6
220+
assert abs(obs.attention_budget - nb_th) <= 1e-6, f"{obs.attention_budget} vs {nb_th}"
221221
assert obs.time_since_last_alarm == -1
222222
assert np.all(obs.last_alarm == [-1, -1, -1])
223223

grid2op/tests/test_MaskedEnvironment.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,10 @@ def test_gym_multidiscrete(self):
221221
env_gym_in.reset()
222222
env_gym_out.reset()
223223
act = env_gym_in.action_space.sample()
224-
act[:] = 0
225-
self._aux_run_envs(act, env_gym_in, env_gym_out)
224+
act[:] = 0 # this is not the do nothing action...
225+
with warnings.catch_warnings():
226+
warnings.filterwarnings("ignore")
227+
self._aux_run_envs(act, env_gym_in, env_gym_out)
226228

227229

228230
if __name__ == "__main__":

grid2op/tests/test_basic_env_ls.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ def setUp(self) -> None:
4747
self.env = grid2op.make("l2rpn_case14_sandbox",
4848
test=True,
4949
_add_to_name=type(self).__name__,
50-
backend=LightSimBackend())
50+
backend=LightSimBackend(),
51+
allow_detachment=False)
5152
self.line_id = 3
5253
th_lim = self.env.get_thermal_limit() * 2. # avoid all problem in general
5354
th_lim[self.line_id] /= 10. # make sure to get trouble in line 3
@@ -169,6 +170,9 @@ def test_backward_compatibility(self):
169170
"1.9.8",
170171
"1.10.0",
171172
"1.10.1",
173+
"1.10.2",
174+
"1.10.3",
175+
"1.10.4",
172176
]
173177
# first check a normal run
174178
curr_version = "test_version"
@@ -275,12 +279,12 @@ def _aux_backward(self, base_path, g2op_version_txt, g2op_version):
275279
if g2op_ver <= version.parse("1.4.0"):
276280
assert (
277281
EpisodeData.get_grid2op_version(full_episode_path) == "<=1.4.0"
278-
), "wrong grid2op version stored (grid2op version <= 1.4.0)"
282+
), f"wrong grid2op version stored (grid2op version <= 1.4.0) stored {EpisodeData.get_grid2op_version(full_episode_path)} vs '<=1.4.0'"
279283
elif g2op_version == "test_version":
280284
assert (
281285
EpisodeData.get_grid2op_version(full_episode_path)
282286
== grid2op.__version__
283-
), "wrong grid2op version stored (test_version)"
287+
), f"wrong grid2op version stored (test_version) : {EpisodeData.get_grid2op_version(full_episode_path)} vs {grid2op.__version__}"
284288
else:
285289
assert (
286290
EpisodeData.get_grid2op_version(full_episode_path) == g2op_version
@@ -342,10 +346,10 @@ def test_gym_multidiscrete(self):
342346
env_gym = GymEnv(self.env)
343347
with warnings.catch_warnings():
344348
warnings.filterwarnings("ignore")
345-
env_gym.action_space = MultiDiscreteActSpace(self.env.action_space)
349+
env_gym.action_space = MultiDiscreteActSpace(self.env.action_space, attr_to_keep=["set_line_status"])
346350
env_gym.reset()
347351
act = env_gym.action_space.sample()
348-
act[:] = 0
352+
act[:] = 1 # apparently this is "do nothing"
349353
self._aux_run_envs(act, env_gym)
350354

351355

0 commit comments

Comments
 (0)