Rename "rgb_array" to "rgb_array_list" and "single_rgb_array" to "rgb_array" (#3040)

* initial commit

* Fix CI

* Fixed CI

* third time the charm

* Fix mujoco environment render modes order

* Remove unnecessary changes

* pre-commit

* Fix tests

* Comment out test render modes

* Fix code review and readd mujoco

* pre-commit

* Fix testing envs

* Fix all GenericTestEnvs

* Do not run mujoco-py render environments
This commit is contained in:
Mark Towers
2022-09-01 14:06:42 +01:00
committed by GitHub
parent aaa6cd9f33
commit 799c8d20c1
65 changed files with 307 additions and 255 deletions

View File

@@ -160,11 +160,11 @@ class Env(Generic[ObsType, ActType]):
- None (default): no render is computed.
- human: render return None.
The environment is continuously rendered in the current display or terminal. Usually for human consumption.
- single_rgb_array: return a single frame representing the current state of the environment.
- rgb_array: return a single frame representing the current state of the environment.
A frame is a numpy.ndarray with shape (x, y, 3) representing RGB values for an x-by-y pixel image.
- rgb_array: return a list of frames representing the states of the environment since the last reset.
Each frame is a numpy.ndarray with shape (x, y, 3), as with single_rgb_array.
- ansi: Return a list of strings (str) or StringIO.StringIO containing a
- rgb_array_list: return a list of frames representing the states of the environment since the last reset.
Each frame is a numpy.ndarray with shape (x, y, 3), as with `rgb_array`.
- ansi: Return a strings (str) or StringIO.StringIO containing a
terminal-style text representation for each time step.
The text can include newlines and ANSI escape sequences (e.g. for colors).

View File

@@ -164,7 +164,7 @@ class BipedalWalker(gym.Env, EzPickle):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": FPS,
}
@@ -742,7 +742,7 @@ class BipedalWalker(gym.Env, EzPickle):
pygame.event.pump()
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2)
)[:, -VIEWPORT_W:]

View File

@@ -184,10 +184,10 @@ class CarRacing(gym.Env, EzPickle):
metadata = {
"render_modes": [
"human",
"rgb_array_list",
"state_pixels_list",
"rgb_array",
"state_pixels",
"single_rgb_array",
"single_state_pixels",
],
"render_fps": FPS,
}
@@ -541,7 +541,7 @@ class CarRacing(gym.Env, EzPickle):
self.world.Step(1.0 / FPS, 6 * 30, 2 * 30)
self.t += 1.0 / FPS
self.state = self._render("single_state_pixels")
self.state = self._render("state_pixels")
step_reward = 0
terminated = False
@@ -601,7 +601,7 @@ class CarRacing(gym.Env, EzPickle):
zoom,
trans,
angle,
mode not in ["state_pixels", "single_state_pixels"],
mode not in ["state_pixels_list", "state_pixels"],
)
self.surf = pygame.transform.flip(self.surf, False, True)
@@ -623,9 +623,9 @@ class CarRacing(gym.Env, EzPickle):
self.screen.blit(self.surf, (0, 0))
pygame.display.flip()
if mode in {"rgb_array", "single_rgb_array"}:
if mode in {"rgb_array", "rgb_array_list"}:
return self._create_image_array(self.surf, (VIDEO_W, VIDEO_H))
elif mode in {"state_pixels", "single_state_pixels"}:
elif mode in {"state_pixels_list", "state_pixels"}:
return self._create_image_array(self.surf, (STATE_W, STATE_H))
else:
return self.isopen

View File

@@ -179,7 +179,7 @@ class LunarLander(gym.Env, EzPickle):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": FPS,
}
@@ -698,7 +698,7 @@ class LunarLander(gym.Env, EzPickle):
pygame.event.pump()
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2)
)

View File

@@ -137,7 +137,7 @@ class AcrobotEnv(core.Env):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 15,
}
@@ -297,7 +297,7 @@ class AcrobotEnv(core.Env):
self.screen = pygame.display.set_mode(
(self.SCREEN_DIM, self.SCREEN_DIM)
)
else: # mode in {"rgb_array", "single_rgb_array"}
else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.SCREEN_DIM, self.SCREEN_DIM))
if self.clock is None:
self.clock = pygame.time.Clock()
@@ -358,7 +358,7 @@ class AcrobotEnv(core.Env):
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
)

View File

@@ -83,7 +83,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 50,
}
@@ -226,7 +226,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height)
)
else: # mode in {"rgb_array", "single_rgb_array"}
else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None:
self.clock = pygame.time.Clock()
@@ -294,7 +294,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
)

View File

@@ -102,7 +102,7 @@ class Continuous_MountainCarEnv(gym.Env):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30,
}
@@ -208,7 +208,7 @@ class Continuous_MountainCarEnv(gym.Env):
self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height)
)
else: # mode in {"rgb_array", "single_rgb_array"}
else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None:
self.clock = pygame.time.Clock()
@@ -282,7 +282,7 @@ class Continuous_MountainCarEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
)

View File

@@ -97,7 +97,7 @@ class MountainCarEnv(gym.Env):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30,
}
@@ -186,7 +186,7 @@ class MountainCarEnv(gym.Env):
self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height)
)
else: # mode in {"rgb_array", "single_rgb_array"}
else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None:
self.clock = pygame.time.Clock()
@@ -260,7 +260,7 @@ class MountainCarEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
)

View File

@@ -89,7 +89,7 @@ class PendulumEnv(gym.Env):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30,
}
@@ -182,7 +182,7 @@ class PendulumEnv(gym.Env):
self.screen = pygame.display.set_mode(
(self.screen_dim, self.screen_dim)
)
else: # mode in {"rgb_array", "single_rgb_array"}
else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_dim, self.screen_dim))
if self.clock is None:
self.clock = pygame.time.Clock()
@@ -249,7 +249,7 @@ class PendulumEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
else: # mode == "rgb_array":
else: # mode == "rgb_array_list":
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
)

View File

@@ -10,9 +10,9 @@ class AntEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -14,9 +14,9 @@ class AntEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -176,9 +176,9 @@ class AntEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -10,9 +10,9 @@ class HalfCheetahEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -16,9 +16,9 @@ class HalfCheetahEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -136,9 +136,9 @@ class HalfCheetahEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -10,9 +10,9 @@ class HopperEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -19,9 +19,9 @@ class HopperEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -142,9 +142,9 @@ class HopperEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -16,9 +16,9 @@ class HumanoidEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 67,
}

View File

@@ -23,9 +23,9 @@ class HumanoidEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 67,
}

View File

@@ -216,9 +216,9 @@ class HumanoidEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 67,
}

View File

@@ -10,9 +10,9 @@ class HumanoidStandupEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 67,
}

View File

@@ -182,9 +182,9 @@ class HumanoidStandupEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 67,
}

View File

@@ -10,9 +10,9 @@ class InvertedDoublePendulumEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -116,9 +116,9 @@ class InvertedDoublePendulumEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -10,9 +10,9 @@ class InvertedPendulumEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 25,
}

View File

@@ -87,9 +87,9 @@ class InvertedPendulumEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 25,
}

View File

@@ -64,10 +64,10 @@ class BaseMujocoEnv(gym.Env):
assert self.metadata["render_modes"] == [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
]
"depth_array_list",
], self.metadata["render_modes"]
assert (
int(np.round(1.0 / self.dt)) == self.metadata["render_fps"]
), f'Expected value: {int(np.round(1.0 / self.dt))}, Actual value: {self.metadata["render_fps"]}'
@@ -254,9 +254,9 @@ class MuJocoPyEnv(BaseMujocoEnv):
assert mode in self.metadata["render_modes"]
if mode in {
"rgb_array",
"single_rgb_array",
"rgb_array_list",
"depth_array",
"single_depth_array",
"depth_array_list",
}:
if camera_id is not None and camera_name is not None:
raise ValueError(
@@ -274,11 +274,11 @@ class MuJocoPyEnv(BaseMujocoEnv):
self._get_viewer(mode).render(width, height, camera_id=camera_id)
if mode in {"rgb_array", "single_rgb_array"}:
if mode in {"rgb_array", "rgb_array_list"}:
data = self._get_viewer(mode).read_pixels(width, height, depth=False)
# original image is upside-down, so flip it
return data[::-1, :, :]
elif mode in {"depth_array", "single_depth_array"}:
elif mode in {"depth_array_list", "depth_array"}:
self._get_viewer(mode).render(width, height)
# Extract depth part of the read_pixels() tuple
data = self._get_viewer(mode).read_pixels(width, height, depth=True)[1]
@@ -298,8 +298,8 @@ class MuJocoPyEnv(BaseMujocoEnv):
elif mode in {
"rgb_array",
"depth_array",
"single_rgb_array",
"single_depth_array",
"rgb_array_list",
"depth_array_list",
}:
self.viewer = mujoco_py.MjRenderContextOffscreen(self.sim, -1)
else:
@@ -383,9 +383,9 @@ class MujocoEnv(BaseMujocoEnv):
if mode in {
"rgb_array",
"single_rgb_array",
"rgb_array_list",
"depth_array",
"single_depth_array",
"depth_array_list",
}:
if camera_id is not None and camera_name is not None:
raise ValueError(
@@ -406,11 +406,11 @@ class MujocoEnv(BaseMujocoEnv):
self._get_viewer(mode).render(camera_id=camera_id)
if mode in {"rgb_array", "single_rgb_array"}:
if mode in {"rgb_array", "rgb_array_list"}:
data = self._get_viewer(mode).read_pixels(depth=False)
# original image is upside-down, so flip it
return data[::-1, :, :]
elif mode in {"depth_array", "single_depth_array"}:
elif mode in {"depth_array", "depth_array_list"}:
self._get_viewer(mode).render()
# Extract depth part of the read_pixels() tuple
data = self._get_viewer(mode).read_pixels(depth=True)[1]
@@ -436,8 +436,8 @@ class MujocoEnv(BaseMujocoEnv):
elif mode in {
"rgb_array",
"depth_array",
"single_rgb_array",
"single_depth_array",
"rgb_array_list",
"depth_array_list",
}:
from gym.envs.mujoco import RenderContextOffscreen

View File

@@ -10,9 +10,9 @@ class PusherEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -132,9 +132,9 @@ class PusherEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 20,
}

View File

@@ -10,9 +10,9 @@ class ReacherEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 50,
}

View File

@@ -122,9 +122,9 @@ class ReacherEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 50,
}

View File

@@ -10,9 +10,9 @@ class SwimmerEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 25,
}

View File

@@ -14,9 +14,9 @@ class SwimmerEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 25,
}

View File

@@ -128,9 +128,9 @@ class SwimmerEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 25,
}

View File

@@ -10,9 +10,9 @@ class Walker2dEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -17,9 +17,9 @@ class Walker2dEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -147,9 +147,9 @@ class Walker2dEnv(MujocoEnv, utils.EzPickle):
"render_modes": [
"human",
"rgb_array",
"rgb_array_list",
"depth_array",
"single_rgb_array",
"single_depth_array",
"depth_array_list",
],
"render_fps": 125,
}

View File

@@ -638,17 +638,17 @@ def make(
if (
mode == "human"
and "human" not in render_modes
and ("single_rgb_array" in render_modes or "rgb_array" in render_modes)
and ("rgb_array" in render_modes or "rgb_array_list" in render_modes)
):
logger.warn(
"You are trying to use 'human' rendering for an environment that doesn't natively support it. "
"The HumanRendering wrapper is being applied to your environment."
)
apply_human_rendering = True
if "single_rgb_array" in render_modes:
_kwargs["render_mode"] = "single_rgb_array"
else:
if "rgb_array" in render_modes:
_kwargs["render_mode"] = "rgb_array"
else:
_kwargs["render_mode"] = "rgb_array_list"
elif mode not in render_modes:
logger.warn(
f"The environment is being initialised with mode ({mode}) that is not in the possible render_modes ({render_modes})."

View File

@@ -112,7 +112,7 @@ class BlackjackEnv(gym.Env):
"""
metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 4,
}

View File

@@ -62,7 +62,7 @@ class CliffWalkingEnv(Env):
- v0: Initial version release
"""
metadata = {"render_modes": ["human", "rgb_array", "ansi"], "render_fps": 4}
metadata = {"render_modes": ["human", "rgb_array_list", "ansi"], "render_fps": 4}
def __init__(self, render_mode: Optional[str] = None):
self.shape = (4, 12)

View File

@@ -156,7 +156,7 @@ class FrozenLakeEnv(Env):
"""
metadata = {
"render_modes": ["human", "ansi", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "ansi", "rgb_array", "rgb_array_list"],
"render_fps": 4,
}
@@ -274,7 +274,7 @@ class FrozenLakeEnv(Env):
assert mode in self.metadata["render_modes"]
if mode == "ansi":
return self._render_text()
elif mode in {"human", "rgb_array", "single_rgb_array"}:
elif mode in {"human", "rgb_array", "rgb_array_list"}:
return self._render_gui(mode)
def _render_gui(self, mode):
@@ -292,7 +292,7 @@ class FrozenLakeEnv(Env):
pygame.display.init()
pygame.display.set_caption("Frozen Lake")
self.window_surface = pygame.display.set_mode(self.window_size)
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
self.window_surface = pygame.Surface(self.window_size)
assert (
@@ -370,7 +370,7 @@ class FrozenLakeEnv(Env):
pygame.event.pump()
pygame.display.update()
self.clock.tick(self.metadata["render_fps"])
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.window_surface)), axes=(1, 0, 2)
)

View File

@@ -122,7 +122,7 @@ class TaxiEnv(Env):
"""
metadata = {
"render_modes": ["human", "ansi", "rgb_array", "single_rgb_array"],
"render_modes": ["human", "ansi", "rgb_array", "rgb_array_list"],
"render_fps": 4,
}
@@ -284,7 +284,7 @@ class TaxiEnv(Env):
assert mode in self.metadata["render_modes"]
if mode == "ansi":
return self._render_text()
elif mode in {"human", "rgb_array", "single_rgb_array"}:
elif mode in {"human", "rgb_array", "rgb_array_list"}:
return self._render_gui(mode)
def _render_gui(self, mode):
@@ -300,7 +300,7 @@ class TaxiEnv(Env):
pygame.display.set_caption("Taxi")
if mode == "human":
self.window = pygame.display.set_mode(WINDOW_SIZE)
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
self.window = pygame.Surface(WINDOW_SIZE)
assert (
@@ -412,7 +412,7 @@ class TaxiEnv(Env):
if mode == "human":
pygame.display.update()
self.clock.tick(self.metadata["render_fps"])
elif mode in {"rgb_array", "single_rgb_array"}:
elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose(
np.array(pygame.surfarray.pixels3d(self.window)), axes=(1, 0, 2)
)

View File

@@ -27,7 +27,7 @@ try:
import matplotlib.pyplot as plt
except ImportError:
logger.warn("Matplotlib is not installed, run `pip install gym[other]`")
plt = None
matplotlib, plt = None, None
class MissingKeysToAction(Exception):
@@ -50,9 +50,9 @@ class PlayableGame:
keys_to_action: The dictionary of keyboard tuples and action value
zoom: If to zoom in on the environment render
"""
if env.render_mode not in {"rgb_array", "single_rgb_array"}:
if env.render_mode not in {"rgb_array", "rgb_array_list"}:
logger.error(
"PlayableGame wrapper works only with rgb_array and single_rgb_array render modes, "
"PlayableGame wrapper works only with rgb_array and rgb_array_list render modes, "
f"but your environment render_mode = {env.render_mode}."
)
@@ -85,10 +85,10 @@ class PlayableGame:
if isinstance(rendered, List):
rendered = rendered[-1]
assert rendered is not None and isinstance(rendered, np.ndarray)
video_size = [rendered.shape[1], rendered.shape[0]]
video_size = (rendered.shape[1], rendered.shape[0])
if zoom is not None:
video_size = int(video_size[0] * zoom), int(video_size[1] * zoom)
video_size = (int(video_size[0] * zoom), int(video_size[1] * zoom))
return video_size
@@ -150,7 +150,7 @@ def play(
>>> import gym
>>> from gym.utils.play import play
>>> play(gym.make("CarRacing-v1", render_mode="single_rgb_array"), keys_to_action={
>>> play(gym.make("CarRacing-v1", render_mode="rgb_array"), keys_to_action={
... "w": np.array([0, 0.7, 0]),
... "a": np.array([-1, 0, 0]),
... "s": np.array([0, 0, 1]),
@@ -217,10 +217,6 @@ def play(
seed: Random seed used when resetting the environment. If None, no seed is used.
noop: The action used when no key input has been entered, or the entered key combination is unknown.
"""
deprecation(
"`play.py` currently supports only the old step API which returns one boolean, however this will soon be updated to support only the new step api that returns two bools."
)
env.reset(seed=seed)
if keys_to_action is None:

View File

@@ -5,7 +5,7 @@ from typing import Any, Callable, List, Optional, Set
NO_RETURNS_RENDER = {"human"}
# list of modes with which render returns just a single frame of the current state
SINGLE_RENDER = {"single_rgb_array", "single_depth_array", "single_state_pixels"}
SINGLE_RENDER = {"rgb_array", "depth_array", "state_pixels", "ansi"}
class Renderer:
@@ -36,7 +36,7 @@ class Renderer:
no_returns_render (Optional[Set[str]]): Set of render modes that don't return any value.
The default value is the set {"human"}.
single_render (Optional[Set[str]]): Set of render modes that should return a single frame.
The default value is the set {"single_rgb_array", "single_depth_array", "single_state_pixels"}.
The default value is the set {"rgb_array", "depth_array", "state_pixels", "ansi"}.
"""
if no_returns_render is None:
no_returns_render = NO_RETURNS_RENDER

View File

@@ -61,7 +61,7 @@ def save_video(
Example:
>>> import gym
>>> from gym.utils.save_video import save_video
>>> env = gym.make("FrozenLake-v1", render_mode="rgb_array")
>>> env = gym.make("FrozenLake-v1", render_mode="rgb_array_list")
>>> env.reset()
>>> step_starting_index = 0
>>> episode_index = 0
@@ -82,9 +82,7 @@ def save_video(
>>> env.close()
"""
if not isinstance(frames, list):
logger.error(
f"Expected a list of frames, got a {frames.__class__.__name__} instead."
)
logger.error(f"Expected a list of frames, got a {type(frames)} instead.")
if episode_trigger is None and step_trigger is None:
episode_trigger = capped_cubic_video_schedule

View File

@@ -6,17 +6,17 @@ from gym.error import DependencyNotInstalled
class HumanRendering(gym.Wrapper):
"""Performs human rendering for an environment that only supports rgb_array rendering.
"""Performs human rendering for an environment that only supports "rgb_array"rendering.
This wrapper is particularly useful when you have implemented an environment that can produce
RGB images but haven't implemented any code to render the images to the screen.
If you want to use this wrapper with your environments, remember to specify ``"render_fps"``
in the metadata of your environment.
The ``render_mode`` of the wrapped environment must be either ``'rgb_array'`` or ``'single_rgb_array'``.
The ``render_mode`` of the wrapped environment must be either ``'rgb_array'`` or ``'rgb_array_list'``.
Example:
>>> env = gym.make("LunarLander-v2", render_mode="single_rgb_array")
>>> env = gym.make("LunarLander-v2", render_mode="rgb_array")
>>> wrapped = HumanRendering(env)
>>> wrapped.reset() # This will start rendering to the screen
@@ -28,10 +28,10 @@ class HumanRendering(gym.Wrapper):
>>> env = gym.make("NoNativeRendering-v2", render_mode="human") # NoNativeRendering-v0 doesn't implement human-rendering natively
>>> env.reset() # This will start rendering to the screen
Warning: If the base environment uses ``render_mode="rgb_array"``, its (i.e. the *base environment's*) render method
Warning: If the base environment uses ``render_mode="rgb_array_list"``, its (i.e. the *base environment's*) render method
will always return an empty list:
>>> env = gym.make("LunarLander-v2", render_mode="rgb_array")
>>> env = gym.make("LunarLander-v2", render_mode="rgb_array_list")
>>> wrapped = HumanRendering(env)
>>> wrapped.reset()
>>> env.render()
@@ -47,9 +47,9 @@ class HumanRendering(gym.Wrapper):
"""
super().__init__(env)
assert env.render_mode in [
"single_rgb_array",
"rgb_array",
], f"Expected env.render_mode to be one of 'rgb_array' or 'single_rgb_array' but got '{env.render_mode}'"
"rgb_array_list",
], f"Expected env.render_mode to be one of 'rgb_array' or 'rgb_array_list' but got '{env.render_mode}'"
assert (
"render_fps" in env.metadata
), "The base environment must specify 'render_fps' to be used with the HumanRendering wrapper"
@@ -79,7 +79,7 @@ class HumanRendering(gym.Wrapper):
"""This method doesn't do much, actual rendering is performed in :meth:`step` and :meth:`reset`."""
return None
def _render_frame(self, mode="human", **kwargs):
def _render_frame(self):
"""Fetch the last frame from the base environment and render it to the screen."""
try:
import pygame
@@ -87,19 +87,18 @@ class HumanRendering(gym.Wrapper):
raise DependencyNotInstalled(
"pygame is not installed, run `pip install gym[box2d]`"
)
if self.env.render_mode == "rgb_array":
last_rgb_array = self.env.render(**kwargs)
if self.env.render_mode == "rgb_array_list":
last_rgb_array = self.env.render()
assert isinstance(last_rgb_array, list)
last_rgb_array = last_rgb_array[-1]
elif self.env.render_mode == "single_rgb_array":
last_rgb_array = self.env.render(**kwargs)
elif self.env.render_mode == "rgb_array":
last_rgb_array = self.env.render()
else:
raise Exception(
f"Wrapped environment must have mode 'rgb_array' or 'single_rgb_array', actual render mode: {self.env.render_mode}"
f"Wrapped environment must have mode 'rgb_array' or 'rgb_array_list', actual render mode: {self.env.render_mode}"
)
assert isinstance(last_rgb_array, np.ndarray)
if mode == "human":
rgb_array = np.transpose(last_rgb_array, axes=(1, 0, 2))
if self.screen_size is None:
@@ -122,8 +121,6 @@ class HumanRendering(gym.Wrapper):
pygame.event.pump()
self.clock.tick(self.metadata["render_fps"])
pygame.display.flip()
else:
raise Exception("Can only use 'human' rendering in HumanRendering wrapper")
def close(self):
"""Close the rendering window."""

View File

@@ -55,10 +55,10 @@ class VideoRecorder:
self.render_mode = env.render_mode
if "rgb_array" != self.render_mode and "single_rgb_array" != self.render_mode:
if "rgb_array_list" != self.render_mode and "rgb_array" != self.render_mode:
logger.warn(
f"Disabling video recorder because environment {env} was not initialized with any compatible video "
"mode between `single_rgb_array` and `rgb_array`"
"mode between `rgb_array` and `rgb_array_list`"
)
# Disable since the environment has not been initialized with a compatible `render_mode`
self.enabled = False

View File

@@ -24,13 +24,13 @@ class PixelObservationWrapper(gym.ObservationWrapper):
Example:
>>> import gym
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array"))
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"))
>>> obs = env.reset()
>>> obs.keys()
odict_keys(['pixels'])
>>> obs['pixels'].shape
(400, 600, 3)
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array"), pixels_only=False)
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"), pixels_only=False)
>>> obs = env.reset()
>>> obs.keys()
odict_keys(['state', 'pixels'])
@@ -38,7 +38,7 @@ class PixelObservationWrapper(gym.ObservationWrapper):
(96, 96, 3)
>>> obs['pixels'].shape
(400, 600, 3)
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array"), pixel_keys=('obs',))
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"), pixel_keys=('obs',))
>>> obs = env.reset()
>>> obs.keys()
odict_keys(['obs'])
@@ -95,10 +95,10 @@ class PixelObservationWrapper(gym.ObservationWrapper):
default_render_kwargs = {}
if not env.render_mode:
default_render_kwargs = {"mode": "rgb_array"}
default_render_kwargs = {"mode": "rgb_array_list"}
logger.warn(
"env.render_mode must be specified to use PixelObservationWrapper:"
"`gym.make(env_name, render_mode='single_rgb_array')`."
"`gym.make(env_name, render_mode='rgb_array')`."
)
for key in pixel_keys:

View File

@@ -1,16 +1,17 @@
import pickle
import warnings
import numpy as np
import pytest
import gym
from gym.envs.registration import EnvSpec
from gym.logger import warn
from gym.utils.env_checker import check_env, data_equivalence
from tests.envs.utils import (
all_testing_env_specs,
all_testing_initialised_envs,
assert_equals,
gym_testing_env_specs,
)
# This runs a smoketest on each official registered env. We may want
@@ -30,7 +31,6 @@ CHECK_ENV_IGNORE_WARNINGS = [
"A Box observation space minimum value is -infinity. This is probably too low.",
"A Box observation space maximum value is -infinity. This is probably too high.",
"For Box action spaces, we recommend using a symmetric and normalized space (range=[-1, 1] or [0, 1]). See https://stable-baselines3.readthedocs.io/en/master/guide/rl_tips.html for more information.",
"Initializing environment in done (old) step API which returns one bool instead of two.",
]
]
@@ -48,9 +48,6 @@ def test_envs_pass_env_checker(spec):
for warning in caught_warnings:
if warning.message.args[0] not in CHECK_ENV_IGNORE_WARNINGS:
print()
print(warning.message.args[0])
print(CHECK_ENV_IGNORE_WARNINGS[-1])
raise gym.error.Error(f"Unexpected warning: {warning.message}")
@@ -118,19 +115,69 @@ def test_env_determinism_rollout(env_spec: EnvSpec):
env_2.close()
def check_rendered(rendered_frame, mode: str):
"""Check that the rendered frame is as expected."""
if mode == "rgb_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "rgb_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 3
assert rendered_frame.shape[2] == 3
assert np.all(rendered_frame >= 0) and np.all(rendered_frame <= 255)
elif mode == "ansi":
assert isinstance(rendered_frame, str)
assert len(rendered_frame) > 0
elif mode == "state_pixels_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "state_pixels":
check_rendered(rendered_frame, "rgb_array")
elif mode == "depth_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "depth_array")
elif mode == "depth_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 2
else:
warn(
f"Unknown render mode: {mode}, cannot check that the rendered data is correct. Add case to `check_rendered`"
)
non_mujoco_py_env_specs = [
spec
for spec in all_testing_env_specs
if "mujoco" not in spec.entry_point or "v4" in spec.id
]
@pytest.mark.parametrize(
"spec", gym_testing_env_specs, ids=[spec.id for spec in gym_testing_env_specs]
"spec", non_mujoco_py_env_specs, ids=[spec.id for spec in non_mujoco_py_env_specs]
)
def test_render_modes(spec):
"""There is a known issue where rendering a mujoco environment then mujoco-py will cause an error on non-mac based systems.
Therefore, we are only testing with mujoco environments.
"""
env = spec.make()
for mode in env.metadata.get("render_modes", []):
assert len(env.metadata["render_modes"]) > 0
for mode in env.metadata["render_modes"]:
if mode != "human":
new_env = spec.make(render_mode=mode)
new_env.reset()
rendered = new_env.render()
check_rendered(rendered, mode)
new_env.step(new_env.action_space.sample())
new_env.render()
rendered = new_env.render()
check_rendered(rendered, mode)
new_env.close()
env.close()

View File

@@ -175,8 +175,10 @@ def test_make_render_mode():
env.close()
# Make sure that render_mode is applied correctly
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True)
assert env.render_mode == "rgb_array"
env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
assert env.render_mode == "rgb_array_list"
env.reset()
renders = env.render()
assert isinstance(
@@ -226,7 +228,9 @@ def test_make_render_mode():
TypeError, match=re.escape("got an unexpected keyword argument 'render_mode'")
):
gym.make(
"test/NoHumanOldAPI-v0", render_mode="rgb_array", disable_env_checker=True
"test/NoHumanOldAPI-v0",
render_mode="rgb_array_list",
disable_env_checker=True,
)
# Make sure that an additional error is thrown a user tries to use the wrapper on an environment with old API

View File

@@ -23,7 +23,7 @@ class ArgumentEnv(gym.Env):
class NoHuman(gym.Env):
"""Environment that does not have human-rendering."""
metadata = {"render_modes": ["rgb_array"], "render_fps": 4}
metadata = {"render_modes": ["rgb_array_list"], "render_fps": 4}
def __init__(self, render_mode=None):
assert render_mode in self.metadata["render_modes"]
@@ -33,7 +33,7 @@ class NoHuman(gym.Env):
class NoHumanOldAPI(gym.Env):
"""Environment that does not have human-rendering."""
metadata = {"render_modes": ["rgb_array"], "render_fps": 4}
metadata = {"render_modes": ["rgb_array_list"], "render_fps": 4}
def __init__(self):
pass

View File

@@ -101,7 +101,7 @@ properties = [
},
{"action_space": spaces.Discrete(2)},
{"reward_range": (-1.0, 1.0)},
{"metadata": {"render_modes": ["human", "rgb_array"]}},
{"metadata": {"render_modes": ["human", "rgb_array_list"]}},
{
"observation_space": spaces.Box(
low=0.0, high=1.0, shape=(64, 64, 3), dtype=np.float32

View File

@@ -1,6 +1,6 @@
"""Provides a generic testing environment for use in tests with custom reset, step and render functions."""
import types
from typing import List, Optional, Tuple, Union
from typing import Any, Dict, Optional, Tuple, Union
import gym
from gym import spaces
@@ -46,14 +46,11 @@ class GenericTestEnv(gym.Env):
reset_fn: callable = basic_reset_fn,
step_fn: callable = new_step_fn,
render_fn: callable = basic_render_fn,
render_modes: Optional[List[str]] = None,
render_fps: Optional[int] = None,
metadata: Optional[Dict[str, Any]] = None,
render_mode: Optional[str] = None,
spec: EnvSpec = EnvSpec("TestingEnv-v0"),
):
self.metadata = {"render_modes": render_modes}
if render_fps:
self.metadata["render_fps"] = render_fps
self.metadata = {} if metadata is None else metadata
self.render_mode = render_mode
self.spec = spec
@@ -76,7 +73,10 @@ class GenericTestEnv(gym.Env):
options: Optional[dict] = None,
) -> Union[ObsType, Tuple[ObsType, dict]]:
# If you need a default working reset function, use `basic_reset_fn` above
raise NotImplementedError("TestingEnv reset_fn is not set")
raise NotImplementedError("TestingEnv reset_fn is not set.")
def step(self, action: ActType) -> Tuple[ObsType, float, bool, dict]:
raise NotImplementedError("TestingEnv step_fn is not set")
raise NotImplementedError("TestingEnv step_fn is not set.")
def render(self):
raise NotImplementedError("testingEnv render_fn is not set.")

View File

@@ -396,24 +396,25 @@ def test_passive_env_step_checker(
[
[
UserWarning,
GenericTestEnv(render_modes=None),
GenericTestEnv(metadata={"render_modes": None}),
"No render modes was declared in the environment (env.metadata['render_modes'] is None or not defined), you may have trouble when calling `.render()`.",
],
[
UserWarning,
GenericTestEnv(render_modes="Testing mode"),
GenericTestEnv(metadata={"render_modes": "Testing mode"}),
"Expects the render_modes to be a sequence (i.e. list, tuple), actual type: <class 'str'>",
],
[
UserWarning,
GenericTestEnv(render_modes=["Testing mode", 1], render_fps=1),
GenericTestEnv(
metadata={"render_modes": ["Testing mode", 1], "render_fps": 1},
),
"Expects all render modes to be strings, actual types: [<class 'str'>, <class 'int'>]",
],
[
UserWarning,
GenericTestEnv(
render_modes=["Testing mode"],
render_fps=None,
metadata={"render_modes": ["Testing mode"], "render_fps": None},
render_mode="Testing mode",
render_fn=lambda self: 0,
),
@@ -421,18 +422,23 @@ def test_passive_env_step_checker(
],
[
UserWarning,
GenericTestEnv(render_modes=["Testing mode"], render_fps="fps"),
GenericTestEnv(
metadata={"render_modes": ["Testing mode"], "render_fps": "fps"}
),
"Expects the `env.metadata['render_fps']` to be an integer or a float, actual type: <class 'str'>",
],
[
AssertionError,
GenericTestEnv(render_modes=[], render_fps=30, render_mode="Test"),
GenericTestEnv(
metadata={"render_modes": [], "render_fps": 30}, render_mode="Test"
),
"With no render_modes, expects the Env.render_mode to be None, actual value: Test",
],
[
AssertionError,
GenericTestEnv(
render_modes=["Testing mode"], render_fps=30, render_mode="Non mode"
metadata={"render_modes": ["Testing mode"], "render_fps": 30},
render_mode="Non mode",
),
"The environment was initialized successfully however with an unsupported render mode. Render mode: Non mode, modes: ['Testing mode']",
],

View File

@@ -1,6 +1,6 @@
from dataclasses import dataclass
from functools import partial
from itertools import product
from typing import Callable, Optional
from typing import Callable
import numpy as np
import pygame
@@ -10,31 +10,18 @@ from pygame.event import Event
import gym
from gym.utils.play import MissingKeysToAction, PlayableGame, play
from tests.testing_env import GenericTestEnv
RELEVANT_KEY_1 = ord("a") # 97
RELEVANT_KEY_2 = ord("d") # 100
IRRELEVANT_KEY = 1
@dataclass
class DummyEnvSpec:
id: str
class DummyPlayEnv(gym.Env):
def __init__(self, render_mode: Optional[str] = None):
self.render_mode = render_mode
def step(self, action):
obs = np.zeros((1, 1))
rew, terminated, truncated, info = 1, False, False, {}
return obs, rew, terminated, truncated, info
def reset(self, seed=None):
...
def render(self):
return np.zeros((1, 1))
PlayableEnv = partial(
GenericTestEnv,
metadata={"render_modes": ["rgb_array"]},
render_fn=lambda self: np.ones((10, 10, 3)),
)
class KeysToActionWrapper(gym.Wrapper):
@@ -76,14 +63,13 @@ def close_pygame():
def test_play_relevant_keys():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2}
def test_play_relevant_keys_no_mapping():
env = DummyPlayEnv(render_mode="single_rgb_array")
env.spec = DummyEnvSpec("DummyPlayEnv")
env = PlayableEnv(render_mode="rgb_array")
with pytest.raises(MissingKeysToAction):
PlayableGame(env)
@@ -91,27 +77,27 @@ def test_play_relevant_keys_no_mapping():
def test_play_relevant_keys_with_env_attribute():
"""Env has a keys_to_action attribute"""
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
env.get_keys_to_action = dummy_keys_to_action
game = PlayableGame(env)
assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2}
def test_video_size_no_zoom():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
assert game.video_size == list(env.render().shape)
assert game.video_size == env.render().shape[:2]
def test_video_size_zoom():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
zoom = 2.2
game = PlayableGame(env, dummy_keys_to_action(), zoom)
assert game.video_size == tuple(int(shape * zoom) for shape in env.render().shape)
assert game.video_size == tuple(int(dim * zoom) for dim in env.render().shape[:2])
def test_keyboard_quit_event():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": pygame.K_ESCAPE})
assert game.running is True
@@ -120,7 +106,7 @@ def test_keyboard_quit_event():
def test_pygame_quit_event():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.QUIT)
assert game.running is True
@@ -129,7 +115,7 @@ def test_pygame_quit_event():
def test_keyboard_relevant_keydown_event():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1})
game.process_event(event)
@@ -137,7 +123,7 @@ def test_keyboard_relevant_keydown_event():
def test_keyboard_irrelevant_keydown_event():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": IRRELEVANT_KEY})
game.process_event(event)
@@ -145,7 +131,7 @@ def test_keyboard_irrelevant_keydown_event():
def test_keyboard_keyup_event():
env = DummyPlayEnv(render_mode="single_rgb_array")
env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1})
game.process_event(event)
@@ -189,7 +175,7 @@ def test_play_loop_real_env():
return obs_t, obs_tp1, action, rew, terminated, truncated, info
env = gym.make(ENV, render_mode="single_rgb_array", disable_env_checker=True)
env = gym.make(ENV, render_mode="rgb_array", disable_env_checker=True)
env.reset(seed=SEED)
keys_to_action = (
dummy_keys_to_action_str() if str_keys else dummy_keys_to_action()
@@ -202,9 +188,7 @@ def test_play_loop_real_env():
action = keys_to_action[chr(e.key) if str_keys else (e.key,)]
obs, _, _, _, _ = env.step(action)
env_play = gym.make(
ENV, render_mode="single_rgb_array", disable_env_checker=True
)
env_play = gym.make(ENV, render_mode="rgb_array", disable_env_checker=True)
if apply_wrapper:
env_play = KeysToActionWrapper(env, keys_to_action=keys_to_action)
assert hasattr(env_play, "get_keys_to_action")

View File

@@ -8,7 +8,9 @@ from gym.utils.save_video import capped_cubic_video_schedule, save_video
def test_record_video_using_default_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True)
env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
env.reset()
step_starting_index = 0
@@ -45,7 +47,7 @@ def modulo_step_trigger(mod: int):
def test_record_video_step_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array")
env = gym.make("CartPole-v1", render_mode="rgb_array_list")
env._max_episode_steps = 20
env.reset()
@@ -76,7 +78,7 @@ def test_record_video_step_trigger():
def test_record_video_within_vector():
envs = gym.vector.make(
"CartPole-v1", num_envs=2, asynchronous=True, render_mode="rgb_array"
"CartPole-v1", num_envs=2, asynchronous=True, render_mode="rgb_array_list"
)
envs.reset()
episode_frames = []

View File

@@ -97,7 +97,9 @@ def test_step_async_vector_env(shared_memory, use_single_action_space):
@pytest.mark.parametrize("shared_memory", [True, False])
def test_call_async_vector_env(shared_memory):
env_fns = [make_env("CartPole-v1", i, render_mode="rgb_array") for i in range(4)]
env_fns = [
make_env("CartPole-v1", i, render_mode="rgb_array_list") for i in range(4)
]
env = AsyncVectorEnv(env_fns, shared_memory=shared_memory)
_ = env.reset()

View File

@@ -77,7 +77,9 @@ def test_step_sync_vector_env(use_single_action_space):
def test_call_sync_vector_env():
env_fns = [make_env("CartPole-v1", i, render_mode="rgb_array") for i in range(4)]
env_fns = [
make_env("CartPole-v1", i, render_mode="rgb_array_list") for i in range(4)
]
env = SyncVectorEnv(env_fns)
_ = env.reset()

View File

@@ -7,7 +7,7 @@ from gym.wrappers import HumanRendering
def test_human_rendering():
for mode in ["rgb_array", "single_rgb_array"]:
for mode in ["rgb_array", "rgb_array_list"]:
env = HumanRendering(
gym.make("CartPole-v1", render_mode=mode, disable_env_checker=True)
)
@@ -25,7 +25,7 @@ def test_human_rendering():
with pytest.raises(
AssertionError,
match=re.escape(
"Expected env.render_mode to be one of 'rgb_array' or 'single_rgb_array' but got 'human'"
"Expected env.render_mode to be one of 'rgb_array' or 'rgb_array_list' but got 'human'"
),
):
HumanRendering(env)

View File

@@ -21,7 +21,7 @@ def test_gym_make_order_enforcing(spec):
def test_order_enforcing():
"""Checks that the order enforcing works as expected, raising an error before reset is called and not after."""
# The reason for not using gym.make is that all environments are by default wrapped in the order enforcing wrapper
env = CartPoleEnv(render_mode="rgb_array")
env = CartPoleEnv(render_mode="rgb_array_list")
assert not has_wrapper(env, OrderEnforcing)
# Assert that the order enforcing works for step and render before reset
@@ -40,6 +40,6 @@ def test_order_enforcing():
order_enforced_env.render()
# Assert that with disable_render_order_enforcing works, the environment has already been reset
env = CartPoleEnv(render_mode="rgb_array")
env = CartPoleEnv(render_mode="rgb_array_list")
env = OrderEnforcing(env, disable_render_order_enforcing=True)
env.render() # no assertion error

View File

@@ -68,7 +68,9 @@ def _step_failure(self, action):
def test_api_failures():
env = GenericTestEnv(
reset_fn=_reset_failure, step_fn=_step_failure, render_modes="error"
reset_fn=_reset_failure,
step_fn=_step_failure,
metadata={"render_modes": "error"},
)
env = PassiveEnvChecker(env)
assert env.checked_reset is False

View File

@@ -6,7 +6,9 @@ from gym.wrappers import capped_cubic_video_schedule
def test_record_video_using_default_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True)
env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
env = gym.wrappers.RecordVideo(env, "videos")
env.reset()
for _ in range(199):

View File

@@ -78,3 +78,5 @@ def test_step_compatibility_in_make(apply_step_compatibility):
assert len(step_returns) == 4
_, _, done, _ = step_returns
assert isinstance(done, bool)
gym.envs.registry.pop("OldStepEnv-v0")

View File

@@ -10,9 +10,9 @@ from gym.wrappers.monitoring.video_recorder import VideoRecorder
class BrokenRecordableEnv(gym.Env):
metadata = {"render_modes": ["rgb_array"]}
metadata = {"render_modes": ["rgb_array_list"]}
def __init__(self, render_mode="rgb_array"):
def __init__(self, render_mode="rgb_array_list"):
self.render_mode = render_mode
def render(self):
@@ -30,7 +30,9 @@ class UnrecordableEnv(gym.Env):
def test_record_simple():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True)
env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
rec = VideoRecorder(env)
env.reset()
rec.capture_frame()
@@ -45,7 +47,9 @@ def test_record_simple():
def test_autoclose():
def record():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True)
env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
rec = VideoRecorder(env)
env.reset()
rec.capture_frame()
@@ -77,7 +81,9 @@ def test_no_frames():
def test_record_unrecordable_method():
with pytest.warns(
UserWarning,
match="Disabling video recorder because environment <UnrecordableEnv instance> was not initialized with any compatible video mode between `single_rgb_array` and `rgb_array`",
match=re.escape(
"\x1b[33mWARN: Disabling video recorder because environment <UnrecordableEnv instance> was not initialized with any compatible video mode between `rgb_array` and `rgb_array_list`\x1b[0m"
),
):
env = UnrecordableEnv()
rec = VideoRecorder(env)
@@ -101,7 +107,9 @@ def test_record_breaking_render_method():
def test_text_envs():
env = gym.make("FrozenLake-v1", render_mode="rgb_array", disable_env_checker=True)
env = gym.make(
"FrozenLake-v1", render_mode="rgb_array_list", disable_env_checker=True
)
video = VideoRecorder(env)
try:
env.reset()