marota / ExpertOp4Grid

Expert System agent to operate a power grid
https://expertop4grid.readthedocs.io/en/latest
Mozilla Public License 2.0
7 stars 2 forks source link

Bug when the current topology is not "one node for every substation" #21

Closed marota closed 4 years ago

marota commented 4 years ago

A use case displays the "end result dataframe" with only Nans for action efficacy. It should not be.

image

However:

To reproduce:

The problem arrises ar timestep 798

import grid2op
from l2rpn_baselines.ExpertAgent import ExpertAgent

dataset = "rte_case14_realistic"
env=grid2op.make(dataset)

res = evaluate(env, nb_episode=1,logs_path="ExpertAgent")

To investigate more deeply:


chronic_scenario=0
env.set_id(chronic_scenario)
env.reset()

agent = ExpertAgent(env.action_space, env.observation_space,"agent_test")

obs=env.get_obs()
done=False
reward=0.0
info=None

maxIter=797 #the expert system will act at timestep 798 
iter=0
#we run the agent 

while not done and iter<maxIter:
    act=agent.act(obs,reward,done)
    obs,reward,done,info=env.step(act)
    iter+=1
import matplotlib.pyplot as plt  # pip install matplotlib
import imageio  # pip install imageio

#plot the observation
from grid2op.PlotGrid import PlotMatplot
plot_helper = PlotMatplot(env.observation_space)
fig_obs = plot_helper.plot_obs(obs)

image

#test action simulation from the data frame
sub_id=12
target_topology=[2, 1, 1, 2]     
action_def={"set_bus": {"substations_id": [(sub_id, target_topology)] } }
action=env.action_space(action_def)
osb_simu,_reward,_done,_info=obs.simulate(action,time_step=0)

#plot simulated observation
fig_obs_simlu = plot_helper.plot_obs(osb_simu)

image

NMegel commented 4 years ago

I could reproduce the graph you get at timestep 797

Yet, I could not reproduce the same expert_result dataframe. I don't have substation 12 in it, so it seems alphadeesp doesn't return the best actions image

So I set the parameter "totalnumberofsimulatedtopos" in Expert Agent to 25 instead of 10 to see more actions self.config = { "totalnumberofsimulatedtopos": 25, "numberofsimulatedtopospernode": 5, "maxUnusedLines": 3, "ratioToReconsiderFlowDirection": 0.75, "ratioToKeepLoop": 0.25, "ThersholdMinPowerOfLoop": 0.1, "ThresholdReportOfLine": 0.2 }

You may want to check:

marota commented 4 years ago

grid2op version = 1.1.0

On my side, self.config = { "totalnumberofsimulatedtopos": 30, "numberofsimulatedtopospernode": 10, "maxUnusedLines": 3, "ratioToReconsiderFlowDirection": 0.75, "ratioToKeepLoop": 0.25, "ThersholdMinPowerOfLoop": 0.1, "ThresholdReportOfLine": 0.2 }

I will look into it. By the way, I had to make this slight improvement in l2rpn-baseline/ExpertAgent (but I am not allowed to commit): ++ best_action=self.action_space({})#do nothing action ++ if not np.isnan(index_best_action): ++ best_action = actions[index_best_action]

NMegel commented 4 years ago

Is this what you want to commit ? image

marota commented 4 years ago

Yes

NMegel commented 4 years ago

OK it's done in commit 5a38e54ce143e51907592257e6fad547d4890339

NMegel commented 4 years ago

When debugging we noticed 2 important things:

marota commented 4 years ago

Expert4Grid is not working properly when the topology is different from the meshed topology. Launching the expert system at this timestep (for which substation 1 is split into 2 nodes) we obtain the following overflow graph image substation 1 should be split into 2 nodes

the corresponding Graph DataFrame confirms it: image

marota commented 4 years ago
from alphaDeesp.core.grid2op.Grid2opSimulation import Grid2opSimulation
config= {
            "totalnumberofsimulatedtopos": 30,
            "numberofsimulatedtopospernode": 10,
            "maxUnusedLines": 3,
            "ratioToReconsiderFlowDirection": 0.75,
            "ratioToKeepLoop": 0.25,
            "ThersholdMinPowerOfLoop": 0.1,
            "ThresholdReportOfLine": 0.2
        }
id_lines=[17]
plot_graphs=True
plot_folder='Test_Expert_Baseline'
sim = Grid2opSimulation(obs, env.action_space, env.observation_space, param_options=config, debug=False,
                                 ltc=id_lines, plot=plot_graphs, plot_folder = plot_folder)
marota commented 4 years ago
import os
if plot_graphs:
    #plot_folder = "alphaDeesp/ressources/output"
    os.makedirs(plot_folder, exist_ok=True)
    gridName = dataset#config['DEFAULT']['gridPath'].split('/')[-1]
    plot_folder = os.path.join(plot_folder, gridName)
    os.makedirs(plot_folder, exist_ok=True)
    lineName = 'linetocut_'+str(id_lines)
    plot_folder = os.path.join(plot_folder, lineName)
    os.makedirs(plot_folder, exist_ok=True)
    #scenarioName = 'Scenario_'+str(args.chronicscenario)
    plot_folder = os.path.join(plot_folder, scenarioName)
    os.makedirs(plot_folder, exist_ok=True)
    timestepName = 'Timestep_' + str(timestep_of_interest)
    plot_folder = os.path.join(plot_folder, timestepName)
    os.makedirs(plot_folder, exist_ok=True)

from alphaDeesp.expert_operator import expert_operator
ranked_combinations, expert_system_results, action = expert_operator(sim, plot=plot_graphs)
marota commented 4 years ago

https://github.com/marota/ExpertOp4Grid/blob/2830ceb5737dbde37ac3c449961da9201bf738f8/alphaDeesp/core/grid2op/Grid2opSimulation.py#L284

This function needs to be changed: we expect node ids and not substations ids, especially when a substation has 2 nodes. In AlphaDeesp represenation, the second node id is 666+sub_id

Because of that, the graph of alphadeesp is not the graph of the current topology is nodes splitting has already been performed

marota commented 4 years ago

https://github.com/marota/ExpertOp4Grid/blob/2830ceb5737dbde37ac3c449961da9201bf738f8/alphaDeesp/tests/grid2op/grid2op_grid_test.py#L107

This test should be rewritten: the node splitting action should be done using grid2op, before creating sim = Grid2opSimulation() https://github.com/marota/ExpertOp4Grid/blob/2830ceb5737dbde37ac3c449961da9201bf738f8/alphaDeesp/tests/grid2op/grid2op_grid_test.py#L20

marota commented 4 years ago
def test_detailed_graph_with_node_0_split_in_two():
    """
    From an observation, avec using load2()
    basic graph with zero nodes split in two, has 14 nodes
    with node 0 split in two, we should have 15 nodes
    :return:
    """
    config = configparser.ConfigParser()
    config.read("./alphaDeesp/tests/resources_for_tests_grid2op/config_for_tests.ini")
    param_folder = "./alphaDeesp/tests/resources_for_tests_grid2op/l2rpn_2019_ltc_9"

    loader = Grid2opObservationLoader(param_folder)
    env, obs, action_space = loader.get_observation()

    new_configuration = [2, 2, 2, 1, 1]
    sub_id = 4
    action_def = {"set_bus": {"substations_id": [(sub_id, new_configuration)]}}
    action = env.action_space(action_def)
    osb, _reward, _done, _info = env.step(action)

    observation_space = env.observation_space
    sim = Grid2opSimulation(obs, action_space, observation_space, param_options=config["DEFAULT"], debug=False,
                                 ltc=[9])

    network = Network(sim.substations_elements)
    print("There are {} graphical nodes ".format(network.get_graphical_number_of_nodes()))
    assert (network.get_graphical_number_of_nodes() == 15)

Something like that. This one fails currently as it returns 14 nodes

marota commented 4 years ago

@NMegel @mjothy

marota commented 4 years ago

It is not useful that g_over displays 2 node at a given substation (if this substation was initially at 2 nodes) because it does not change the process of the expert system then (given that the backend simulation to compute the graph edges is indeed computed with the current topology with 2 nodes at the relevant substation)