Grid2op / grid2op

Grid2Op a testbed platform to model sequential decision making in power systems.
https://grid2op.readthedocs.io/
Mozilla Public License 2.0
300 stars 117 forks source link

Need a consistent model for all "time dependant" attribute (eg redispatching, cooldowns, get_current_step etc.) when simulation with "time_step=0" #598

Open marota opened 8 months ago

marota commented 8 months ago

Environment

Bug description

When simulating on the current state, we would expect the same injections, in particular the same productions. This is verified when no action is performed for instance. But once a redispatch action is applied at some step, the later simulations on the current state don't verify that any more. This leads to wrong simulation result.

How to reproduce

Command line

# command line used if any 

Code snippet

import grid2op
from lightsim2grid import LightSimBackend

bkClass = LightSimBackend

timestep_simu=0
env = grid2op.make("l2rpn_case14_sandbox", backend=bkClass())

obs, *_ =env.step(env.action_space({}))

obs_simulate, *_ =obs.simulate(env.action_space({}),time_step=timestep_simu)

#no redispatch action yet, the productions are the same after simulation on the same state
assert((obs_simulate.prod_p==obs.prod_p).all())

act = env.action_space()
act.redispatch={"gen_2_1": 2.0}

obs, *_ =env.step(act)
obs_simulate, *_ =obs.simulate(env.action_space({}),time_step=timestep_simu)

print(obs.actual_dispatch)
print(obs.target_dispatch)
#a redispatch action has been performed before and actual_dispatch is non non. The productions are not the same anymoreafter simulation on the same state
#actual dispatch has been reapplied to the productions in the simulation whereas it was already part of that chronic
print(obs_simulate.prod_p)
print(obs.prod_p+obs.actual_dispatch)
assert((obs_simulate.prod_p==obs.prod_p).all())

Current output

The last assert fails and it seems that actual dispatch has been reapplied to the productions when doing the simulation, whereas it was already included in the current observed productions

Expected output

We should always verify (obs_simulate.prod_p==obs.prod_p) when simulating do nothing on the current state
BDonnot commented 8 months ago

Hello,

We should always verify (obs_simulate.prod_p==obs.prod_p) when simulating do nothing on the current state

I disagree. A simulation is NOT the current sate.

For example if you have a different solver for simulation or the reality, or if you have noisy observation or if you use different parameters for the solvers in simulation and in the environment (and i'm sure lots of other reasons).

That being said, these are not the issue you faced here.

Your problem is probably related to the slack, only the last generator is modified in your example. When you do a "step" compared to when you do a simulation, you don't start with the exact same "state" (not the same input passed to the solver) so you might end up with different results (slack compensation does not work the same way).

This not a bug grid2op side, this is just yet another case where "simulation is not reality", even in this simplified settings.

BDonnot commented 8 months ago

There might be a difference in behaviour different than "only the slack" as in fact (what you did not show) all the generators changed, not only the last one. Which is weird indeed.

marota commented 8 months ago

From my understanding previous dispatch is counted twice on the current state when doing a simulation with no action. This where this is not clear to me. From the forecasts, you actually take the forecasted chronics and apply the actual dispatch on it which is relevant. But on the current state, it is already applied, so why reapplying it ?

marota commented 8 months ago

And when doing-nothing in this configuration, I would still expect the simulation to return the same productions as in the initial observation. But here the productions where dispatch has been applied some steps before are not the same anymore. This is not only slack related

BDonnot commented 8 months ago

And when doing-nothing in this configuration, I would still expect the simulation to return the same productions as in the initial observation.

In the general case no it will not, even without noise or with the same solver.

Initialisation of the powerflow will be different so output might be different. But it's not what caused the "issue" you showed I agree.

BDonnot commented 8 months ago

The problem here is that the "simulate" is properly defined for redispatching. There are no clear specifications on what it should do in all cases, because redispatching is a "time dependant" attribute and "simulating" time dependant attribute when the time does not change is... not clear.

A clear specification for the behaviour of redispatching in all cases should be done. @marota can you do that for (suppose t is the current step):

The bug is that the "actual_dispatch" is not updated correctly in the "sim_obs": it should be doubled as you said.

BDonnot commented 8 months ago

And the specifications should also holds for storage units (with the charge and the impact on generators) and the curtailment.

And take into account the case where the redispatching action is "too strong" and cannot be met at "the first time".

BDonnot commented 1 month ago

A "model for simulate with time_step=0" is also needed if we chain "simulation" (see #651) this is also related to the issue that get_current_date() is also a time dependant attribute.