Error regarding forecast while evaluating PowerLineSwitch agent using `FromOneEpisodeData`
Closed this issue · 3 comments
I am trying to use the newly created FromOneEpisodeData
and following some previous discussions regarding how to test different agents by replaying the environment actions for 36 bus I am doing 3 things
- Generate Logs by setting overflow disconnection to false
- Create an environment with
FromOneEpisodeData
class and see how a DoNothing agent performs - Create an environment with
FromOneEpisodeData
class and see how a PowerLineSwitch performs
However it is giving me the following error. I set the with_forecast
to False
into the third runner because without it was getting a separate error message regarding forecasts. Any help to resolve would be appreciated
Impossible to compute next grid state with error "Grid2OpException "Attempt to retrieve the forecasts when they are not available.""
Traceback (most recent call last):
File "/Users/paula/Desktop/Projects/RL Practice/RLLIB_Practice4/multi_episode_36bus_DN_test5.py", line 167, in <module>
res3 = runner.run(#path_save=logs_path,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Runner/runner.py", line 1227, in run
res = self._run_sequential(
^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Runner/runner.py", line 846, in _run_sequential
) = self.run_one_episode(
^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Runner/runner.py", line 737, in run_one_episode
with self.init_env() as env:
^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Runner/runner.py", line 676, in init_env
env, self.agent = self._new_env(self.chronics_handler, self.parameters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Runner/runner.py", line 616, in _new_env
res = self.envClass.init_obj_from_kwargs(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Environment/environment.py", line 1759, in init_obj_from_kwargs
res = Environment(init_env_path=init_env_path,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Environment/environment.py", line 169, in __init__
self._init_backend(
File "/Users/paula/Desktop/Projects/venvs/L2RPN_080_RLLIB_261_Grid2OP_195/lib/python3.11/site-packages/grid2op/Environment/environment.py", line 420, in _init_backend
raise Grid2OpException(
grid2op.Exceptions.Grid2OpException.Grid2OpException: Grid2OpException "Impossible to initialize the powergrid, the powerflow diverge at iteration 0. Available information are: {'disc_lines': array([-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1], dtype=int32), 'is_illegal': False, 'is_ambiguous': False, 'is_dispatching_illegal': False, 'is_illegal_reco': False, 'reason_alarm_illegal': None, 'reason_alert_illegal': None, 'opponent_attack_line': None, 'opponent_attack_sub': None, 'opponent_attack_duration': 0, 'exception': [Grid2OpException Grid2OpException('Attempt to retrieve the forecasts when they are not available.')], 'rewards': {}}"
Here is the sample code
import grid2op
from grid2op.Runner import Runner
from grid2op.Agent import RecoPowerlineAgent, TopologyGreedy, RandomAgent, DoNothingAgent
from lightsim2grid import LightSimBackend
from grid2op.Chronics import MultifolderWithCache
import re
import numpy as np
from datetime import datetime, timedelta
from grid2op.Agent import PowerLineSwitch as greedy
path_agent = "./saved_multiepisode_agent_36bus_DN_4/"
nb_episode = 1
env_name = "l2rpn_neurips_2020_track1_small" # or any other name
add_msg = "\n"
env = grid2op.make(env_name,
backend=LightSimBackend(),
chronics_class=MultifolderWithCache)
env.chronics_handler.real_data.set_filter(lambda x: re.match(".*july.*", x) is not None)
env.chronics_handler.real_data.reset()
# # optional (change the parameters to allow the )
param = env.parameters
param.NO_OVERFLOW_DISCONNECTION = True
env.change_parameters(param)
env.reset()
# # end optional
runner = Runner(**env.get_params_for_runner(),
#agentClass=RecoPowerlineAgent),
# agentClass=RandomAgent
)
res = runner.run(nb_episode=4,
path_save=path_agent)
print("DoNtohing Agent")
for _, chron_name, cum_reward, nb_time_step, max_ts in res:
msg_tmp = "chronics at: {}".format(chron_name)
msg_tmp += "\ttotal score: {:.6f}".format(cum_reward)
msg_tmp += "\ttime steps: {:.0f}/{:.0f}".format(nb_time_step, max_ts)
print(msg_tmp)
add_msg += msg_tmp
env.close()
###### Compare two different agents from previously generated episode #######
from grid2op.Chronics import FromMultiEpisodeData, FromOneEpisodeData
from grid2op.Opponent import FromEpisodeDataOpponent
from grid2op.Episode import EpisodeData
li_episode = EpisodeData.list_episode(path_agent)
for each_episode in li_episode[:3]:
full_path, episode_studied = each_episode
env2 = grid2op.make(env_name,
backend=LightSimBackend(),
chronics_class=FromOneEpisodeData,
data_feeding_kwargs={"ep_data": each_episode},
opponent_class=FromEpisodeDataOpponent,
opponent_attack_cooldown=1,
)
runner_params = env2.get_params_for_runner()
runner = Runner(**runner_params,)
res2 = runner.run(nb_episode=nb_episode,
# path_save="./saved_multiepisode_agent_36bus_DN_overload_trip/"
)
print("Do Nothing Agent")
for _, chron_name, cum_reward, nb_time_step, max_ts in res2:
msg_tmp = "\tchronics at: {}".format(episode_studied)#.format(chron_name)
msg_tmp += "\ttotal score: {:.6f}".format(cum_reward)
msg_tmp += "\ttime steps: {:.0f}/{:.0f}".format(nb_time_step, max_ts)
print(msg_tmp)
add_msg += msg_tmp + "\n"
env2.close()
env3 = grid2op.make(env_name,
backend=LightSimBackend(),
chronics_class=FromOneEpisodeData,
data_feeding_kwargs={"ep_data": each_episode},
# "start_datetime": datetime(year=2019, month=7, day=start_day),
# "chunk_size": 288},
opponent_class=FromEpisodeDataOpponent,
opponent_attack_cooldown=1,
)
runner_params = env3.get_params_for_runner()
runner_params["verbose"] = "True"
runner = Runner(**runner_params,
agentClass=greedy,
with_forecast=False
)
res3 = runner.run(#path_save=logs_path,
nb_episode=nb_episode,
nb_process=1,
)
for _, chron_name, cum_reward, nb_time_step, max_ts in res3:
msg_tmp = "\tchronics at: {}".format(episode_studied)#.format(chron_name)
msg_tmp += "\ttotal score: {:.6f}".format(cum_reward)
msg_tmp += "\ttime steps: {:.0f}/{:.0f}".format(nb_time_step, max_ts)
print(msg_tmp)
add_msg += msg_tmp + "\n"
env3.close()
print(add_msg)
I have verified that when I don't pass the FromMultiEpisodeData
and FromOneEpisodeData
then the issue don't happen.
Hello,
Remember when posting error message to give a minimal working example.
In your case this could mean:
- using "test=True" when making the environment
- using the runner for 1 episode and not 4
- only give the error for a single agent and not 2
- and most importantly not having a code of 100+ lines
I'll see what I can do but won't have lot of time to spend on this unfortunately. If the could was smaller and executed faster I would spend less time on it and this would increase the odd to find the solution.
The above state is true for me but applies also to every other person, including you
Sometimes I really wonder what I can do to document stuff that are "tricky" / not straightforward.
But first:
- why you used the MultiFolderWithCache for this example ? => no reason, remove it
- why you do all the steps => no reason, remove it and limit it with "max_iter=10" or something
- lightsim2grid is not the issue, remove it
- why you implement 3 runners, you can reproduce the bug with only 2...
If you did that, you could have focused the bug on the forecast (which is already in the error message by the way, but completely polluted by everything else). And then realised that using with_forecast=False
is probably a bad idea when you use an agent that... performs "obs.simulate" (read the doc)
So you could have removed the with_forecast=False
Then, you could have wondered why there were no forecast in the FromOneEpisodeData
. From there, a good place to find a solution is the doc. And in the doc, it's written:
If you want to include perfect forecast (unfortunately you cannot retrieve the original forecasts) you can do:
# same as above
env = grid2op.make(env_name,
chronics_class=FromOneEpisodeData,
data_feeding_kwargs={"ep_data": ep_data},
opponent_class=FromEpisodeDataOpponent,
opponent_attack_cooldown=1,
list_perfect_forecasts=(5, 10, 15)
)
# it creates an environment with perfect forecasts available for the next step (5),
# the step afterwards (10) and again the following one (15)
I honestly don't know how I can be more explicit than this. (ok there is a typo there, the real answer is:
env = grid2op.make(env_name,
chronics_class=FromOneEpisodeData,
data_feeding_kwargs={"ep_data": ep_data,
"list_perfect_forecasts": (5, 10, 15),
},
opponent_class=FromEpisodeDataOpponent,
opponent_attack_cooldown=1,
)
But beside that everything is written.
Thanks for your prompt response and taking your time in investigating the issue. I will keep the advice you provided in mind and reduce the code as much as possible before submitting an issue. The reason I provided 3 runners was to show it was working with DoNothing agent but not with rule based agent.
However I can provide some comments and walk you through on why I was not able to find the solution in the documentation. When I had this issue I went to the documentation and looked up FromOneEpisodeData
. The Chronics page is too long so I opened up the search bar and this is what appeared
As you can see there is no mention of the forecast in these two examples. I scrolled down further till I reached the function forecasts()
. On a high level I understood what it does but I was not sure if this is something I should use to resolve my problem. I proceeded to click on the source
link and it took me to code, that I tried to understand but with no avail. So at this point I am not even on the Chronics page anymore and confused what to do to debug the issue, other than look up similar issues in past in github and submit one. I was not even sure if the issue is with the make
or runner
and looking at the grid2op github runner code I tried using with_forecasts
but now I understand why it is wrong.
After reading your messages I find that in the detailed documentation by class
section the example that you provided. But even if I did find that I would not be convinced that it would resolve my problem. All this to say is that I do consult the documentation and even the github repo to find some way to resolve it. But at least I know now that there are two different places to look for examples in the documentation page. Also the search bar in the documentation page never gives result