From 2eeb896099145167f493825f893598535439f7af Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Tue, 28 Nov 2023 12:16:04 +0000 Subject: [PATCH 1/9] #2085 - Dump describe_state output to JSON file. --- src/primaite/game/game.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 38e9d5fc..4e896987 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -1,4 +1,6 @@ """PrimAITE game - Encapsulates the simulation and agents.""" +import json +from datetime import datetime from ipaddress import IPv4Address from typing import Dict, List @@ -10,6 +12,7 @@ from primaite.game.agent.data_manipulation_bot import DataManipulationAgent from primaite.game.agent.interface import AbstractAgent, AgentSettings, ProxyAgent, RandomAgent from primaite.game.agent.observations import ObservationManager from primaite.game.agent.rewards import RewardFunction +from primaite.session.io import generate_session_path from primaite.simulator.network.hardware.base import NIC, NodeOperatingState from primaite.simulator.network.hardware.nodes.computer import Computer from primaite.simulator.network.hardware.nodes.router import ACLAction, Router @@ -107,6 +110,13 @@ class PrimaiteGame: # Get the current state of the simulation sim_state = self.get_sim_state() + # Create state suitable for dumping to JSON file. + dump_state = {self.episode_counter: {self.step_counter: sim_state}} + json_path = generate_session_path(datetime.now()) / "describe_state.json" + # Dump to file + with open(json_path, "a") as f: + json.dump(dump_state, f) + # Update agents' observations and rewards based on the current state self.update_agents(sim_state) From e63727fa3ad0fcd58e1943abe65f1acd521da158 Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Tue, 28 Nov 2023 14:12:01 +0000 Subject: [PATCH 2/9] #2058 - Fix up log file path --- src/primaite/__init__.py | 5 +++++ src/primaite/game/game.py | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/primaite/__init__.py b/src/primaite/__init__.py index 28245d33..1e5fe925 100644 --- a/src/primaite/__init__.py +++ b/src/primaite/__init__.py @@ -38,6 +38,7 @@ class _PrimaitePaths: self.app_config_file_path = self.generate_app_config_file_path() self.app_log_dir_path = self.generate_app_log_dir_path() self.app_log_file_path = self.generate_app_log_file_path() + self.episode_steps_log_file_path = self.generate_episode_step_log_file_path() def _get_dirs_properties(self) -> List[str]: class_items = self.__class__.__dict__.items() @@ -105,6 +106,10 @@ class _PrimaitePaths: """The PrimAITE app log file path.""" return self.app_log_dir_path / "primaite.log" + def generate_episode_step_log_file_path(self) -> Path: + """The PrimAITE app episode step log file path.""" + return self.app_log_dir_path / "epi_step.json" + def __repr__(self) -> str: properties_str = ", ".join([f"{p}='{getattr(self, p)}'" for p in self._get_dirs_properties()]) return f"{self.__class__.__name__}({properties_str})" diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 4e896987..3409100e 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -1,18 +1,17 @@ """PrimAITE game - Encapsulates the simulation and agents.""" import json -from datetime import datetime +import os from ipaddress import IPv4Address from typing import Dict, List from pydantic import BaseModel, ConfigDict -from primaite import getLogger +from primaite import getLogger, PRIMAITE_PATHS from primaite.game.agent.actions import ActionManager from primaite.game.agent.data_manipulation_bot import DataManipulationAgent from primaite.game.agent.interface import AbstractAgent, AgentSettings, ProxyAgent, RandomAgent from primaite.game.agent.observations import ObservationManager from primaite.game.agent.rewards import RewardFunction -from primaite.session.io import generate_session_path from primaite.simulator.network.hardware.base import NIC, NodeOperatingState from primaite.simulator.network.hardware.nodes.computer import Computer from primaite.simulator.network.hardware.nodes.router import ACLAction, Router @@ -112,10 +111,10 @@ class PrimaiteGame: # Create state suitable for dumping to JSON file. dump_state = {self.episode_counter: {self.step_counter: sim_state}} - json_path = generate_session_path(datetime.now()) / "describe_state.json" # Dump to file - with open(json_path, "a") as f: - json.dump(dump_state, f) + if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): + with open(PRIMAITE_PATHS.episode_steps_log_file_path, "a") as f: + json.dump(dump_state, f) # Update agents' observations and rewards based on the current state self.update_agents(sim_state) From 957702fa5db703b442e820ad19e52a4d3290b3cd Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Wed, 29 Nov 2023 10:10:23 +0000 Subject: [PATCH 3/9] #2085: Remove JSON file handling --- src/primaite/game/game.py | 11 +---------- src/primaite/session/environment.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 3409100e..38e9d5fc 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -1,12 +1,10 @@ """PrimAITE game - Encapsulates the simulation and agents.""" -import json -import os from ipaddress import IPv4Address from typing import Dict, List from pydantic import BaseModel, ConfigDict -from primaite import getLogger, PRIMAITE_PATHS +from primaite import getLogger from primaite.game.agent.actions import ActionManager from primaite.game.agent.data_manipulation_bot import DataManipulationAgent from primaite.game.agent.interface import AbstractAgent, AgentSettings, ProxyAgent, RandomAgent @@ -109,13 +107,6 @@ class PrimaiteGame: # Get the current state of the simulation sim_state = self.get_sim_state() - # Create state suitable for dumping to JSON file. - dump_state = {self.episode_counter: {self.step_counter: sim_state}} - # Dump to file - if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): - with open(PRIMAITE_PATHS.episode_steps_log_file_path, "a") as f: - json.dump(dump_state, f) - # Update agents' observations and rewards based on the current state self.update_agents(sim_state) diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index a5fdade9..913038f9 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -1,9 +1,11 @@ +import os from typing import Any, Dict, Final, Optional, SupportsFloat, Tuple import gymnasium from gymnasium.core import ActType, ObsType from ray.rllib.env.multi_agent_env import MultiAgentEnv +from primaite import PRIMAITE_PATHS from primaite.game.agent.interface import ProxyAgent from primaite.game.game import PrimaiteGame @@ -30,6 +32,17 @@ class PrimaiteGymEnv(gymnasium.Env): self.game.apply_agent_actions() self.game.advance_timestep() state = self.game.get_sim_state() + + # Create state suitable for dumping to file. + dump_state = {self.game.episode_counter: {self.game.step_counter: state}} + + # Dump to file + if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): + with open(PRIMAITE_PATHS.episode_steps_log_file_path, "a", encoding="utf-8") as f: + f.write(str(dump_state)) + f.write("\n=================\n") + f.flush() + self.game.update_agents(state) next_obs = self._get_obs() From 3ab911f6af57bffb6f0ae3019267340dd5f4eeef Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Wed, 29 Nov 2023 11:41:02 +0000 Subject: [PATCH 4/9] #2085: Change output file type --- src/primaite/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primaite/__init__.py b/src/primaite/__init__.py index 1e5fe925..a143b9b9 100644 --- a/src/primaite/__init__.py +++ b/src/primaite/__init__.py @@ -108,7 +108,7 @@ class _PrimaitePaths: def generate_episode_step_log_file_path(self) -> Path: """The PrimAITE app episode step log file path.""" - return self.app_log_dir_path / "epi_step.json" + return self.app_log_dir_path / "epi_step.log" def __repr__(self) -> str: properties_str = ", ".join([f"{p}='{getattr(self, p)}'" for p in self._get_dirs_properties()]) From 5cd69f343f26570f4709da4377e911e8e3b4f100 Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Thu, 30 Nov 2023 16:11:44 +0000 Subject: [PATCH 5/9] #2085: generate time based log files --- src/primaite/__init__.py | 10 +++++++--- src/primaite/session/environment.py | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/primaite/__init__.py b/src/primaite/__init__.py index a143b9b9..c58f0103 100644 --- a/src/primaite/__init__.py +++ b/src/primaite/__init__.py @@ -1,4 +1,5 @@ # © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +import datetime as datetime import logging import logging.config import shutil @@ -38,7 +39,7 @@ class _PrimaitePaths: self.app_config_file_path = self.generate_app_config_file_path() self.app_log_dir_path = self.generate_app_log_dir_path() self.app_log_file_path = self.generate_app_log_file_path() - self.episode_steps_log_file_path = self.generate_episode_step_log_file_path() + self.episode_log_file_path = self.generate_episode_log_file_path() def _get_dirs_properties(self) -> List[str]: class_items = self.__class__.__dict__.items() @@ -106,9 +107,12 @@ class _PrimaitePaths: """The PrimAITE app log file path.""" return self.app_log_dir_path / "primaite.log" - def generate_episode_step_log_file_path(self) -> Path: + def generate_episode_log_file_path(self) -> Path: """The PrimAITE app episode step log file path.""" - return self.app_log_dir_path / "epi_step.log" + date_string = datetime.datetime.now().strftime("%Y-%m-%dT%H-%M-%S") + self.episode_log_dir_path = self.app_log_dir_path / date_string + self.episode_log_dir_path.mkdir(exist_ok=True, parents=True) + return self.episode_log_dir_path / "episode.log" def __repr__(self) -> str: properties_str = ", ".join([f"{p}='{getattr(self, p)}'" for p in self._get_dirs_properties()]) diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index 913038f9..1471e683 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -1,4 +1,4 @@ -import os +# import os from typing import Any, Dict, Final, Optional, SupportsFloat, Tuple import gymnasium @@ -37,11 +37,11 @@ class PrimaiteGymEnv(gymnasium.Env): dump_state = {self.game.episode_counter: {self.game.step_counter: state}} # Dump to file - if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): - with open(PRIMAITE_PATHS.episode_steps_log_file_path, "a", encoding="utf-8") as f: - f.write(str(dump_state)) - f.write("\n=================\n") - f.flush() + # if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): + with open(PRIMAITE_PATHS.episode_log_file_path, "a", encoding="utf-8") as f: + f.write(str(dump_state)) + f.write("\n=================\n") + f.flush() self.game.update_agents(state) From a073038ec09de444b081edce41916c5e740f660d Mon Sep 17 00:00:00 2001 From: Nick Todd Date: Fri, 1 Dec 2023 09:52:31 +0000 Subject: [PATCH 6/9] #2085: Get enum value data --- src/primaite/session/environment.py | 11 ++++++----- src/primaite/simulator/system/services/service.py | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index 1471e683..bb7028d8 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -1,4 +1,4 @@ -# import os +import json from typing import Any, Dict, Final, Optional, SupportsFloat, Tuple import gymnasium @@ -34,14 +34,15 @@ class PrimaiteGymEnv(gymnasium.Env): state = self.game.get_sim_state() # Create state suitable for dumping to file. - dump_state = {self.game.episode_counter: {self.game.step_counter: state}} + # dump_state = {self.game.episode_counter: {self.game.step_counter: state}} # Dump to file # if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): with open(PRIMAITE_PATHS.episode_log_file_path, "a", encoding="utf-8") as f: - f.write(str(dump_state)) - f.write("\n=================\n") - f.flush() + # f.write(str(dump_state)) + # f.write("\n=================\n") + # f.flush() + json.dump(state, f) self.game.update_agents(state) diff --git a/src/primaite/simulator/system/services/service.py b/src/primaite/simulator/system/services/service.py index 6d6cda86..e60b7700 100644 --- a/src/primaite/simulator/system/services/service.py +++ b/src/primaite/simulator/system/services/service.py @@ -109,8 +109,8 @@ class Service(IOSoftware): """ state = super().describe_state() state["operating_state"] = self.operating_state.value - state["health_state_actual"] = self.health_state_actual - state["health_state_visible"] = self.health_state_visible + state["health_state_actual"] = self.health_state_actual.value + state["health_state_visible"] = self.health_state_visible.value return state def stop(self) -> None: From cc04efb31db63f57869c0ce833f30134639f930a Mon Sep 17 00:00:00 2001 From: Chris McCarthy Date: Fri, 1 Dec 2023 16:37:58 +0000 Subject: [PATCH 7/9] #2085 - Added step metadata json file dumps to the environments. Fixed serialization issues in the Switch and ACLRule classes. --- docs/source/primaite_session.rst | 4 +- src/primaite/session/environment.py | 47 ++++++++++++++----- .../network/hardware/nodes/router.py | 4 +- .../network/hardware/nodes/switch.py | 2 +- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/docs/source/primaite_session.rst b/docs/source/primaite_session.rst index f3ef0399..706397b6 100644 --- a/docs/source/primaite_session.rst +++ b/docs/source/primaite_session.rst @@ -31,4 +31,6 @@ Outputs Running a session creates a session output directory in your user data folder. The filepath looks like this: ``~/primaite/3.0.0/sessions/YYYY-MM-DD/HH-MM-SS/``. This folder contains the simulation sys logs generated by each node, -the saved agent checkpoints, and final model. +the saved agent checkpoints, and final model. The folder also contains a .json file for each episode step that +contains the action, reward, and simulation state. These can be found in +``~/primaite/3.0.0/sessions/YYYY-MM-DD/HH-MM-SS/simulation_output/episode_/step_metadata/step_.json`` diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index 3c164878..9c86aee0 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -5,9 +5,9 @@ import gymnasium from gymnasium.core import ActType, ObsType from ray.rllib.env.multi_agent_env import MultiAgentEnv -from primaite import PRIMAITE_PATHS from primaite.game.agent.interface import ProxyAgent from primaite.game.game import PrimaiteGame +from primaite.simulator import SIM_OUTPUT class PrimaiteGymEnv(gymnasium.Env): @@ -33,17 +33,6 @@ class PrimaiteGymEnv(gymnasium.Env): self.game.advance_timestep() state = self.game.get_sim_state() - # Create state suitable for dumping to file. - # dump_state = {self.game.episode_counter: {self.game.step_counter: state}} - - # Dump to file - # if os.path.isfile(PRIMAITE_PATHS.episode_steps_log_file_path): - with open(PRIMAITE_PATHS.episode_log_file_path, "a", encoding="utf-8") as f: - # f.write(str(dump_state)) - # f.write("\n=================\n") - # f.flush() - json.dump(state, f) - self.game.update_agents(state) next_obs = self._get_obs() @@ -51,9 +40,26 @@ class PrimaiteGymEnv(gymnasium.Env): terminated = False truncated = self.game.calculate_truncated() info = {} + self._write_step_metadata_json(action, state, reward) print(f"Episode: {self.game.episode_counter}, Step: {self.game.step_counter}, Reward: {reward}") return next_obs, reward, terminated, truncated, info + def _write_step_metadata_json(self, action: int, state: Dict, reward: int): + output_dir = SIM_OUTPUT.path / f"episode_{self.game.episode_counter}" / "step_metadata" + + output_dir.mkdir(parents=True, exist_ok=True) + path = output_dir / f"step_{self.game.step_counter}.json" + + data = { + "episode": self.game.episode_counter, + "step": self.game.step_counter, + "action": int(action), + "reward": int(reward), + "state": state, + } + with open(path, "w") as file: + json.dump(data, file) + def reset(self, seed: Optional[int] = None) -> Tuple[ObsType, Dict[str, Any]]: """Reset the environment.""" self.game.reset() @@ -173,8 +179,25 @@ class PrimaiteRayMARLEnv(MultiAgentEnv): infos = {} terminateds["__all__"] = len(self.terminateds) == len(self.agents) truncateds["__all__"] = self.game.calculate_truncated() + self._write_step_metadata_json(actions, state, rewards) return next_obs, rewards, terminateds, truncateds, infos + def _write_step_metadata_json(self, actions: Dict, state: Dict, rewards: Dict): + output_dir = SIM_OUTPUT.path / f"episode_{self.game.episode_counter}" / "step_metadata" + + output_dir.mkdir(parents=True, exist_ok=True) + path = output_dir / f"step_{self.game.step_counter}.json" + + data = { + "episode": self.game.episode_counter, + "step": self.game.step_counter, + "actions": {agent_name: int(action) for agent_name, action in actions.items()}, + "reward": rewards, + "state": state, + } + with open(path, "w") as file: + json.dump(data, file) + def _get_obs(self) -> Dict[str, ObsType]: """Return the current observation.""" obs = {} diff --git a/src/primaite/simulator/network/hardware/nodes/router.py b/src/primaite/simulator/network/hardware/nodes/router.py index 0017215a..0234934d 100644 --- a/src/primaite/simulator/network/hardware/nodes/router.py +++ b/src/primaite/simulator/network/hardware/nodes/router.py @@ -66,9 +66,9 @@ class ACLRule(SimComponent): state = super().describe_state() state["action"] = self.action.value state["protocol"] = self.protocol.value if self.protocol else None - state["src_ip_address"] = self.src_ip_address if self.src_ip_address else None + state["src_ip_address"] = str(self.src_ip_address) if self.src_ip_address else None state["src_port"] = self.src_port.value if self.src_port else None - state["dst_ip_address"] = self.dst_ip_address if self.dst_ip_address else None + state["dst_ip_address"] = str(self.dst_ip_address) if self.dst_ip_address else None state["dst_port"] = self.dst_port.value if self.dst_port else None return state diff --git a/src/primaite/simulator/network/hardware/nodes/switch.py b/src/primaite/simulator/network/hardware/nodes/switch.py index fe61509c..92999b88 100644 --- a/src/primaite/simulator/network/hardware/nodes/switch.py +++ b/src/primaite/simulator/network/hardware/nodes/switch.py @@ -57,7 +57,7 @@ class Switch(Node): state = super().describe_state() state["ports"] = {port_num: port.describe_state() for port_num, port in self.switch_ports.items()} state["num_ports"] = self.num_ports # redundant? - state["mac_address_table"] = {mac: port for mac, port in self.mac_address_table.items()} + state["mac_address_table"] = {mac: port.port_num for mac, port in self.mac_address_table.items()} return state def _add_mac_table_entry(self, mac_address: str, switch_port: SwitchPort): From a5c4f7797d34416fb7bec946a59843fdcbc2ba31 Mon Sep 17 00:00:00 2001 From: Marek Wolan Date: Mon, 4 Dec 2023 10:42:20 +0000 Subject: [PATCH 8/9] Make saving step metadata optional --- src/primaite/config/_package_data/example_config.yaml | 1 + .../config/_package_data/example_config_2_rl_agents.yaml | 1 + src/primaite/game/game.py | 9 +++++++++ src/primaite/session/environment.py | 6 ++++-- src/primaite/session/io.py | 2 ++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/primaite/config/_package_data/example_config.yaml b/src/primaite/config/_package_data/example_config.yaml index 7d5b50d6..24f9945d 100644 --- a/src/primaite/config/_package_data/example_config.yaml +++ b/src/primaite/config/_package_data/example_config.yaml @@ -13,6 +13,7 @@ training_config: io_settings: save_checkpoints: true checkpoint_interval: 5 + save_step_metadata: false game: diff --git a/src/primaite/config/_package_data/example_config_2_rl_agents.yaml b/src/primaite/config/_package_data/example_config_2_rl_agents.yaml index b811bfa5..9c2acaae 100644 --- a/src/primaite/config/_package_data/example_config_2_rl_agents.yaml +++ b/src/primaite/config/_package_data/example_config_2_rl_agents.yaml @@ -9,6 +9,7 @@ training_config: io_settings: save_checkpoints: true checkpoint_interval: 5 + save_step_metadata: false game: diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index a36cbea9..8c32f41d 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -10,6 +10,7 @@ from primaite.game.agent.data_manipulation_bot import DataManipulationAgent from primaite.game.agent.interface import AbstractAgent, AgentSettings, ProxyAgent, RandomAgent from primaite.game.agent.observations import ObservationManager from primaite.game.agent.rewards import RewardFunction +from primaite.session.io import SessionIO, SessionIOSettings from primaite.simulator.network.hardware.base import NIC, NodeOperatingState from primaite.simulator.network.hardware.nodes.computer import Computer from primaite.simulator.network.hardware.nodes.router import ACLAction, Router @@ -84,6 +85,9 @@ class PrimaiteGame: self.ref_map_links: Dict[str, str] = {} """Mapping from human-readable link reference to link object. Used when parsing config files.""" + self.save_step_metadata: bool = False + """Whether to save the RL agents' action, environment state, and other data at every single step.""" + def step(self): """ Perform one step of the simulation/agent loop. @@ -180,8 +184,13 @@ class PrimaiteGame: :return: A PrimaiteGame object. :rtype: PrimaiteGame """ + io_settings = cfg.get("io_settings", {}) + _ = SessionIO(SessionIOSettings(**io_settings)) + # Instantiating this ensures that the game saves to the correct output dir even without being part of a session + game = cls() game.options = PrimaiteGameOptions(**cfg["game"]) + game.save_step_metadata = cfg.get("io_settings", {}).get("save_step_metadata") or False # 1. create simulation sim = game.simulation diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index dfee9a2f..3d43e338 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -40,7 +40,8 @@ class PrimaiteGymEnv(gymnasium.Env): terminated = False truncated = self.game.calculate_truncated() info = {} - self._write_step_metadata_json(action, state, reward) + if self.game.save_step_metadata: + self._write_step_metadata_json(action, state, reward) print(f"Episode: {self.game.episode_counter}, Step: {self.game.step_counter}, Reward: {reward}") return next_obs, reward, terminated, truncated, info @@ -183,7 +184,8 @@ class PrimaiteRayMARLEnv(MultiAgentEnv): infos = {} terminateds["__all__"] = len(self.terminateds) == len(self.agents) truncateds["__all__"] = self.game.calculate_truncated() - self._write_step_metadata_json(actions, state, rewards) + if self.game.save_step_metadata: + self._write_step_metadata_json(actions, state, rewards) return next_obs, rewards, terminateds, truncateds, infos def _write_step_metadata_json(self, actions: Dict, state: Dict, rewards: Dict): diff --git a/src/primaite/session/io.py b/src/primaite/session/io.py index e0b849c9..0d80a385 100644 --- a/src/primaite/session/io.py +++ b/src/primaite/session/io.py @@ -25,6 +25,8 @@ class SessionIOSettings(BaseModel): """Whether to save transactions, If true, the session path will have a transactions folder.""" save_tensorboard_logs: bool = False """Whether to save tensorboard logs. If true, the session path will have a tenorboard_logs folder.""" + save_step_metadata: bool = False + """Whether to save the RL agents' action, environment state, and other data at every single step.""" class SessionIO: From 01b9e661ce94c1f959f1f8b866616fdafa496afd Mon Sep 17 00:00:00 2001 From: Marek Wolan Date: Mon, 4 Dec 2023 10:45:33 +0000 Subject: [PATCH 9/9] Clean up print statements. --- src/primaite/session/environment.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/primaite/session/environment.py b/src/primaite/session/environment.py index 3d43e338..ca71a0c0 100644 --- a/src/primaite/session/environment.py +++ b/src/primaite/session/environment.py @@ -42,7 +42,6 @@ class PrimaiteGymEnv(gymnasium.Env): info = {} if self.game.save_step_metadata: self._write_step_metadata_json(action, state, reward) - print(f"Episode: {self.game.episode_counter}, Step: {self.game.step_counter}, Reward: {reward}") return next_obs, reward, terminated, truncated, info def _write_step_metadata_json(self, action: int, state: Dict, reward: int):