Skip to content

Commit 2209a30

Browse files
author
yassine abdou
committed
feat : use default and no protection in baseEnv, use protection in place of next_grid function from backend
1 parent 8934ddd commit 2209a30

File tree

5 files changed

+91
-73
lines changed

5 files changed

+91
-73
lines changed

grid2op/Backend/protectionScheme.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ def __init__(
3232
self.thermal_limits = thermal_limits
3333

3434
self._thermal_limit_a = self.thermal_limits.limits if self.thermal_limits else None
35-
35+
self.backend.thermal_limit_a = self._thermal_limit_a
36+
3637
self._hard_overflow_threshold = self._get_value_from_parameters("HARD_OVERFLOW_THRESHOLD")
3738
self._soft_overflow_threshold = self._get_value_from_parameters("SOFT_OVERFLOW_THRESHOLD")
3839
self._nb_timestep_overflow_allowed = self._get_value_from_parameters("NB_TIMESTEP_OVERFLOW_ALLOWED")
39-
self._no_overflow_disconnection = self._get_value_from_parameters("NO_OVERFLOW_DISCONNECTION")
4040

4141
self.disconnected_during_cf = np.full(self.thermal_limits.n_line, fill_value=-1, dtype=dt_int)
4242
self._timestep_overflow = np.zeros(self.thermal_limits.n_line, dtype=dt_int)
@@ -81,9 +81,6 @@ def _disconnect_lines(self, lines_to_disconnect: np.ndarray, timestep: int) -> N
8181

8282
def next_grid_state(self) -> Tuple[np.ndarray, List[Any], Union[None, Exception]]:
8383
try:
84-
if self._no_overflow_disconnection: # détaché cela d'ici et si on simule pas
85-
return self._handle_no_protection()
86-
8784
timestep = 0
8885
while True:
8986
power_flow_result = self._run_power_flow()
@@ -105,24 +102,30 @@ def next_grid_state(self) -> Tuple[np.ndarray, List[Any], Union[None, Exception]
105102
logger.exception("Erreur inattendue dans le calcul de l'état du réseau.")
106103
return self.disconnected_during_cf, self.infos, e
107104

108-
def _handle_no_protection(self) -> Tuple[np.ndarray, List[Any], None]:
109-
no_protection = NoProtection(self.thermal_limits)
110-
return no_protection.handle_no_protection()
111-
112105
class NoProtection:
113106
"""
114107
Classe qui gère le cas où les protections de débordement sont désactivées.
115108
"""
116109
def __init__(
117110
self,
111+
backend: Backend,
118112
thermal_limits: ThermalLimits
119113
):
114+
self.backend = backend
115+
self._validate_input(self.backend)
120116

121117
self.thermal_limits = thermal_limits
118+
119+
self._thermal_limit_a = self.thermal_limits.limits if self.thermal_limits else None
120+
self.backend.thermal_limit_a = self._thermal_limit_a
121+
122122
self.disconnected_during_cf = np.full(self.thermal_limits.n_line, fill_value=-1, dtype=dt_int)
123123
self.infos = []
124124

125-
def handle_no_protection(self) -> Tuple[np.ndarray, List[Any], None]:
125+
def _validate_input(self, backend: Backend) -> None:
126+
if not isinstance(backend, Backend):
127+
raise Grid2OpException(f"Argument 'backend' doit être de type 'Backend', reçu : {type(backend)}")
128+
def next_grid_state(self) -> Tuple[np.ndarray, List[Any], None]:
126129
"""
127130
Retourne l'état du réseau sans effectuer de déconnexions dues aux débordements.
128131
"""

grid2op/Environment/baseEnv.py

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ def __init__(
571571

572572
# Thermal limit and protection
573573
self._init_thermal_limit()
574-
self.protection : protectionScheme.DefaultProtection = None
574+
self.protection : protectionScheme = None
575575

576576
# to change the parameters
577577
self.__new_param = None
@@ -681,12 +681,21 @@ def _init_thermal_limit(self):
681681

682682
def _init_protection(self):
683683
# Initialize the protection system with the specified parameters
684-
self.protection = protectionScheme.DefaultProtection(
685-
backend=self.backend,
686-
parameters=self.parameters,
687-
thermal_limits=self.ts_manager,
688-
is_dc=self._env_dc
689-
)
684+
self._no_overflow_disconnection: bool = (
685+
self._parameters.NO_OVERFLOW_DISCONNECTION
686+
)
687+
if self._no_overflow_disconnection:
688+
self.protection = protectionScheme.NoProtection(
689+
backend=self.backend,
690+
thermal_limits=self.ts_manager,
691+
)
692+
else:
693+
self.protection = protectionScheme.DefaultProtection(
694+
backend=self.backend,
695+
parameters=self.parameters,
696+
thermal_limits=self.ts_manager,
697+
is_dc=self._env_dc
698+
)
690699

691700
@property
692701
def highres_sim_counter(self):
@@ -1869,51 +1878,52 @@ def _init_backend(
18691878
"""
18701879
pass
18711880

1872-
# def set_thermal_limit(self, thermal_limit):
1873-
# """
1874-
# Set the thermal limit effectively.
1881+
def set_thermal_limit(self, thermal_limit):
1882+
"""
1883+
Set the thermal limit effectively.
18751884
1876-
# Parameters
1877-
# ----------
1878-
# thermal_limit: ``numpy.ndarray``
1879-
# The new thermal limit. It must be a numpy ndarray vector (or convertible to it). For each powerline it
1880-
# gives the new thermal limit.
1885+
Parameters
1886+
----------
1887+
thermal_limit: ``numpy.ndarray``
1888+
The new thermal limit. It must be a numpy ndarray vector (or convertible to it). For each powerline it
1889+
gives the new thermal limit.
18811890
1882-
# Alternatively, this can be a dictionary mapping the line names (keys) to its thermal limits (values). In
1883-
# that case, all thermal limits for all powerlines should be specified (this is a safety measure
1884-
# to reduce the odds of misuse).
1891+
Alternatively, this can be a dictionary mapping the line names (keys) to its thermal limits (values). In
1892+
that case, all thermal limits for all powerlines should be specified (this is a safety measure
1893+
to reduce the odds of misuse).
18851894
1886-
# Examples
1887-
# ---------
1895+
Examples
1896+
---------
18881897
1889-
# This function can be used like this:
1898+
This function can be used like this:
18901899
1891-
# .. code-block:: python
1900+
.. code-block:: python
18921901
1893-
# import grid2op
1902+
import grid2op
18941903
1895-
# # I create an environment
1896-
# env = grid2op.make(""l2rpn_case14_sandbox"", test=True)
1904+
# I create an environment
1905+
env = grid2op.make(""l2rpn_case14_sandbox"", test=True)
18971906
1898-
# # i set the thermal limit of each powerline to 20000 amps
1899-
# env.set_thermal_limit([20000 for _ in range(env.n_line)])
1907+
# i set the thermal limit of each powerline to 20000 amps
1908+
env.set_thermal_limit([20000 for _ in range(env.n_line)])
19001909
1901-
# Notes
1902-
# -----
1903-
# As of grid2op > 1.5.0, it is possible to set the thermal limit by using a dictionary with the keys being
1904-
# the name of the powerline and the values the thermal limits.
1910+
Notes
1911+
-----
1912+
As of grid2op > 1.5.0, it is possible to set the thermal limit by using a dictionary with the keys being
1913+
the name of the powerline and the values the thermal limits.
19051914
1906-
# """
1907-
# if self.__closed:
1908-
# raise EnvError("This environment is closed, you cannot use it.")
1909-
# if not self.__is_init:
1910-
# raise Grid2OpException(
1911-
# "Impossible to set the thermal limit to a non initialized Environment. "
1912-
# "Have you called `env.reset()` after last game over ?"
1913-
# )
1914-
# # update n_line and name_line of ts_manager (old : self.ts_manager.n_line = -1 and self.ts_manager.name_line = None)
1915-
# self.ts_manager.env_limits(thermal_limit=thermal_limit)
1916-
# self.observation_space.set_thermal_limit(thermal_limit=thermal_limit)
1915+
"""
1916+
if self.__closed:
1917+
raise EnvError("This environment is closed, you cannot use it.")
1918+
if not self.__is_init:
1919+
raise Grid2OpException(
1920+
"Impossible to set the thermal limit to a non initialized Environment. "
1921+
"Have you called `env.reset()` after last game over ?"
1922+
)
1923+
# update n_line and name_line of ts_manager (old : self.ts_manager.n_line = -1 and self.ts_manager.name_line = None)
1924+
self.ts_manager.env_limits(thermal_limit=thermal_limit)
1925+
self.backend.thermal_limit_a = self.ts_manager.limits
1926+
self.observation_space.set_thermal_limit(self.ts_manager.limits)
19171927

19181928
def _reset_redispatching(self):
19191929
# redispatching

grid2op/MakeEnv/MakeFromPath.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,8 +1069,7 @@ def make_from_dataset_path(
10691069
env._do_not_erase_local_dir_cls = do_not_erase_cls
10701070
# Update the thermal limit if any
10711071
if thermal_limits is not None:
1072-
env.ts_manager.env_limits(thermal_limits)
1073-
env.observation_space.ts_manager.env_limits(env.ts_manager.limits)
1072+
env.set_thermal_limit(thermal_limits)
10741073

10751074
# Set graph layout if not None and not an empty dict
10761075
if graph_layout is not None and graph_layout:

grid2op/Observation/observationSpace.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,11 @@ def change_reward(self, reward_func):
399399
"function when you cannot simulate (because the "
400400
"backend could not be copied)")
401401

402-
# def set_thermal_limit(self, thermal_limit_a):
403-
# if self.obs_env is not None:
404-
# self.obs_env.set_thermal_limit(thermal_limit_a)
405-
# if self._backend_obs is not None:
406-
# self.obs_env.ts_manager.limits = thermal_limit_a
402+
def set_thermal_limit(self, thermal_limit_a):
403+
if self.obs_env is not None:
404+
self.obs_env.ts_manager.env_limits(thermal_limit_a)
405+
if self._backend_obs is not None:
406+
self._backend_obs.thermal_limit_a = thermal_limit_a
407407

408408
def reset_space(self):
409409
if self.with_forecast:

grid2op/tests/BaseBackendTest.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ def next_grid_state_no_overflow(self):
16371637

16381638
)
16391639

1640-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1640+
disco, infos, conv_ = env.protection.next_grid_state()
16411641
assert conv_ is None
16421642
assert not infos
16431643

@@ -1667,9 +1667,10 @@ def test_next_grid_state_1overflow(self):
16671667
thermal_limit[self.id_first_line_disco] = (
16681668
self.lines_flows_init[self.id_first_line_disco] / 2
16691669
)
1670-
self.backend.set_thermal_limit(thermal_limit)
1671-
1672-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1670+
env.ts_manager.limits = thermal_limit
1671+
env._init_protection()
1672+
1673+
disco, infos, conv_ = env.protection.next_grid_state()
16731674
assert conv_ is None
16741675
assert len(infos) == 1 # check that i have only one overflow
16751676
assert np.sum(disco >= 0) == 1
@@ -1704,9 +1705,10 @@ def test_next_grid_state_1overflow_envNoCF(self):
17041705
thermal_limit[self.id_first_line_disco] = (
17051706
lines_flows_init[self.id_first_line_disco] / 2
17061707
)
1707-
self.backend.set_thermal_limit(thermal_limit)
1708+
env.ts_manager.limits = thermal_limit
1709+
env._init_protection()
17081710

1709-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1711+
disco, infos, conv_ = env.protection.next_grid_state()
17101712
assert conv_ is None
17111713
assert not infos # check that don't simulate a cascading failure
17121714
assert np.sum(disco >= 0) == 0
@@ -1750,9 +1752,10 @@ def test_nb_timestep_overflow_disc0(self):
17501752
lines_flows_init[self.id_first_line_disco] / 2
17511753
)
17521754
thermal_limit[self.id_2nd_line_disco] = 400
1753-
self.backend.set_thermal_limit(thermal_limit)
1755+
env.ts_manager.limits = thermal_limit
1756+
env._init_protection()
17541757

1755-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1758+
disco, infos, conv_ = env.protection.next_grid_state()
17561759
assert conv_ is None
17571760
assert len(infos) == 2 # check that there is a cascading failure of length 2
17581761
assert disco[self.id_first_line_disco] >= 0
@@ -1793,9 +1796,10 @@ def test_nb_timestep_overflow_nodisc(self):
17931796
self.lines_flows_init[self.id_first_line_disco] / 2
17941797
)
17951798
thermal_limit[self.id_2nd_line_disco] = 400
1796-
self.backend.set_thermal_limit(thermal_limit)
1799+
env.ts_manager.limits = thermal_limit
1800+
env._init_protection()
17971801

1798-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1802+
disco, infos, conv_ = env.protection.next_grid_state()
17991803
assert conv_ is None
18001804
assert len(infos) == 1 # check that don't simulate a cascading failure
18011805
assert disco[self.id_first_line_disco] >= 0
@@ -1836,9 +1840,10 @@ def test_nb_timestep_overflow_nodisc_2(self):
18361840
self.lines_flows_init[self.id_first_line_disco] / 2
18371841
)
18381842
thermal_limit[self.id_2nd_line_disco] = 400
1839-
self.backend.set_thermal_limit(thermal_limit)
1843+
env.ts_manager.limits = thermal_limit
1844+
env._init_protection()
18401845

1841-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1846+
disco, infos, conv_ = env.protection.next_grid_state()
18421847
assert conv_ is None
18431848
assert len(infos) == 1 # check that don't simulate a cascading failure
18441849
assert disco[self.id_first_line_disco] >= 0
@@ -1879,9 +1884,10 @@ def test_nb_timestep_overflow_disc2(self):
18791884
self.lines_flows_init[self.id_first_line_disco] / 2
18801885
)
18811886
thermal_limit[self.id_2nd_line_disco] = 400
1882-
self.backend.set_thermal_limit(thermal_limit)
1887+
env.ts_manager.limits = thermal_limit
1888+
env._init_protection()
18831889

1884-
disco, infos, conv_ = self.backend.next_grid_state(env, is_dc=False)
1890+
disco, infos, conv_ = env.protection.next_grid_state()
18851891
assert conv_ is None
18861892
assert len(infos) == 2 # check that there is a cascading failure of length 2
18871893
assert disco[self.id_first_line_disco] >= 0

0 commit comments

Comments
 (0)