Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev possibility to turn off generators, loads and storage units #675

Merged
merged 78 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
96e1ca5
Add: AllowShedding attribute to GridObjects
DEUCE1957 Nov 4, 2024
75cf5a7
Debug: GridObject AllowShedding conversion
DEUCE1957 Nov 4, 2024
55e8c41
Add: Exception if shedding is not supported by Backend
DEUCE1957 Nov 4, 2024
51eb97e
Refact: Remove bool return from set_shedding() method
DEUCE1957 Nov 4, 2024
623d04b
Test: Add Entry for Allow_Shedding
DEUCE1957 Nov 4, 2024
ccbd1db
Refact: Remove Allow_Shedding from dict repr of GridObject
DEUCE1957 Nov 4, 2024
9c0078e
Add: Unit Tests
DEUCE1957 Nov 5, 2024
90c96d8
Refact: Use DEFAULT constants for n_busbar and allow_shedding
DEUCE1957 Nov 6, 2024
50b7c0f
Add: Can/Cannot Handle Interface for Load/Gen detachment
DEUCE1957 Nov 6, 2024
54ef719
Refact: Remove Set_Shedding
DEUCE1957 Nov 6, 2024
d9da4bf
Add: Backend-Agnostic Detachment Check
DEUCE1957 Nov 6, 2024
e66fd03
Add: ClassAttribute integration for AllowDetachment
DEUCE1957 Nov 6, 2024
6aa67c0
Debug: Use _get_topo_vect inside Backend check for Detachment
DEUCE1957 Nov 8, 2024
aebfaa1
Test: Update Backend Tests to expect _run_pf_with_diverging to catch …
DEUCE1957 Nov 8, 2024
486cffa
Debug: Try to fix Test_Issue_125
DEUCE1957 Nov 8, 2024
f16ba3c
Merge remote-tracking branch 'deuce1957/dev_shedding' into dev_shedding
BDonnot Nov 19, 2024
938709a
Add: 'detachment_is_allowed' in GridObj and Environment
DEUCE1957 Nov 23, 2024
4112dfe
Debug: assert 'detachment_is_allowed' in GridObject
DEUCE1957 Nov 23, 2024
7b6dabc
Test: Update strings for detachment
DEUCE1957 Nov 24, 2024
0666b39
Debug: Fix nested f-string in GridObjects
DEUCE1957 Nov 24, 2024
7cdf6c2
Debug: Add post-powerflow check for load / gen disconnect
DEUCE1957 Nov 24, 2024
bb23193
Debug: Add convergence check to post-powerflow check
DEUCE1957 Nov 24, 2024
c4d2c5c
Merge remote-tracking branch 'deuce1957/dev_shedding' into dev_shedding
BDonnot Nov 25, 2024
62f5428
fixing conflicts
BDonnot Nov 25, 2024
e921057
fix some minor things, before handling actions [skip ci]
BDonnot Nov 25, 2024
d9b3e11
some addition of the feature on the action, not finished yet
BDonnot Nov 25, 2024
6e08212
forbid args in env creation, fix bug on CI, refacto the 'make' call
BDonnot Nov 25, 2024
4cf73c6
fixes to make tests pass
BDonnot Nov 25, 2024
dbba375
fix issue 125
BDonnot Nov 25, 2024
09d1a65
still working on making tests pass with new more concise implementation
BDonnot Nov 25, 2024
d6bf9a8
should fix all issues, need to make the AAA test suite better now
BDonnot Nov 26, 2024
8b70407
fixing broken tests (hopefully) and improve AAA backend test suite fo…
BDonnot Nov 26, 2024
2e81300
remove a pdb...
BDonnot Nov 26, 2024
3e25e95
Debug: Fix check in PandaPower Backend that prevents large-scale load…
DEUCE1957 Nov 27, 2024
d2d71ba
Debug: Use load dataframe instead of res_load for in_service check
DEUCE1957 Nov 27, 2024
809dfe4
Debug: Temporarily Rollback HotFix to PandaPowerBackend
DEUCE1957 Nov 27, 2024
5350712
Merge pull request #1 from BDonnot/dev_shedding
DEUCE1957 Nov 27, 2024
7d34daa
Merge remote-tracking branch 'upstream/dev_1.11.0' into dev_dev_shedding
BDonnot Nov 28, 2024
b970632
fixing conflicts when synching with dev_shedding
BDonnot Nov 28, 2024
a97643c
add possibility to detach generators and storage units in the action
BDonnot Nov 28, 2024
d2117e9
Merge branch 'dev_1.11.0' of https://github.com/Grid2op/grid2op into …
DEUCE1957 Dec 2, 2024
edcc81c
Refact: Improve Code Smell
DEUCE1957 Dec 2, 2024
5ee9aee
Add: Bring back fix to PandaPowerBackend for isolated loads
DEUCE1957 Dec 2, 2024
9adc3a4
Refact: Simplify _check_kirchhoff
DEUCE1957 Dec 2, 2024
42535de
Debug: Fix missing param in kirchhoff static methods
DEUCE1957 Dec 2, 2024
9a6b696
Refact: Emulate obs._check_kirchhoff in Backend._check_kirchhoff
DEUCE1957 Dec 2, 2024
0df6f5d
Merge branch 'dev_shedding' into dev_dev_shedding
BDonnot Dec 3, 2024
d07041b
fixing conflicts by merging with 'upstream' and bd_dev
BDonnot Dec 3, 2024
3bf8934
Merge pull request #671 from Grid2op/dev_1.11.0
BDonnot Dec 3, 2024
5851026
refactoring check_kirchhoff methods of Observation and Backend, shoul…
BDonnot Dec 4, 2024
2b37759
Merge branch 'dev_shedding' into dev_dev_shedding
BDonnot Dec 4, 2024
3529f10
fix a bug in loading back actions from / to json and to / from vect …
BDonnot Dec 4, 2024
38cd8c3
fix issue with copying action, add action topological_impact caching
BDonnot Dec 4, 2024
70d9292
Merge: dev_1.11.0 into dev_shedding
DEUCE1957 Dec 5, 2024
7dcbfa4
Merge pull request #2 from BDonnot/dev_shedding
DEUCE1957 Dec 5, 2024
62a1471
fix a bug when deserializing actions
BDonnot Dec 5, 2024
777d778
fix some other bugs in the tests
BDonnot Dec 5, 2024
24c6cf6
try to fix ci bug that I cannot reproduce
BDonnot Dec 5, 2024
17afbf4
fix some issue when resetting the class attributes, hopefully
BDonnot Dec 5, 2024
1c0220f
trying to fix bug on CI
BDonnot Dec 6, 2024
eb49910
trying to fix bug on CI
BDonnot Dec 6, 2024
8dcf4aa
adding support for detachment in backend action
BDonnot Dec 12, 2024
d3415f9
adding first working -for basic functionality- for shedding, end to end
BDonnot Dec 13, 2024
812a2e8
Merge remote-tracking branch 'upstream/dev_1.11.0' into dev_shedding
BDonnot Dec 13, 2024
c29b619
fix some last issue before merging on dev_turnoff_gen_load
BDonnot Dec 13, 2024
fb28f9b
fix a typo and synch with base branch
BDonnot Dec 13, 2024
7241e13
fix another typo
BDonnot Dec 13, 2024
93ec180
fixing broken tests for the Observation
BDonnot Dec 13, 2024
d67e08d
fix some broken tests again
BDonnot Dec 13, 2024
953d273
fix some other broken tests
BDonnot Dec 13, 2024
0a40daf
yet some other fixes
BDonnot Dec 13, 2024
73d14dd
Merge branch 'BDonnot-dev_shedding' into dev_shedding
DEUCE1957 Dec 13, 2024
d0e8385
Merge pull request #655 from DEUCE1957/dev_shedding
BDonnot Dec 13, 2024
7d8af65
upgrade to version 1.11.0.dev3
BDonnot Dec 13, 2024
cb7a9f4
fixing some issues spotted by sonarcube
BDonnot Dec 16, 2024
55f08cf
two minor fixes
BDonnot Dec 16, 2024
c6299c9
some fixes due to matplotlib deprecation function
BDonnot Dec 16, 2024
1b717c8
Merge pull request #674 from BDonnot/dev_dev_shedding
BDonnot Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ Native multi agents support:
name is added. This behaviour can be turned off by passing `_add_cls_nm_bk=False`
when calling `grid2op.make(...)`. If you develop a new Backend, you can also
customize the added name by overloading the `get_class_added_name` class method.
- [BREAKING] it is now forbidden to create environment with arguments.
Only key-word arguments are allowed.
- [BREAKING] the way actions is serialized has been changed with respect to the `from_vect` /
`to_vect` method. This might introduce some issues when loading previously saved actions
with this methods.
- [FIXED] issue https://github.com/Grid2op/grid2op/issues/657
- [FIXED] missing an import on the `MaskedEnvironment` class
- [FIXED] a bug when trying to set the load_p, load_q, gen_p, gen_v by names.
Expand All @@ -123,7 +128,11 @@ Native multi agents support:
environment data
- [FIXED] an issue preventing to set the thermal limit in the options
if the last simulated action lead to a game over
- [FIXED] some bugs in `act.from_json(...)` due to the handling of the injection modifications.
- [FIXED] logos now have the correct URL
- [FIXED] deprecated call to `tostring_rgb` (replaced `tostring_argb`) in the env.render function.
- [FIXED] warnings not properly issued in the AAA test when backend failed to call
`can_handle_XXX` functions (*eg* `can_handle_more_than_2_busbar()` or `can_handle_detachment()`)
- [ADDED] possibility to set the "thermal limits" when calling `env.reset(..., options={"thermal limit": xxx})`
- [ADDED] possibility to retrieve some structural information about elements with
with `gridobj.get_line_info(...)`, `gridobj.get_load_info(...)`, `gridobj.get_gen_info(...)`
Expand All @@ -132,6 +141,10 @@ Native multi agents support:
- [ADDED] a method to check the KCL (`obs.check_kirchhoff`) directly from the observation
(previously it was only possible to do it from the backend). This should
be used for testing purpose only
- [ADDED] parameters to disable the "redispatching routine" of the environment
(see `params.ENV_DOES_REDISPATCHING`)
- [ADDED] parameters to stop the episode when one of the constraints of one of the
generators is not met (see `params.STOP_EP_IF_SLACK_BREAK_CONSTRAINTS`)
- [ADDED] possibility to set the initial time stamp of the observation in the `env.reset`
kwargs by using `env.reset(..., options={"init datetime": XXX})`
- [IMPROVED] possibility to set the injections values with names
Expand All @@ -151,12 +164,18 @@ Native multi agents support:
does not have shunt information but there are not shunts on the grid.
- [IMPROVED] consistency of `MultiMixEnv` in case of automatic_classes (only one
class is generated for all mixes)
- [IMRPOVED] handling of disconnected elements in the backend no more
raise error. The base `Backend` class does that.
- [IMPROVED] the `act.as_serializable_dict()` to be more 'backend agnostic'as
it nows tries to use the name of the elements in the json output
- [IMPROVED] the way shunt data are digested in the `BaseAction` class (it is now
possible to use the same things as for the other types of element)
- [IMPROVED] grid2op does not require the `chronics` folder when using the `FromHandlers`
class
- [IMPROVED] the function `action.get_topological_impact(...)` has now a "caching" mechanism
that allows not to recompute it over and over again (this is internal API please do not change
it... unless you know what you are doing)


[1.10.4] - 2024-10-15
-------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'Benjamin Donnot'

# The full version, including alpha/beta/rc tags
release = '1.11.0.dev2'
release = '1.11.0.dev3'
version = '1.11'


Expand Down
83 changes: 83 additions & 0 deletions getting_started/13_DetachmentOfLoadsAndGenerators.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Detachment of Loads and Generators\n",
"In emergency conditions, it may be possible / necessary for a grid operator to detach certain loads, generators, or other components in order to prevent a larger blackout. This notebook explores how this can be achieved in Grid2OP. \n",
"\n",
"By default detachment is disabled in all environments, to provide the keyword argument allow_detachment when initializing the environment. The backend must be able to support this feature."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import grid2op\n",
"from grid2op.Parameters import Parameters\n",
"from grid2op.PlotGrid import PlotMatplot\n",
"from pathlib import Path\n",
"\n",
"# Setup Environment\n",
"data_path = Path.cwd() / \"grid2op\" / \"data\"\n",
"p = Parameters()\n",
"p.MAX_SUB_CHANGED = 5\n",
"env = grid2op.make(data_path / \"rte_case5_example\", param=p, allow_detachment=True)\n",
"\n",
"# Setup Plotter Utility\n",
"plotter = PlotMatplot(env.observation_space, load_name=True, gen_name=True, dpi=150)\n",
"print(f\"Loads: {env.n_load}, Generators: {env.n_gen}, Storage: {env.n_storage}, Allow Detachment: {env._allow_detachment}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Detach the loads at substation 3 and 4. Normally this would cause a game-over, but if allow_detachment is True, the powerflow will be run. Game over in these cases can only occur if the powerflow does not converge."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"load_lookup = {name:i for i,name in enumerate(env.name_load)}\n",
"gen_lookup = {name:i for i,name in enumerate(env.name_gen)}\n",
"act = env.action_space({\"set_bus\":[(env.load_pos_topo_vect[load_lookup[\"load_3_1\"]], -1),\n",
" (env.load_pos_topo_vect[load_lookup[\"load_4_2\"]], -1)]})\n",
"print(act)\n",
"env.set_id(\"00\")\n",
"init_obs = env.reset()\n",
"obs, reward, done, info = env.step(act)\n",
"plotter.plot_obs(obs, figure=plt.figure(figsize=(8,5)))\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv_test",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
119 changes: 88 additions & 31 deletions grid2op/Action/_backendAction.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,66 @@ def _aux_iadd_reconcile_disco_reco(self):
self.line_ex_pos_topo_vect,
self.last_topo_registered,
)


def _aux_iadd_detach(self, other, set_topo_vect : np.ndarray, modif_inj: bool):
cls = type(self)
if other._modif_detach_load:
set_topo_vect[cls.load_pos_topo_vect[other._detach_load]] = -1
modif_set_bus = True
if other._modif_detach_gen:
set_topo_vect[cls.gen_pos_topo_vect[other._detach_gen]] = -1
modif_set_bus = True
if other._modif_detach_storage:
set_topo_vect[cls.storage_pos_topo_vect[other._detach_storage]] = -1
modif_set_bus = True
if modif_inj:
for key, vect_ in other._dict_inj.items():
if key == "load_p" or key == "load_q":
vect_[other._detach_load] = 0.
elif key == "prod_p":
vect_[other._detach_gen] = 0.
elif key == "prod_v":
vect_[other._detach_gen] = np.nan
else:
raise RuntimeError(f"Unknown key {key} for injection found.")
else:
# TODO when injection is not modified by the action (eg change nothing)
if other._modif_detach_load:
modif_inj = True
other._dict_inj["load_p"] = np.full(cls.n_load, fill_value=np.nan, dtype=dt_float)
other._dict_inj["load_q"] = np.full(cls.n_load, fill_value=np.nan, dtype=dt_float)
other._dict_inj["load_p"][other._detach_load] = 0.
other._dict_inj["load_q"][other._detach_load] = 0.
if other._modif_detach_gen:
modif_inj = True
other._dict_inj["prod_p"] = np.full(cls.n_gen, fill_value=np.nan, dtype=dt_float)
other._dict_inj["prod_p"][other._detach_gen] = 0.
return modif_set_bus, modif_inj

def _aux_iadd_line_status(self, other: BaseAction, switch_status: np.ndarray, set_status: np.ndarray):
if other._modif_change_status:
self.current_topo.change_status(
switch_status,
self.line_or_pos_topo_vect,
self.line_ex_pos_topo_vect,
self.last_topo_registered,
)
if other._modif_set_status:
self.current_topo.set_status(
set_status,
self.line_or_pos_topo_vect,
self.line_ex_pos_topo_vect,
self.last_topo_registered,
)

# if other._modif_change_status or other._modif_set_status:
(
self._status_or_before[:],
self._status_ex_before[:],
) = self.current_topo.get_line_status(
self.line_or_pos_topo_vect, self.line_ex_pos_topo_vect
)

def __iadd__(self, other : BaseAction) -> Self:
"""
.. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\
Expand All @@ -760,16 +819,23 @@ def __iadd__(self, other : BaseAction) -> Self:

"""

set_status = other._set_line_status
set_status = 1 * other._set_line_status
switch_status = other._switch_line_status
set_topo_vect = other._set_topo_vect
set_topo_vect = 1 * other._set_topo_vect
switcth_topo_vect = other._change_bus_vect
redispatching = other._redispatch
storage_power = other._storage_power

modif_set_bus = other._modif_set_bus
modif_inj = other._modif_inj
cls = type(self)

# I detachment (before all else)
if cls.detachment_is_allowed and other.has_element_detached():
modif_set_bus, modif_inj = self._aux_iadd_detach(other, set_topo_vect, modif_inj)

# I deal with injections
# Ia set the injection
if other._modif_inj:
if modif_inj:
self._aux_iadd_inj(other._dict_inj)

# Ib change the injection aka redispatching
Expand All @@ -781,39 +847,18 @@ def __iadd__(self, other : BaseAction) -> Self:
self.storage_power.set_val(storage_power)

# II shunts
if type(self).shunts_data_available:
if cls.shunts_data_available:
self._aux_iadd_shunt(other)

# III line status
# this need to be done BEFORE the topology, as a connected powerline will be connected to their old bus.
# regardless if the status is changed in the action or not.
if other._modif_change_status:
self.current_topo.change_status(
switch_status,
self.line_or_pos_topo_vect,
self.line_ex_pos_topo_vect,
self.last_topo_registered,
)
if other._modif_set_status:
self.current_topo.set_status(
set_status,
self.line_or_pos_topo_vect,
self.line_ex_pos_topo_vect,
self.last_topo_registered,
)

# if other._modif_change_status or other._modif_set_status:
(
self._status_or_before[:],
self._status_ex_before[:],
) = self.current_topo.get_line_status(
self.line_or_pos_topo_vect, self.line_ex_pos_topo_vect
)

self._aux_iadd_line_status(other, switch_status, set_status)

# IV topo
if other._modif_change_bus:
self.current_topo.change_val(switcth_topo_vect)
if other._modif_set_bus:
if modif_set_bus:
self.current_topo.set_val(set_topo_vect)

# V Force disconnected status
Expand All @@ -823,7 +868,7 @@ def __iadd__(self, other : BaseAction) -> Self:
)

# At least one disconnected extremity
if other._modif_change_bus or other._modif_set_bus:
if other._modif_change_bus or modif_set_bus:
self._aux_iadd_reconcile_disco_reco()
return self

Expand Down Expand Up @@ -1444,3 +1489,15 @@ def update_state(self, powerline_disconnected) -> None:
)
self.last_topo_registered.update_connected(self.current_topo)
self.current_topo.reset()

def get_load_detached(self):
cls = type(self)
return self.current_topo.values[cls.load_pos_topo_vect] == -1

def get_gen_detached(self):
cls = type(self)
return self.current_topo.values[cls.gen_pos_topo_vect] == -1

def get_sto_detached(self):
cls = type(self)
return self.current_topo.values[cls.storage_pos_topo_vect] == -1
2 changes: 0 additions & 2 deletions grid2op/Action/actionSpace.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ def __init__(
Class specifying the rules of the game used to check the legality of the actions.

"""
actionClass._add_shunt_data()
actionClass._update_value_set()
SerializableActionSpace.__init__(self, gridobj, actionClass=actionClass, _local_dir_cls=_local_dir_cls)
self.legal_action = legal_action

Expand Down
Loading
Loading