update envs: add actions, reward range, and update render/hide/close

This commit is contained in:
Brian Delhaisse
2019-05-06 18:26:13 +02:00
parent 4d5d8451c5
commit 91cd04b196
2 changed files with 69 additions and 18 deletions
+52 -17
View File
@@ -32,7 +32,7 @@ __email__ = "briandelhaisse@gmail.com"
__status__ = "Development"
class Env(object): # gym.Env):
class Env(object): # gym.Env): # TODO: make it inheriting the gym.Env
r"""Environment class.
This class defines the environment as it described in a reinforcement learning setting [1]. That is, given an
@@ -51,11 +51,10 @@ class Env(object): # gym.Env):
[1] "Reinforcement Learning: An Introduction", Sutton and Barto, 1998
[2] "Wikipedia: Composition over Inheritance", https://en.wikipedia.org/wiki/Composition_over_inheritance
[3] "OpenAI gym": https://gym.openai.com/ and https://github.com/openai/gym
"""
def __init__(self, world, states, rewards=None, terminal_conditions=None, initial_state_generators=None,
physics_randomizers=None, extra_info=None):
physics_randomizers=None, extra_info=None, actions=None):
"""
Initialize the environment.
@@ -72,6 +71,9 @@ class Env(object): # gym.Env):
physics_randomizers (None, PhysicsRandomizer, list of PhysicsRandomizer): physics randomizers. This will be
called each time you reset the environment.
extra_info (None, callable): Extra info returned by the environment at each time step.
actions (Action): actions that are given to the environment. Note that this is not used here in the current
environment as it should be the policy that performs the action. This is useful when creating policies
after the environment (that is, the policy can uses the environment's states and actions).
"""
# Check and set parameters (see corresponding properties)
self.world = world
@@ -81,6 +83,7 @@ class Env(object): # gym.Env):
self.physics_randomizers = physics_randomizers
self.state_generators = initial_state_generators
self.extra_info = extra_info if extra_info is not None else lambda: False
self.actions = actions
self.rendering = False # check with simulator
@@ -115,20 +118,54 @@ class Env(object): # gym.Env):
return self._states
@states.setter
def states(self, states): # TODO: make it a list of states
def states(self, states):
"""Set the states."""
if isinstance(states, State):
states = [states]
elif isinstance(states, (list, tuple)):
for idx, state in enumerate(states):
if not isinstance(state, State):
raise TypeError("The {} item is not an instance of `State`, but instead: "
raise TypeError("The {}th item is not an instance of `State`, but instead: "
"{}".format(idx, type(state)))
else:
raise TypeError("Expecting the 'states' argument to be an instance of `State` or a list of `State`, "
"instead got: {}".format(type(states)))
self._states = states
@property
def state(self):
"""Return the first (combined) state."""
return self._states[0]
@property
def actions(self):
"""Return the actions."""
return self._actions
@actions.setter
def actions(self, actions):
"""Set the actions."""
if actions is not None:
# if actions is not a list/tuple, make it a list
if not isinstance(actions, (list, tuple)):
actions = [actions]
# verify the type of each action
for idx, action in enumerate(actions):
if not isinstance(action, Action):
raise TypeError("The {}th item in 'actions' is not an instance of `Action`, instead got: "
"{}".format(idx, type(action)))
# set the actions
self._actions = actions
@property
def action(self):
"""Return the first (combined) action."""
if self.actions is None:
return None
return self.actions[0]
@property
def rewards(self):
"""Return the rewards."""
@@ -144,6 +181,11 @@ class Env(object): # gym.Env):
rewards = lambda: None
self._rewards = rewards
@property
def reward_range(self):
"""Return the range of the reward function; a tuple corresponding to the min and max possible rewards"""
return self._rewards.range
@property
def terminal_conditions(self):
"""Return the terminal condition."""
@@ -304,22 +346,15 @@ class Env(object): # gym.Env):
def render(self, mode='human'):
"""Renders the environment (show the GUI)."""
# This is dependent on the simulator. Some simulators allow to show the GUI at any point in time,
# while others like pybullet requires to specify it at the beginning (thus see SimuRealInterface).
# Bullet: do nothing
# if isinstance(self.sim, Bullet): pass
# self.sim.configureDebugVisualizer(self.sim.COV_ENABLE_RENDERING, 1)
pass
self.sim.render()
def hide(self):
"""hide the GUI."""
# self.sim.configureDebugVisualizer(self.sim.COV_ENABLE_RENDERING, 0)
pass
self.sim.hide()
def close(self):
"""Close the environment."""
pass
self.sim.close()
def seed(self, seed=None):
"""
@@ -343,10 +378,10 @@ class BasicEnv(Env):
"""
def __init__(self, sim, states=None, rewards=None, terminal_conditions=None, initial_state_generators=None,
physics_randomizers=None, extra_info=None):
physics_randomizers=None, extra_info=None, actions=None):
world = BasicWorld(sim)
super(BasicEnv, self).__init__(world, states, rewards, terminal_conditions, initial_state_generators,
physics_randomizers, extra_info)
physics_randomizers, extra_info, actions)
# Tests
+17 -1
View File
@@ -154,6 +154,11 @@ class GymEnvWrapper(gym.Env):
"""Return the reward instance."""
return self._reward
@property
def reward_range(self):
"""Return the range of the reward function; a tuple corresponding to the min and max possible rewards"""
return self.env.reward_range
@property
def state_processors(self):
"""Return the processors that have to be applied on the state."""
@@ -227,13 +232,14 @@ class GymEnvWrapper(gym.Env):
return states
def reset(self):
"""Reset the gym environment."""
observation = self.env.reset()
self.state.data = observation
self.reward_processors.reset()
return self._convert_state_to_data(self.state)
def step(self, actions):
"""perform a step in the environment and set the data for the GymState and GymAction"""
"""perform a step in the gym environment and set the data for the GymState and GymAction"""
if isinstance(actions, Action): # convert from `Action` to numpy
actions = actions.merged_data[0]
elif isinstance(actions, torch.Tensor): # convert from torch to numpy
@@ -263,11 +269,21 @@ class GymEnvWrapper(gym.Env):
return observations, reward, done, info
def render(self, mode='human'):
"""Render the gym environment."""
self.env.render(mode)
def hide(self):
"""Hide the gym environment (not used)."""
pass
def close(self):
"""Close the gym environment."""
self.env.close()
def seed(self, seed=None):
"""Set the given seed to the gym environment."""
self.env.seed(seed)
#############
# Operators #
#############