From dcf61303a64057529e948cda8caceb6e8c883e82 Mon Sep 17 00:00:00 2001 From: ahalev Date: Sun, 23 Apr 2023 15:55:07 -0700 Subject: [PATCH 01/12] make get action public --- src/pymgrid/algos/rbc/rbc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pymgrid/algos/rbc/rbc.py b/src/pymgrid/algos/rbc/rbc.py index bb916d8b..62dff671 100644 --- a/src/pymgrid/algos/rbc/rbc.py +++ b/src/pymgrid/algos/rbc/rbc.py @@ -43,7 +43,7 @@ def _get_priority_list(self, priority_list, remove_redundant_gensets): return priority_list - def _get_action(self): + def get_action(self): """ Given the priority list, define an action. """ @@ -82,7 +82,7 @@ def run(self, max_steps=None, verbose=False): self.reset() for _ in tqdm(range(self._get_num_iter(max_steps)), desc="RBC Progress", disable=(not verbose)): - action = self._get_action() + action = self.get_action() _, _, done, _ = self._microgrid.run(action, normalized=False) if done: break From a14168af341ef13e68ea3b0809f518e923d72d9a Mon Sep 17 00:00:00 2001 From: ahalev Date: Sun, 23 Apr 2023 15:55:41 -0700 Subject: [PATCH 02/12] move get_action down --- src/pymgrid/algos/rbc/rbc.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pymgrid/algos/rbc/rbc.py b/src/pymgrid/algos/rbc/rbc.py index 62dff671..6d0c40d4 100644 --- a/src/pymgrid/algos/rbc/rbc.py +++ b/src/pymgrid/algos/rbc/rbc.py @@ -43,12 +43,6 @@ def _get_priority_list(self, priority_list, remove_redundant_gensets): return priority_list - def get_action(self): - """ - Given the priority list, define an action. - """ - return self._populate_action(self._priority_list) - def reset(self): """ Reset the underlying microgrid. @@ -94,6 +88,13 @@ def _get_num_iter(self, max_steps): return max_steps return self.microgrid.final_step - self.microgrid.initial_step + def get_action(self): + """ + Given the priority list, define an action. + """ + return self._populate_action(self._priority_list) + + def get_empty_action(self): """ :meta private: From 4260da3dfcac8df1d124fae8fc2d8fdbe56964b5 Mon Sep 17 00:00:00 2001 From: ahalev Date: Sun, 23 Apr 2023 15:55:53 -0700 Subject: [PATCH 03/12] whitespace --- src/pymgrid/algos/rbc/rbc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pymgrid/algos/rbc/rbc.py b/src/pymgrid/algos/rbc/rbc.py index 6d0c40d4..57731650 100644 --- a/src/pymgrid/algos/rbc/rbc.py +++ b/src/pymgrid/algos/rbc/rbc.py @@ -94,7 +94,6 @@ def get_action(self): """ return self._populate_action(self._priority_list) - def get_empty_action(self): """ :meta private: From 38e92c0c8c69c2b05b451a6efaa7f92a8b02929b Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 15:54:29 -0700 Subject: [PATCH 04/12] make microgrid public attr --- src/pymgrid/algos/rbc/rbc.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/pymgrid/algos/rbc/rbc.py b/src/pymgrid/algos/rbc/rbc.py index 57731650..ca73faa0 100644 --- a/src/pymgrid/algos/rbc/rbc.py +++ b/src/pymgrid/algos/rbc/rbc.py @@ -1,6 +1,7 @@ from copy import deepcopy from tqdm import tqdm +from pymgrid import Microgrid from pymgrid.algos.priority_list import PriorityListAlgo @@ -23,9 +24,13 @@ class RuleBasedControl(PriorityListAlgo): cost to the highest. """ + + microgrid : Microgrid + 'Microgrid on which to run rule-based control.' + def __init__(self, microgrid, priority_list=None, remove_redundant_gensets=True): super().__init__() - self._microgrid = microgrid + self.microgrid = microgrid self._priority_list = self._get_priority_list(priority_list, remove_redundant_gensets) def _get_priority_list(self, priority_list, remove_redundant_gensets): @@ -77,11 +82,11 @@ def run(self, max_steps=None, verbose=False): for _ in tqdm(range(self._get_num_iter(max_steps)), desc="RBC Progress", disable=(not verbose)): action = self.get_action() - _, _, done, _ = self._microgrid.run(action, normalized=False) + _, _, done, _ = self.microgrid.run(action, normalized=False) if done: break - return self._microgrid.get_log(as_frame=True) + return self.microgrid.get_log(as_frame=True) def _get_num_iter(self, max_steps): if max_steps is not None: @@ -98,35 +103,22 @@ def get_empty_action(self): """ :meta private: """ - return self._microgrid.get_empty_action() - - @property - def microgrid(self): - """ - View of the microgrid. - - Returns - ------- - microgrid : :class:`pymgrid.Microgrid` - The microgrid that RBC is being run on. - - """ - return self._microgrid + return self.microgrid.get_empty_action() @property def fixed(self): """:meta private:""" - return self._microgrid.fixed + return self.microgrid.fixed @property def flex(self): """:meta private:""" - return self._microgrid.flex + return self.microgrid.flex @property def modules(self): """:meta private:""" - return self._microgrid.modules + return self.microgrid.modules @property def priority_list(self): From 78ab80da151aaf8150d5d9e142fe81eb0a689e2a Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:06:49 -0700 Subject: [PATCH 05/12] do not reset microgrid in rbc.reset if already reset --- src/pymgrid/algos/rbc/rbc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pymgrid/algos/rbc/rbc.py b/src/pymgrid/algos/rbc/rbc.py index ca73faa0..c49bbf9c 100644 --- a/src/pymgrid/algos/rbc/rbc.py +++ b/src/pymgrid/algos/rbc/rbc.py @@ -52,13 +52,16 @@ def reset(self): """ Reset the underlying microgrid. + If already reset (e.g. current step is initial step), do nothing. + Returns ------- obs : dict[str, list[float]] Observations from resetting the modules as well as the flushed balance log. """ - return self._microgrid.reset() + if self.microgrid.current_step != self.microgrid.initial_step: + self.microgrid.reset() def run(self, max_steps=None, verbose=False): """ From e76394c0d519d2f1114953c7d077b193d1a5931c Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:07:15 -0700 Subject: [PATCH 06/12] custom flatten obs --- src/pymgrid/envs/base/base.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pymgrid/envs/base/base.py b/src/pymgrid/envs/base/base.py index 72104a99..9285eb89 100644 --- a/src/pymgrid/envs/base/base.py +++ b/src/pymgrid/envs/base/base.py @@ -1,3 +1,4 @@ +import numpy as np import pandas as pd from gym import Env @@ -251,7 +252,7 @@ def _get_obs(self, obs): obs = obs.to_frame().unstack(level=1).T.droplevel(level=1, axis=1).to_dict(orient='list') elif self._flat_spaces: - obs = flatten(self._nested_observation_space, obs) + obs = self.flatten_obs(obs) return obs @@ -268,6 +269,10 @@ def render(self, mode="human"): """:meta private:""" raise RuntimeError('rendering is not possible in Microgrid environments.') + @staticmethod + def flatten_obs(obs): + return np.hstack(list(obs.values())).squeeze() + @property def unwrapped(self): """:meta private:""" From 07394955af0f5a329b560000b56211cda3eef1eb Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:07:36 -0700 Subject: [PATCH 07/12] pop keys we don't want in env.reset --- src/pymgrid/envs/base/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pymgrid/envs/base/base.py b/src/pymgrid/envs/base/base.py index 9285eb89..a56df9f8 100644 --- a/src/pymgrid/envs/base/base.py +++ b/src/pymgrid/envs/base/base.py @@ -178,6 +178,8 @@ def potential_observation_keys(self): def reset(self): obs = super().reset() + obs.pop('balance') + obs.pop('other') self.reset_callback() return self._get_obs(obs) From 55a43f9b55a57330f8f2e7e2acbebef9785d848a Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:08:58 -0700 Subject: [PATCH 08/12] better convert_action --- src/pymgrid/envs/base/base.py | 2 +- src/pymgrid/envs/continuous/continuous.py | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/pymgrid/envs/base/base.py b/src/pymgrid/envs/base/base.py index a56df9f8..f6455816 100644 --- a/src/pymgrid/envs/base/base.py +++ b/src/pymgrid/envs/base/base.py @@ -194,7 +194,7 @@ def step(self, action, normalized=True): Parameters ---------- - action : dict[str, list[float]] + action : int or np.ndarray An action provided by the agent. normalized : bool, default True diff --git a/src/pymgrid/envs/continuous/continuous.py b/src/pymgrid/envs/continuous/continuous.py index c7889f5d..8fc9b1d4 100644 --- a/src/pymgrid/envs/continuous/continuous.py +++ b/src/pymgrid/envs/continuous/continuous.py @@ -14,6 +14,18 @@ def _get_action_space(self, remove_redundant_actions=False): self._nested_action_space = self._get_nested_action_space() return flatten_space(self._nested_action_space) if self._flat_spaces else self._nested_action_space - def convert_action(self, action): - return unflatten(self._nested_action_space, action) + def convert_action(self, action, to_microgrid=True, normalize=False): + if to_microgrid: + converted = unflatten(self._nested_action_space, action) + if normalize: + converted = self.microgrid_action_space.normalize(converted) + + return converted + + if normalize: + action = self.microgrid_action_space.normalize(action) + + assert action in self._nested_action_space + + return flatten(self._nested_action_space, action) From 6f45e9a635efa5f88928b72a95d1d36a85d20695 Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:14:53 -0700 Subject: [PATCH 09/12] add necessary import --- src/pymgrid/envs/continuous/continuous.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pymgrid/envs/continuous/continuous.py b/src/pymgrid/envs/continuous/continuous.py index 8fc9b1d4..2c9f1770 100644 --- a/src/pymgrid/envs/continuous/continuous.py +++ b/src/pymgrid/envs/continuous/continuous.py @@ -1,4 +1,4 @@ -from gym.spaces import Dict, Tuple, flatten_space, unflatten +from gym.spaces import Dict, Tuple, flatten_space, flatten, unflatten from pymgrid.envs.base import BaseMicrogridEnv From 70769c19bb9f2ec1f93fea9510ff4cc4d8977d10 Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 16:15:39 -0700 Subject: [PATCH 10/12] add as_run_output to state dict for comparison purposes --- src/pymgrid/microgrid/microgrid.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/pymgrid/microgrid/microgrid.py b/src/pymgrid/microgrid/microgrid.py index 3b45b091..1dac7c0b 100644 --- a/src/pymgrid/microgrid/microgrid.py +++ b/src/pymgrid/microgrid/microgrid.py @@ -714,7 +714,7 @@ def modules(self): """ return self._modules - def state_dict(self, normalized=False): + def state_dict(self, normalized=False, as_run_output=False): """ State of the microgrid as a dict. @@ -725,14 +725,24 @@ def state_dict(self, normalized=False): normalized : bool, default False Whether to return a dict of normalized values. + as_run_output : bool, default False + Whether to return output in the same format as the output of :meth:`Microgrid.run`. + Inner values are numpy arrays and not dict in this case. + + Returns ------- - state_dict : dict[str, list[dict]] + state_dict : dict[str, list[dict]] or dict[str[list[np.ndarray]]] State of the microgrid as a nested dict. """ + def as_run_output_f(state_dict): + if as_run_output: + return np.array(list(state_dict.values())) + return state_dict + return {name: [ - module.state_dict(normalized=normalized) for module in modules + as_run_output_f(module.state_dict(normalized=normalized)) for module in modules ] for name, modules in self._modules.iterdict()} @property From 3c39e780b93747dc7863cf91e5e2bad869f292d4 Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 17:01:07 -0700 Subject: [PATCH 11/12] fix flatten_obs --- src/pymgrid/envs/base/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pymgrid/envs/base/base.py b/src/pymgrid/envs/base/base.py index f6455816..e7884a32 100644 --- a/src/pymgrid/envs/base/base.py +++ b/src/pymgrid/envs/base/base.py @@ -254,7 +254,7 @@ def _get_obs(self, obs): obs = obs.to_frame().unstack(level=1).T.droplevel(level=1, axis=1).to_dict(orient='list') elif self._flat_spaces: - obs = self.flatten_obs(obs) + obs = self.flatten_obs(self._nested_observation_space, obs) return obs @@ -272,8 +272,8 @@ def render(self, mode="human"): raise RuntimeError('rendering is not possible in Microgrid environments.') @staticmethod - def flatten_obs(obs): - return np.hstack(list(obs.values())).squeeze() + def flatten_obs(observation_space, obs): + return np.concatenate([flatten(observation_space[k], v) for k, v in obs.items()]) @property def unwrapped(self): From d871c24a885296bcbedcbb636f4f0be8392f08e8 Mon Sep 17 00:00:00 2001 From: ahalev Date: Tue, 25 Apr 2023 17:41:08 -0700 Subject: [PATCH 12/12] bug fix with log and initial_step != module initial_step --- src/pymgrid/microgrid/microgrid.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pymgrid/microgrid/microgrid.py b/src/pymgrid/microgrid/microgrid.py index 1dac7c0b..b4ca42e8 100644 --- a/src/pymgrid/microgrid/microgrid.py +++ b/src/pymgrid/microgrid/microgrid.py @@ -482,7 +482,8 @@ def get_log(self, as_frame=True, drop_singleton_key=False, drop_forecasts=False) col_names = ['module_name', 'module_number', 'field'] - df = pd.DataFrame(_log_dict, index=pd.RangeIndex(start=self.initial_step, stop=self.current_step)) + initial_step = self._modules.get_attrs('initial_step', unique=True).item() + df = pd.DataFrame(_log_dict, index=pd.RangeIndex(start=initial_step, stop=self.current_step)) df.columns = pd.MultiIndex.from_tuples(df.columns.to_list(), names=col_names) if drop_forecasts: