Skip to content

Commit 26832ff

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 74bd94b commit 26832ff

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
@@ -551,7 +551,7 @@ def __init__(
551551

552552
# Thermal limit and protection
553553
self._init_thermal_limit()
554-
self.protection : protectionScheme.DefaultProtection = None
554+
self.protection : protectionScheme = None
555555

556556
# to change the parameters
557557
self.__new_param = None
@@ -645,12 +645,21 @@ def _init_thermal_limit(self):
645645

646646
def _init_protection(self):
647647
# Initialize the protection system with the specified parameters
648-
self.protection = protectionScheme.DefaultProtection(
649-
backend=self.backend,
650-
parameters=self.parameters,
651-
thermal_limits=self.ts_manager,
652-
is_dc=self._env_dc
653-
)
648+
self._no_overflow_disconnection: bool = (
649+
self._parameters.NO_OVERFLOW_DISCONNECTION
650+
)
651+
if self._no_overflow_disconnection:
652+
self.protection = protectionScheme.NoProtection(
653+
backend=self.backend,
654+
thermal_limits=self.ts_manager,
655+
)
656+
else:
657+
self.protection = protectionScheme.DefaultProtection(
658+
backend=self.backend,
659+
parameters=self.parameters,
660+
thermal_limits=self.ts_manager,
661+
is_dc=self._env_dc
662+
)
654663

655664
@property
656665
def highres_sim_counter(self):
@@ -1783,51 +1792,52 @@ def _init_backend(
17831792
"""
17841793
pass
17851794

1786-
# def set_thermal_limit(self, thermal_limit):
1787-
# """
1788-
# Set the thermal limit effectively.
1795+
def set_thermal_limit(self, thermal_limit):
1796+
"""
1797+
Set the thermal limit effectively.
17891798
1790-
# Parameters
1791-
# ----------
1792-
# thermal_limit: ``numpy.ndarray``
1793-
# The new thermal limit. It must be a numpy ndarray vector (or convertible to it). For each powerline it
1794-
# gives the new thermal limit.
1799+
Parameters
1800+
----------
1801+
thermal_limit: ``numpy.ndarray``
1802+
The new thermal limit. It must be a numpy ndarray vector (or convertible to it). For each powerline it
1803+
gives the new thermal limit.
17951804
1796-
# Alternatively, this can be a dictionary mapping the line names (keys) to its thermal limits (values). In
1797-
# that case, all thermal limits for all powerlines should be specified (this is a safety measure
1798-
# to reduce the odds of misuse).
1805+
Alternatively, this can be a dictionary mapping the line names (keys) to its thermal limits (values). In
1806+
that case, all thermal limits for all powerlines should be specified (this is a safety measure
1807+
to reduce the odds of misuse).
17991808
1800-
# Examples
1801-
# ---------
1809+
Examples
1810+
---------
18021811
1803-
# This function can be used like this:
1812+
This function can be used like this:
18041813
1805-
# .. code-block:: python
1814+
.. code-block:: python
18061815
1807-
# import grid2op
1816+
import grid2op
18081817
1809-
# # I create an environment
1810-
# env = grid2op.make(""l2rpn_case14_sandbox"", test=True)
1818+
# I create an environment
1819+
env = grid2op.make(""l2rpn_case14_sandbox"", test=True)
18111820
1812-
# # i set the thermal limit of each powerline to 20000 amps
1813-
# env.set_thermal_limit([20000 for _ in range(env.n_line)])
1821+
# i set the thermal limit of each powerline to 20000 amps
1822+
env.set_thermal_limit([20000 for _ in range(env.n_line)])
18141823
1815-
# Notes
1816-
# -----
1817-
# As of grid2op > 1.5.0, it is possible to set the thermal limit by using a dictionary with the keys being
1818-
# the name of the powerline and the values the thermal limits.
1824+
Notes
1825+
-----
1826+
As of grid2op > 1.5.0, it is possible to set the thermal limit by using a dictionary with the keys being
1827+
the name of the powerline and the values the thermal limits.
18191828
1820-
# """
1821-
# if self.__closed:
1822-
# raise EnvError("This environment is closed, you cannot use it.")
1823-
# if not self.__is_init:
1824-
# raise Grid2OpException(
1825-
# "Impossible to set the thermal limit to a non initialized Environment. "
1826-
# "Have you called `env.reset()` after last game over ?"
1827-
# )
1828-
# # update n_line and name_line of ts_manager (old : self.ts_manager.n_line = -1 and self.ts_manager.name_line = None)
1829-
# self.ts_manager.env_limits(thermal_limit=thermal_limit)
1830-
# self.observation_space.set_thermal_limit(thermal_limit=thermal_limit)
1829+
"""
1830+
if self.__closed:
1831+
raise EnvError("This environment is closed, you cannot use it.")
1832+
if not self.__is_init:
1833+
raise Grid2OpException(
1834+
"Impossible to set the thermal limit to a non initialized Environment. "
1835+
"Have you called `env.reset()` after last game over ?"
1836+
)
1837+
# update n_line and name_line of ts_manager (old : self.ts_manager.n_line = -1 and self.ts_manager.name_line = None)
1838+
self.ts_manager.env_limits(thermal_limit=thermal_limit)
1839+
self.backend.thermal_limit_a = self.ts_manager.limits
1840+
self.observation_space.set_thermal_limit(self.ts_manager.limits)
18311841

18321842
def _reset_redispatching(self):
18331843
# redispatching

grid2op/MakeEnv/MakeFromPath.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,8 +1042,7 @@ def make_from_dataset_path(
10421042
)
10431043
# Update the thermal limit if any
10441044
if thermal_limits is not None:
1045-
env.ts_manager.env_limits(thermal_limits)
1046-
env.observation_space.ts_manager.env_limits(env.ts_manager.limits)
1045+
env.set_thermal_limit(thermal_limits)
10471046

10481047
# Set graph layout if not None and not an empty dict
10491048
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
@@ -398,11 +398,11 @@ def change_reward(self, reward_func):
398398
"function when you cannot simulate (because the "
399399
"backend could not be copied)")
400400

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

407407
def reset_space(self):
408408
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)