Source code for grid2op.Opponent.fromEpisodeDataOpponent

# Copyright (c) 2019-2023, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems.

import copy
import warnings

from grid2op.Opponent.baseOpponent import BaseOpponent
from grid2op.Chronics import FromOneEpisodeData, FromMultiEpisodeData
from grid2op.Exceptions import OpponentError


[docs]class FromEpisodeDataOpponent(BaseOpponent): """ .. warning:: This can only be used if your environment uses :class:`grid2op.Chronics.FromOneEpisodeData` or XXX (from a list of episode data or directory) class otherwise it will NOT work. .. versionadded:: 1.9.4 .. seealso:: :class:`grid2op.Chronics.FromOneEpisodeData` Examples -------- Provided that you stored some data in `path_agent` using a :class:`grid2op.Runner.Runner` for example you can use this class with: .. code-block:: python import grid2op from grid2op.Chronics import FromOneEpisodeData from grid2op.Opponent import FromEpisodeDataOpponent from grid2op.Episode import EpisodeData path_agent = .... # same as above env_name = .... # same as above # path_agent is the path where data coming from a grid2op runner are stored # NB it should come from a do nothing agent, or at least # an agent that does not modify the injections (no redispatching, curtailment, storage) li_episode = EpisodeData.list_episode(path_agent) ep_data = li_episode[0] env = grid2op.make(env_name, chronics_class=FromOneEpisodeData, # super important data_feeding_kwargs={"ep_data": ep_data}, # super important opponent_class=FromEpisodeDataOpponent, # important opponent_attack_cooldown=1, # super important ) # ep_data can be either a tuple of 2 elements (like above) # or a full path to a saved episode # or directly an object of type EpisodeData obs = env.reset() # and now you can use "env" as any grid2op environment. Parameters ---------- BaseOpponent : _type_ _description_ """ def __init__(self, action_space): BaseOpponent.__init__(self, action_space) self._attacks = [] self._ptr_env = None self._warning_cooldown_issued = False
[docs] def init(self, partial_env, **kwargs): if not isinstance(partial_env.chronics_handler.real_data, (FromOneEpisodeData, FromMultiEpisodeData)): raise OpponentError("FromEpisodeDataOpponent can only be used with FromOneEpisodeData time series !") self._ptr_env = partial_env self._attacks = copy.deepcopy(self._ptr_env.chronics_handler.real_data._episode_data.attacks)
[docs] def reset(self, initial_budget): self._attacks = copy.deepcopy(self._ptr_env.chronics_handler.real_data._episode_data.attacks) if self._ptr_env._oppSpace.attack_cooldown > 1: if not self._warning_cooldown_issued: self._warning_cooldown_issued = True warnings.warn('When using FromEpisodeDataOpponent, make sure that your ' 'environment is made with kwargs `opponent_attack_cooldown=1` for ' 'this class to work properly.')
[docs] def attack(self, observation, agent_action, env_action, budget, previous_fails): step = observation.current_step attack = None time = None tmp = self._attacks[step] if tmp is not None and tmp.can_affect_something(): # there as been an attack at this step attack = tmp time = 1 return attack, time
[docs] def tell_attack_continues(self, observation, agent_action, env_action, budget): pass
[docs] def get_state(self): return (self._ptr_env, copy.deepcopy(self._attacks))
[docs] def set_state(self, state): self._ptr_env = state[0] self._attacks = state[1]