docstr: :param level: (str)
      A string representing the gym level to run. This can also be a LevelSelection object.
      For example, BreakoutDeterministic-v0
  
  :param frame_skip: (int)
      The number of frames to skip between any two actions given by the agent. The action will be repeated
      for all the skipped frames.
  
  :param visualization_parameters: (VisualizationParameters)
      The parameters used for visualizing the environment, such as the render flag, storing videos etc.
  
  :param additional_simulator_parameters: (Dict[str, Any])
      Any additional parameters that the user can pass to the Gym environment. These parameters should be
      accepted by the __init__ function of the implemented Gym environment.
  
  :param seed: (int)
      A seed to use for the random number generator when running the environment.
  
  :param human_control: (bool)
      A flag that allows controlling the environment using the keyboard keys.
  
  :param custom_reward_threshold: (float)
      Allows defining a custom reward that will be used to decide when the agent succeeded in passing the environment.
      If not set, this value will be taken from the Gym environment definition.
  
  :param random_initialization_steps: (int)
      The number of random steps that will be taken in the environment after each reset.
      This is a feature presented in the DQN paper, which improves the variability of the episodes the agent sees.
  
  :param max_over_num_frames: (int)
      This value will be used for merging multiple frames into a single frame by taking the maximum value for each
      of the pixels in the frame. This is particularly used in Atari games, where the frames flicker, and objects
      can be seen in one frame but disappear in the next.
  
  :param observation_space_type:
      This value will be used for generating observation space. Allows a custom space. Should be one of
      ObservationSpaceType. If not specified, observation space is inferred from the number of dimensions
      of the observation: 1D: Vector space, 3D: Image space if 1 or 3 channels, PlanarMaps space otherwise.
docstr_tok: [":","param","level",":","(","str",")","A","string","representing","the","gym","level","to","run",".","This","can","also","be","a","LevelSelection","object",".","For","example",",","BreakoutDeterministic-v0",":","param","frame_skip",":","(","int",")","The","number","of","frames","to","skip","between","any","two","actions","given","by","the","agent",".","The","action","will","be","repeated","for","all","the","skipped","frames",".",":","param","visualization_parameters",":","(","VisualizationParameters",")","The","parameters","used","for","visualizing","the","environment",",","such","as","the","render","flag",",","storing","videos","etc",".",":","param","additional_simulator_parameters",":","(","Dict","[","str",",","Any","]",")","Any","additional","parameters","that","the","user","can","pass","to","the","Gym","environment",".","These","parameters","should","be","accepted","by","the","__init__","function","of","the","implemented","Gym","environment",".",":","param","seed",":","(","int",")","A","seed","to","use","for","the","random","number","generator","when","running","the","environment",".",":","param","human_control",":","(","bool",")","A","flag","that","allows","controlling","the","environment","using","the","keyboard","keys",".",":","param","custom_reward_threshold",":","(","float",")","Allows","defining","a","custom","reward","that","will","be","used","to","decide","when","the","agent","succeeded","in","passing","the","environment",".","If","not","set",",","this","value","will","be","taken","from","the","Gym","environment","definition",".",":","param","random_initialization_steps",":","(","int",")","The","number","of","random","steps","that","will","be","taken","in","the","environment","after","each","reset",".","This","is","a","feature","presented","in","the","DQN","paper",",","which","improves","the","variability","of","the","episodes","the","agent","sees",".",":","param","max_over_num_frames",":","(","int",")","This","value","will","be","used","for","merging","multiple","frames","into","a","single","frame","by","taking","the","maximum","value","for","each","of","the","pixels","in","the","frame",".","This","is","particularly","used","in","Atari","games",",","where","the","frames","flicker",",","and","objects","can","be","seen","in","one","frame","but","disappear","in","the","next",".",":","param","observation_space_type",":","This","value","will","be","used","for","generating","observation","space",".","Allows","a","custom","space",".","Should","be","one","of","ObservationSpaceType",".","If","not","specified",",","observation","space","is","inferred","from","the","number","of","dimensions","of","the","observation",":","1D",":","Vector","space",",","3D",":","Image","space","if","1","or","3","channels",",","PlanarMaps","space","otherwise","."]
code: def __init__(
      self,
      level: LevelSelection,
      frame_skip: int,
      visualization_parameters: VisualizationParameters,
      target_success_rate: float = 1.0,
      additional_simulator_parameters: Dict[str, Any] = {},
      seed: Union[None, int] = None,
      human_control: bool = False,
      custom_reward_threshold: Union[int, float] = None,
      random_initialization_steps: int = 1,
      max_over_num_frames: int = 1,
      observation_space_type: ObservationSpaceType = None,
      **kwargs,
  ):
      """
      :param level: (str)
          A string representing the gym level to run. This can also be a LevelSelection object.
          For example, BreakoutDeterministic-v0
  
      :param frame_skip: (int)
          The number of frames to skip between any two actions given by the agent. The action will be repeated
          for all the skipped frames.
  
      :param visualization_parameters: (VisualizationParameters)
          The parameters used for visualizing the environment, such as the render flag, storing videos etc.
  
      :param additional_simulator_parameters: (Dict[str, Any])
          Any additional parameters that the user can pass to the Gym environment. These parameters should be
          accepted by the __init__ function of the implemented Gym environment.
  
      :param seed: (int)
          A seed to use for the random number generator when running the environment.
  
      :param human_control: (bool)
          A flag that allows controlling the environment using the keyboard keys.
  
      :param custom_reward_threshold: (float)
          Allows defining a custom reward that will be used to decide when the agent succeeded in passing the environment.
          If not set, this value will be taken from the Gym environment definition.
  
      :param random_initialization_steps: (int)
          The number of random steps that will be taken in the environment after each reset.
          This is a feature presented in the DQN paper, which improves the variability of the episodes the agent sees.
  
      :param max_over_num_frames: (int)
          This value will be used for merging multiple frames into a single frame by taking the maximum value for each
          of the pixels in the frame. This is particularly used in Atari games, where the frames flicker, and objects
          can be seen in one frame but disappear in the next.
  
      :param observation_space_type:
          This value will be used for generating observation space. Allows a custom space. Should be one of
          ObservationSpaceType. If not specified, observation space is inferred from the number of dimensions
          of the observation: 1D: Vector space, 3D: Image space if 1 or 3 channels, PlanarMaps space otherwise.
      """
      super().__init__(
          level,
          seed,
          frame_skip,
          human_control,
          custom_reward_threshold,
          visualization_parameters,
          target_success_rate,
      )
  
      self.random_initialization_steps = random_initialization_steps
      self.max_over_num_frames = max_over_num_frames
      self.additional_simulator_parameters = (
          additional_simulator_parameters
      )
  
      # hide warnings
      gym.logger.set_level(40)
  
      """
          load and initialize environment
          environment ids can be defined in 3 ways:
          1. Native gym environments like BreakoutDeterministic-v0 for example
          2. Custom gym environments written and installed as python packages.
             This environments should have a python module with a class inheriting gym.Env, implementing the
             relevant functions (_reset, _step, _render) and defining the observation and action space
             For example: my_environment_package:MyEnvironmentClass will run an environment defined in the
             MyEnvironmentClass class
          3. Custom gym environments written as an independent module which is not installed.
             This environments should have a python module with a class inheriting gym.Env, implementing the
             relevant functions (_reset, _step, _render) and defining the observation and action space.
             For example: path_to_my_environment.sub_directory.my_module:MyEnvironmentClass will run an
             environment defined in the MyEnvironmentClass class which is located in the module in the relative path
             path_to_my_environment.sub_directory.my_module
          """
      if ":" in self.env_id:
          # custom environments
          if "/" in self.env_id or "." in self.env_id:
              # environment in a an absolute path module written as a unix path or in a relative path module
              # written as a python import path
              env_class = short_dynamic_import(self.env_id)
          else:
              # environment in a python package
              env_class = gym.envs.registration.load(self.env_id)
  
          # instantiate the environment
          try:
              self.env = env_class(
                  **self.additional_simulator_parameters
              )
          except:
              screen.error(
                  "Failed to instantiate Gym environment class %s with arguments %s"
                  % (env_class, self.additional_simulator_parameters),
                  crash=False,
              )
              raise
      else:
          self.env = gym.make(self.env_id)
  
      # for classic control we want to use the native renderer because otherwise we will get 2 renderer windows
      environment_to_always_use_with_native_rendering = [
          "classic_control",
          "mujoco",
          "robotics",
      ]
      self.native_rendering = self.native_rendering or any(
          [
              env in str(self.env.unwrapped.__class__)
              for env in environment_to_always_use_with_native_rendering
          ]
      )
      if self.native_rendering:
          if hasattr(self, "renderer"):
              self.renderer.close()
  
      # seed
      if self.seed is not None:
          self.env.seed(self.seed)
          np.random.seed(self.seed)
          random.seed(self.seed)
  
      # frame skip and max between consecutive frames
      self.is_mujoco_env = "mujoco" in str(self.env.unwrapped.__class__)
      self.is_roboschool_env = "roboschool" in str(
          self.env.unwrapped.__class__
      )
      self.is_atari_env = "Atari" in str(self.env.unwrapped.__class__)
      if self.is_atari_env:
          self.env.unwrapped.frameskip = 1  # this accesses the atari env that is wrapped with a timelimit wrapper env
          if (
              self.env_id == "SpaceInvadersDeterministic-v4"
              and self.frame_skip == 4
          ):
              screen.warning(
                  "Warning: The frame-skip for Space Invaders was automatically updated from 4 to 3. "
                  "This is following the DQN paper where it was noticed that a frame-skip of 3 makes the "
                  "laser rays disappear. To force frame-skip of 4, please use SpaceInvadersNoFrameskip-v4."
              )
              self.frame_skip = 3
          self.env = MaxOverFramesAndFrameskipEnvWrapper(
              self.env,
              frameskip=self.frame_skip,
              max_over_num_frames=self.max_over_num_frames,
          )
      else:
          self.env.unwrapped.frameskip = self.frame_skip
  
      self.state_space = StateSpace({})
  
      # observations
      if not isinstance(
          self.env.observation_space, gym.spaces.dict.Dict
      ):
          state_space = {"observation": self.env.observation_space}
      else:
          state_space = self.env.observation_space.spaces
  
      for (
          observation_space_name,
          observation_space,
      ) in state_space.items():
          if observation_space_type == ObservationSpaceType.Tensor:
              # we consider arbitrary input tensor which does not necessarily represent images
              self.state_space[
                  observation_space_name
              ] = TensorObservationSpace(
                  shape=np.array(observation_space.shape),
                  low=observation_space.low,
                  high=observation_space.high,
              )
          elif (
              observation_space_type == ObservationSpaceType.Image
              or len(observation_space.shape) == 3
          ):
              # we assume gym has image observations (with arbitrary number of channels) where their values are
              # within 0-255, and where the channel dimension is the last dimension
              if observation_space.shape[-1] in [1, 3]:
                  self.state_space[
                      observation_space_name
                  ] = ImageObservationSpace(
                      shape=np.array(observation_space.shape),
                      high=255,
                      channels_axis=-1,
                  )
              else:
                  # For any number of channels other than 1 or 3, use the generic PlanarMaps space
                  self.state_space[
                      observation_space_name
                  ] = PlanarMapsObservationSpace(
                      shape=np.array(observation_space.shape),
                      low=0,
                      high=255,
                      channels_axis=-1,
                  )
          elif (
              observation_space_type == ObservationSpaceType.Vector
              or len(observation_space.shape) == 1
          ):
              self.state_space[
                  observation_space_name
              ] = VectorObservationSpace(
                  shape=observation_space.shape[0],
                  low=observation_space.low,
                  high=observation_space.high,
              )
          else:
              raise screen.error(
                  "Failed to instantiate Gym environment class %s with observation space type %s"
                  % (env_class, observation_space_type),
                  crash=True,
              )
  
      if "desired_goal" in state_space.keys():
          self.goal_space = self.state_space["desired_goal"]
  
      # actions
      if type(self.env.action_space) == gym.spaces.box.Box:
          self.action_space = BoxActionSpace(
              shape=self.env.action_space.shape,
              low=self.env.action_space.low,
              high=self.env.action_space.high,
          )
      elif type(self.env.action_space) == gym.spaces.discrete.Discrete:
          actions_description = []
          if hasattr(self.env.unwrapped, "get_action_meanings"):
              actions_description = (
                  self.env.unwrapped.get_action_meanings()
              )
          self.action_space = DiscreteActionSpace(
              num_actions=self.env.action_space.n,
              descriptions=actions_description,
          )
      else:
          raise screen.error(
              (
                  "Failed to instantiate gym environment class {} due to unsupported "
                  "action space {}. Expected BoxActionSpace or DiscreteActionSpace."
              ).format(env_class, self.env.action_space),
              crash=True,
          )
  
      if self.human_control:
          # TODO: add this to the action space
          # map keyboard keys to actions
          self.key_to_action = {}
          if hasattr(self.env.unwrapped, "get_keys_to_action"):
              self.key_to_action = (
                  self.env.unwrapped.get_keys_to_action()
              )
          else:
              screen.error(
                  "Error: Environment {} does not support human control.".format(
                      self.env
                  ),
                  crash=True,
              )
  
      # render
      if self.is_rendered:
          image = self.get_rendered_image()
          scale = 1
          if self.human_control:
              scale = 2
          if not self.native_rendering:
              self.renderer.create_screen(
                  image.shape[1] * scale, image.shape[0] * scale
              )
  
      # the info is only updated after the first step
      self.state_space["measurements"] = VectorObservationSpace(
          shape=len(self.info.keys())
      )
  
      if self.env.spec and custom_reward_threshold is None:
          self.reward_success_threshold = self.env.spec.reward_threshold
          self.reward_space = RewardSpace(
              1, reward_success_threshold=self.reward_success_threshold
          )
  
      self.target_success_rate = target_success_rate
  
imports: import gym
  import numpy
  from enum import IntEnum
  import scipy.ndimage
  from rl_coach.graph_managers.graph_manager import ScheduleParameters
  from rl_coach.utils import lower_under_to_upper, short_dynamic_import
  from typing import Dict, Any, Union
  from rl_coach.core_types import RunPhase, EnvironmentSteps
  from rl_coach.environments.environment import Environment, EnvironmentParameters, LevelSelection
  from rl_coach.spaces import DiscreteActionSpace, BoxActionSpace, ImageObservationSpace, VectorObservationSpace, PlanarMapsObservationSpace, TensorObservationSpace, StateSpace, RewardSpace
  from rl_coach.filters.filter import NoInputFilter, NoOutputFilter
  from rl_coach.filters.reward.reward_clipping_filter import RewardClippingFilter
  from rl_coach.filters.observation.observation_rescale_to_size_filter import ObservationRescaleToSizeFilter
  from rl_coach.filters.observation.observation_stacking_filter import ObservationStackingFilter
  from rl_coach.filters.observation.observation_rgb_to_y_filter import ObservationRGBToYFilter
  from rl_coach.filters.observation.observation_to_uint8_filter import ObservationToUInt8Filter
  from rl_coach.filters.filter import InputFilter
  import random
  from rl_coach.base_parameters import VisualizationParameters
  from rl_coach.logger import screen
label_desc: Use image node_id 1 to create a new GymEnvironment object from inherited base classes: Environment with example: obj = GymEnvironment(level, frame_skip, visualization_parameters, target_success_rate, additional_simulator_parameters, seed, human_control, custom_reward_threshold, random_initialization_steps, max_over_num_frames, observation_space_type)