Simulator
This page is organized as follow:
Objectives
The “Simulator” class is used to interact, with a grid2op “api-like” (the concept of action and observation) with a powergrid simulator that is independant of the one used by the environment.
This can for example be used for “model based reinforcement learning” or to assess the “validity” of an action in some “more extreme” conditions.
It behaves similarly to env.step(…) or obs.simulate(…) with a few key differences:
you can “chain” the call to simulator: simulator.predict(…).predict(…).predict(…)
it does not take into account the “time”: no cooldown on lines nor substation, storage “state of charge” (energy) does not decrease when you use them
no automatic line disconnection: lines are not disconnected when they are above their limit
no opponent will act on the grid
Usage
You can use it to assess if the grid state is “resilient enough” if the loads and generators increase of 5% :
import grid2op
env_name = ... # any environment name available (eg. "l2rpn_case14_sandbox")
env = grid2op.make(env_name)
obs = env.reset()
#### later in the code, for example in an Agent:
simulator = obs.get_simulator()
load_p_stressed = obs.load_p * 1.05
gen_p_stressed = obs.gen_p * 1.05
do_nothing = env.action_space()
simulator_stressed = simulator.predict(act=do_nothing,
new_gen_p=gen_p_stressed,
new_load_p=load_p_stressed)
if not simulator_stressed.converged:
# the solver fails to find a solution for this action
# you are likely to run into trouble if you use that...
... # do something
obs_stressed = simulator_stressed.current_obs
You can also “chain” the call to simulators, usefull for “model based” strategies
import grid2op
env_name = ... # any environment name available (eg. "l2rpn_case14_sandbox")
env = grid2op.make(env_name)
obs = env.reset()
#### later in the code, for example in an Agent:
simulator = obs.get_simulator()
load_p_stressed = obs.load_p * 1.05
gen_p_stressed = obs.gen_p * 1.05
do_nothing = env.action_space()
simulator_stressed = simulator.predict(act=do_nothing, new_gen_p=gen_p_stressed, new_load_p=load_p_stressed)
if not simulator_stressed.converged:
# the solver fails to find a solution for this action
# you are likely to run into trouble if you use that...
... # do something
act1 = ...
simulator_afteract1 = simulator_stressed.predict(act=act1)
act2 = ...
simulator_afteract2 = simulator_stressed.predict(act=act2)
# etc.
Another use (though you might need to use dedicated tools for such purpose such as https://lightsim2grid.readthedocs.io/en/latest/security_analysis.html ) is to check whether your grid is “N-1 secure” which means that if a powerline were to be disconnected (for example by the opponent) then the state it is in would not be too dangerous:
import numpy as np
import grid2op
env_name = ... # any environment name available (eg. "l2rpn_case14_sandbox")
env = grid2op.make(env_name)
obs = env.reset()
#### later in the code, for example in an Agent:
simulator = obs.get_simulator()
act1 = ... # the action your agent has selected
simulator_afteract1 = simulator.predict(act=act1)
for line_id in range(obs.n_line):
act_disco_line = env.action_space()
act_disco_line.set_line_status = [(line_id, -1)]
sim_after_disco_line = simulator_afteract1.predict(act_disco_line)
if sim_after_disco_line.converged:
obs_after_disco = sim_after_disco_line.current_obs
# and for example check the current on all line is bellow the limit
if np.any(obs_after_disco.rho > 1.):
# your action does not make the grid "N-1" safe,
# because if you disconnect line `line_id` you got some overflow
... # do something
else:
# the simulator has not found any solution, it is likely that this will lead
# to a game over in "real time"
# your grid is not "N-1" safe because disconnection of line `line_id` lead
# to a non feasible grid state
... # do something
Warning
This module is still under development, if you need any functionality, let us know with a github “feature request” (https://github.com/rte-france/Grid2Op/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=)
Detailed Documentation by class
Classes:
|
This class represents a "simulator". |
- class grid2op.simulator.Simulator(backend: Backend | None, env: BaseEnv | None = None, tol_redisp=1e-06, _highres_sim_counter: HighResSimCounter | None = None)[source]
Bases:
object
This class represents a “simulator”. It allows to check the impact on this or that on th powergrid, quite like what human operators have at their disposal in control rooms.
It behaves similarly to env.step(…) or obs.simulate(…) with a few key differences:
you can “chain” the call to simulator: simulator.predict(…).predict(…).predict(…)
it does not take into account the “time”: no cooldown on lines nor substation, storage “state of charge” (energy) does not decrease when you use them
no automatic line disconnection: lines are not disconnected when they are above their limit
no opponent will act on the grid
Please see the documentation for usage examples.
Methods:
__init__
(backend[, env, tol_redisp, ...])change_backend
(backend)You can use this function in case you want to change the "solver" use to perform the computation.
change_backend_type
(backend_type, grid_path, ...)It allows to change the type of the backend used
close
()close the underlying backend
copy
()Allows to perform a (deep) copy of the simulator.
predict
(act[, new_gen_p, new_gen_v, ...])Predict the state of the grid after a given action has been taken.
set_state
([obs, do_powerflow, new_gen_p, ...])Set the state of the simulator to a given state described by an observation (and optionally some new loads and generation)
Attributes:
list of weak references to the object (if defined)
returns: Whether or not the powerflow has converged :rtype: bool
- __init__(backend: Backend | None, env: BaseEnv | None = None, tol_redisp=1e-06, _highres_sim_counter: HighResSimCounter | None = None)[source]
- __weakref__
list of weak references to the object (if defined)
- change_backend(backend: Backend) None [source]
You can use this function in case you want to change the “solver” use to perform the computation.
For example, you could use a machine learning based model to do the computation (to accelerate them), provided that you have at your disposal such an algorithm.
Warning
The backend you pass as argument should be initialized with the same grid as the one currently in use.
Notes
Once changed, all the “simulator” that “derived” from this simulator will use the same backend types.
- Parameters:
backend (Backend) – Another grid2op backend you can use to perform the computation.
- Raises:
SimulatorError – When you do not pass a correct backend.
- change_backend_type(backend_type: type, grid_path: PathLike, **kwargs)[source]
It allows to change the type of the backend used
- Parameters:
backend_type (type) – The new backend type
grid_path (os.PathLike) – The path from where to load the powergrid
kwargs – Extra arguments used to build the backend.
Notes
Once changed, all the “simulator” that “derived” from this simulator will use the same backend types.
- Raises:
SimulatorError – if something went wrong (eg you do not pass a type, your type does not inherit from Backend, the file located at grid_path does not exists etc.)
- property converged: bool
returns: Whether or not the powerflow has converged :rtype: bool
- copy() Self [source]
Allows to perform a (deep) copy of the simulator.
- Returns:
A (deep) copy of the simulator you want to copy.
- Return type:
- Raises:
SimulatorError – In case the simulator is not initialized.
- predict(act: BaseAction, new_gen_p: ndarray | None = None, new_gen_v: ndarray | None = None, new_load_p: ndarray | None = None, new_load_q: ndarray | None = None, do_copy: bool = True) Simulator [source]
Predict the state of the grid after a given action has been taken.
- Parameters:
act (BaseAction) – The action you want to take
new_gen_p (np.ndarray, optional) – the new production active setpoint, by default None
new_gen_v (np.ndarray, optional) – the new production voltage setpoint, by default None
new_load_p (np.ndarray, optional) – the new consumption active values, by default None
new_load_q (np.ndarray, optional) – the new consumption reactive values, by default None
do_copy (bool, optional) – Whether to make a copy or not, by default True
Examples
A possible example is:
import grid2op env_name = "l2rpn_case14_sandbox" # or any other name env = grid2op.make(env_name) obs = env.reset() #### later in the code, for example in an Agent: simulator = obs.get_simulator() load_p_stressed = obs.load_p * 1.05 gen_p_stressed = obs.gen_p * 1.05 do_nothing = env.action_space() simulator_stressed = simulator.predict(act=do_nothing, new_gen_p=gen_p_stressed, new_load_p=load_p_stressed) if not simulator_stressed.converged: # the solver fails to find a solution for this action # you are likely to run into trouble if you use that... ... # do something obs_stressed = simulator_stressed.current_obs
- Returns:
The new simulator representing the grid state after the simulation of the action.
- Return type:
- set_state(obs: BaseObservation | None = None, do_powerflow: bool = True, new_gen_p: ndarray | None = None, new_gen_v: ndarray | None = None, new_load_p: ndarray | None = None, new_load_q: ndarray | None = None, update_thermal_limit: bool = True)[source]
Set the state of the simulator to a given state described by an observation (and optionally some new loads and generation)
- Parameters:
obs (Optional[BaseObservation], optional) – The observation to get the state from, by default None
do_powerflow (bool, optional) – Whether to use the underlying backend to get a consistent state after this modification or not, by default True
new_gen_p (np.ndarray, optional) – new generator active setpoint, by default None
new_gen_v (np.ndarray, optional) – new generator voltage setpoint, by default None
new_load_p (np.ndarray, optional) – new load active consumption, by default None
new_load_q (np.ndarray, optional) – new load reactive consumption, by default None
update_thermal_limit (bool, optional) – Do you update the thermal limit of the backend (we recommend to leave it to True otherwise some bugs can appear such as https://github.com/rte-france/Grid2Op/issues/377)
- Raises:
SimulatorError – In case the current simulator is not initialized.
If you still can’t find what you’re looking for, try in one of the following pages:
Still trouble finding the information ? Do not hesitate to send a github issue about the documentation at this link: Documentation issue template