def init_backend(self, init_grid_path, chronics_handler, backend, names_chronics_to_backend, actionClass, observationClass, rewardClass, legalActClass): if not isinstance(rewardClass, type): raise Grid2OpException( "Parameter \"rewardClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(rewardClass))) if not issubclass(rewardClass, Reward): raise Grid2OpException( "Parameter \"rewardClass\" used to build the Environment should derived form the grid2op.Reward class, " "type provided is \"{}\"".format(type(rewardClass))) self.rewardClass = rewardClass self.actionClass = actionClass self.observationClass = observationClass # backend self.init_grid_path = os.path.abspath(init_grid_path) if not isinstance(backend, Backend): raise Grid2OpException( "Parameter \"backend\" used to build the Environment should derived form the grid2op.Backend class, " "type provided is \"{}\"".format(type(backend))) self.backend = backend self.backend.load_grid( self.init_grid_path) # the real powergrid of the environment self.backend.load_redispacthing_data( os.path.split(self.init_grid_path)[0]) self.backend.assert_grid_correct() self.init_grid(backend) self._has_been_initialized() if self._thermal_limit_a is None: self._thermal_limit_a = self.backend.thermal_limit_a else: self.backend.set_thermal_limit(self._thermal_limit_a) *_, tmp = self.backend.generators_info() # rules of the game if not isinstance(legalActClass, type): raise Grid2OpException( "Parameter \"legalActClass\" used to build the Environment should be a type " "(a class) and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(legalActClass, LegalAction): raise Grid2OpException( "Parameter \"legalActClass\" used to build the Environment should derived form the " "grid2op.LegalAction class, type provided is \"{}\"".format( type(legalActClass))) self.game_rules = GameRules(legalActClass=legalActClass) self.legalActClass = legalActClass # action helper if not isinstance(actionClass, type): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(actionClass, Action): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should derived form the " "grid2op.Action class, type provided is \"{}\"".format( type(actionClass))) if not isinstance(observationClass, type): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(observationClass, Observation): raise Grid2OpException( "Parameter \"observationClass\" used to build the Environment should derived form the " "grid2op.Observation class, type provided is \"{}\"".format( type(observationClass))) # action affecting the grid that will be made by the agent self.helper_action_player = HelperAction( gridobj=self.backend, actionClass=actionClass, legal_action=self.game_rules.legal_action) # action that affect the grid made by the environment. self.helper_action_env = HelperAction( gridobj=self.backend, actionClass=Action, legal_action=self.game_rules.legal_action) self.helper_observation = ObservationHelper( gridobj=self.backend, observationClass=observationClass, rewardClass=rewardClass, env=self) # handles input data if not isinstance(chronics_handler, ChronicsHandler): raise Grid2OpException( "Parameter \"chronics_handler\" used to build the Environment should derived form the " "grid2op.ChronicsHandler class, type provided is \"{}\"". format(type(chronics_handler))) self.chronics_handler = chronics_handler self.chronics_handler.initialize( self.name_load, self.name_gen, self.name_line, self.name_sub, names_chronics_to_backend=names_chronics_to_backend) self.names_chronics_to_backend = names_chronics_to_backend # test to make sure the backend is consistent with the chronics generator self.chronics_handler.check_validity(self.backend) # reward function self.reward_helper = RewardHelper(rewardClass=rewardClass) self.reward_helper.initialize(self) # controler for voltage if not issubclass(self.voltagecontrolerClass, ControlVoltageFromFile): raise Grid2OpException( "Parameter \"voltagecontrolClass\" should derive from \"ControlVoltageFromFile\"." ) self.voltage_controler = self.voltagecontrolerClass( gridobj=self.backend, controler_backend=self.backend) # performs one step to load the environment properly (first action need to be taken at first time step after # first injections given) self._reset_maintenance() do_nothing = self.helper_action_env({}) *_, fail_to_start, _ = self.step(do_nothing) if fail_to_start: raise Grid2OpException( "Impossible to initialize the powergrid, the powerflow diverge at iteration 0." ) # test the backend returns object of the proper size self.backend.assert_grid_correct_after_powerflow() # for gym compatibility self.action_space = self.helper_action_player # this should be an action !!! self.observation_space = self.helper_observation # this return an observation. self.reward_range = self.reward_helper.range() self.viewer = None self.metadata = {'render.modes': ["human", "rgb_array"]} self.spec = None self.current_reward = self.reward_range[0] self.done = False self._reset_vectors_and_timings()
def __init__(self, init_grid_path: str, chronics_handler, backend, parameters, names_chronics_to_backend=None, actionClass=TopologyAction, observationClass=CompleteObservation, rewardClass=FlatReward, legalActClass=AllwaysLegal): """ Initialize the environment. See the descirption of :class:`grid2op.Environment.Environment` for more information. Parameters ---------- init_grid_path: ``str`` Used to initailize :attr:`Environment.init_grid_path` chronics_handler backend parameters names_chronics_to_backend actionClass observationClass rewardClass legalActClass """ # TODO documentation!! # some timers self._time_apply_act = 0 self._time_powerflow = 0 self._time_extract_obs = 0 # define logger self.logger = None # and calendar data self.time_stamp = None self.nb_time_step = 0 # specific to power system if not isinstance(parameters, Parameters): raise Grid2OpException( "Parameter \"parameters\" used to build the Environment should derived form the " "grid2op.Parameters class, type provided is \"{}\"".format( type(parameters))) self.parameters = parameters if not isinstance(rewardClass, type): raise Grid2OpException( "Parameter \"rewardClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(rewardClass))) if not issubclass(rewardClass, Reward): raise Grid2OpException( "Parameter \"rewardClass\" used to build the Environment should derived form the grid2op.Reward class, " "type provided is \"{}\"".format(type(rewardClass))) self.rewardClass = rewardClass # backend self.init_grid_path = os.path.abspath(init_grid_path) if not isinstance(backend, Backend): raise Grid2OpException( "Parameter \"backend\" used to build the Environment should derived form the grid2op.Backend class, " "type provided is \"{}\"".format(type(backend))) self.backend = backend self.backend.load_grid( self.init_grid_path) # the real powergrid of the environment self.backend.assert_grid_correct() *_, tmp = self.backend.generators_info() # rules of the game if not isinstance(legalActClass, type): raise Grid2OpException( "Parameter \"legalActClass\" used to build the Environment should be a type " "(a class) and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(legalActClass, LegalAction): raise Grid2OpException( "Parameter \"legalActClass\" used to build the Environment should derived form the " "grid2op.LegalAction class, type provided is \"{}\"".format( type(legalActClass))) self.game_rules = GameRules(legalActClass=legalActClass) # action helper if not isinstance(actionClass, type): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(actionClass, Action): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should derived form the " "grid2op.Action class, type provided is \"{}\"".format( type(actionClass))) if not isinstance(observationClass, type): raise Grid2OpException( "Parameter \"actionClass\" used to build the Environment should be a type (a class) " "and not an object (an instance of a class). " "It is currently \"{}\"".format(type(legalActClass))) if not issubclass(observationClass, Observation): raise Grid2OpException( "Parameter \"observationClass\" used to build the Environment should derived form the " "grid2op.Observation class, type provided is \"{}\"".format( type(observationClass))) # action affecting the _grid that will be made by the agent self.helper_action_player = HelperAction(gridobj=self.backend, actionClass=actionClass, game_rules=self.game_rules) # action that affect the _grid made by the environment. self.helper_action_env = HelperAction(gridobj=self.backend, actionClass=Action, game_rules=self.game_rules) self.helper_observation = ObservationHelper( gridobj=self.backend, observationClass=observationClass, rewardClass=rewardClass, env=self) # observation self.current_obs = None # type of power flow to play # if True, then it will not disconnect lines above their thermal limits self.no_overflow_disconnection = self.parameters.NO_OVERFLOW_DISCONNECTION self.timestep_overflow = np.zeros(shape=(self.backend.n_line, ), dtype=np.int) self.nb_timestep_overflow_allowed = np.full( shape=(self.backend.n_line, ), fill_value=self.parameters.NB_TIMESTEP_POWERFLOW_ALLOWED) # store actions "cooldown" self.times_before_line_status_actionable = np.zeros( shape=(self.backend.n_line, ), dtype=np.int) self.max_timestep_line_status_deactivated = self.parameters.NB_TIMESTEP_LINE_STATUS_REMODIF self.times_before_topology_actionable = np.zeros( shape=(self.backend.n_sub, ), dtype=np.int) self.max_timestep_topology_deactivated = self.parameters.NB_TIMESTEP_TOPOLOGY_REMODIF # for maintenance operation self.time_next_maintenance = np.zeros(shape=(self.backend.n_line, ), dtype=np.int) - 1 self.duration_next_maintenance = np.zeros( shape=(self.backend.n_line, ), dtype=np.int) # hazard (not used outside of this class, information is given in `time_remaining_before_line_reconnection` self._hazard_duration = np.zeros(shape=(self.backend.n_line, ), dtype=np.int) # hard overflow part self.hard_overflow_threshold = self.parameters.HARD_OVERFLOW_THRESHOLD self.time_remaining_before_line_reconnection = np.full( shape=(self.backend.n_line, ), fill_value=0, dtype=np.int) self.env_dc = self.parameters.ENV_DC # handles input data if not isinstance(chronics_handler, ChronicsHandler): raise Grid2OpException( "Parameter \"chronics_handler\" used to build the Environment should derived form the " "grid2op.ChronicsHandler class, type provided is \"{}\"". format(type(chronics_handler))) self.chronics_handler = chronics_handler self.chronics_handler.initialize( self.backend.name_load, self.backend.name_gen, self.backend.name_line, self.backend.name_sub, names_chronics_to_backend=names_chronics_to_backend) self.names_chronics_to_backend = names_chronics_to_backend # test to make sure the backend is consistent with the chronics generator self.chronics_handler.check_validity(self.backend) # store environment modifications self._injection = None self._maintenance = None self._hazards = None self.env_modification = None # reward self.reward_helper = RewardHelper(rewardClass=rewardClass) self.reward_helper.initialize(self) # performs one step to load the environment properly (first action need to be taken at first time step after # first injections given) self._reset_maintenance() do_nothing = self.helper_action_env({}) *_, fail_to_start, _ = self.step(do_nothing) if fail_to_start: raise Grid2OpException( "Impossible to initialize the powergrid, the powerflow diverge at iteration 0." ) # test the backend returns object of the proper size self.backend.assert_grid_correct_after_powerflow() # for gym compatibility self.action_space = self.helper_action_player # this should be an action !!! self.observation_space = self.helper_observation # this return an observation. self.reward_range = self.reward_helper.range() self.viewer = None self.metadata = {'render.modes': []} self.spec = None self._reset_vectors_and_timings()