mirror of
https://github.com/Farama-Foundation/Gymnasium.git
synced 2025-08-30 01:50:19 +00:00
Render API (#2671)
* add pygame GUI for frozen_lake.py env * add new line at EOF * pre-commit reformat * improve graphics * new images and dynamic window size * darker tile borders and fix ICC profile * pre-commit hook * adjust elf and stool size * Update frozen_lake.py * reformat * fix #2600 * #2600 * add rgb_array support * reformat * test render api change on FrozenLake * add render support for reset on frozenlake * add clock on pygame render * new render api for blackjack * new render api for cliffwalking * new render api for Env class * update reset method, lunar and Env * fix wrapper * fix reset lunar * new render api for box2d envs * new render api for mujoco envs * fix bug * new render api for classic control envs * fix tests * add render_mode None for CartPole * new render api for test fake envs * pre-commit hook * fix FrozenLake * fix FrozenLake * more render_mode to super - frozenlake * remove kwargs from frozen_lake new * pre-commit hook * add deprecated render method * add backwards compatibility * fix test * add _render * move pygame.init() (avoid pygame dependency on init) * fix pygame dependencies * remove collect_render() maintain multi-behaviours .render() * add type hints * fix renderer * don't call .render() with None * improve docstring * add single_rgb_array to all envs * remove None from metadata["render_modes"] * add type hints to test_env_checkers * fix lint * add comments to renderer * add comments to single_depth_array and single_state_pixels * reformat * add deprecation warnings and env.render_mode declaration * fix lint * reformat * fix tests * add docs * fix car racing determinism * remove warning test envs, customizable modes on renderer * remove commments and add todo for env_checker * fix car racing * replace render mode check with assert * update new mujoco * reformat * reformat * change metaclass definition * fix tests * implement mark suggestions (test, docs, sets) * check_render Co-authored-by: J K Terry <jkterry0@gmail.com>
This commit is contained in:
101
gym/core.py
101
gym/core.py
@@ -1,6 +1,16 @@
|
||||
"""Core API for Environment, Wrapper, ActionWrapper, RewardWrapper and ObservationWrapper."""
|
||||
import sys
|
||||
from typing import Generic, Optional, SupportsFloat, Tuple, TypeVar, Union
|
||||
from typing import (
|
||||
Any,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Optional,
|
||||
SupportsFloat,
|
||||
Tuple,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
|
||||
from gym import spaces
|
||||
from gym.logger import deprecation, warn
|
||||
@@ -14,6 +24,44 @@ if sys.version_info == (3, 6):
|
||||
|
||||
ObsType = TypeVar("ObsType")
|
||||
ActType = TypeVar("ActType")
|
||||
RenderFrame = TypeVar("RenderFrame")
|
||||
|
||||
|
||||
class _EnvDecorator(type): # TODO: remove with gym 1.0
|
||||
"""Metaclass used for adding deprecation warning to the mode kwarg in the render method."""
|
||||
|
||||
def __new__(cls, name, bases, attr):
|
||||
if "render" in attr.keys():
|
||||
attr["render"] = _EnvDecorator._deprecate_mode(attr["render"])
|
||||
|
||||
return super().__new__(cls, name, bases, attr)
|
||||
|
||||
@staticmethod
|
||||
def _deprecate_mode(render_func): # type: ignore
|
||||
render_return = Optional[Union[RenderFrame, List[RenderFrame]]]
|
||||
|
||||
def render(
|
||||
self: object, *args: Tuple[Any], **kwargs: Dict[str, Any]
|
||||
) -> render_return:
|
||||
if "mode" in kwargs.keys():
|
||||
deprecation(
|
||||
"The argument mode in render method is deprecated; "
|
||||
"use render_mode during environment initialization instead.\n"
|
||||
"See here for more information: https://www.gymlibrary.ml/content/api/"
|
||||
)
|
||||
elif self.spec is not None and "render_mode" not in self.spec.kwargs.keys(): # type: ignore
|
||||
deprecation(
|
||||
"You are calling render method, "
|
||||
"but you didn't specified the argument render_mode at environment initialization. "
|
||||
"To maintain backward compatibility, the environment will render in human mode.\n"
|
||||
"If you want to render in human mode, initialize the environment in this way: "
|
||||
"gym.make('EnvName', render_mode='human') and don't call the render method.\n"
|
||||
"See here for more information: https://www.gymlibrary.ml/content/api/"
|
||||
)
|
||||
|
||||
return render_func(self, *args, **kwargs)
|
||||
|
||||
return render
|
||||
|
||||
|
||||
class Env(Generic[ObsType, ActType]):
|
||||
@@ -43,8 +91,11 @@ class Env(Generic[ObsType, ActType]):
|
||||
Note: a default reward range set to :math:`(-\infty,+\infty)` already exists. Set it if you want a narrower range.
|
||||
"""
|
||||
|
||||
__metaclass__ = _EnvDecorator
|
||||
|
||||
# Set this in SOME subclasses
|
||||
metadata = {"render_modes": []}
|
||||
render_mode = None # define render_mode if your environment supports rendering
|
||||
reward_range = (-float("inf"), float("inf"))
|
||||
spec = None
|
||||
|
||||
@@ -130,42 +181,34 @@ class Env(Generic[ObsType, ActType]):
|
||||
if seed is not None:
|
||||
self._np_random, seed = seeding.np_random(seed)
|
||||
|
||||
def render(self, mode="human"):
|
||||
"""Renders the environment.
|
||||
# TODO: remove kwarg mode with gym 1.0
|
||||
def render(self, mode="human") -> Optional[Union[RenderFrame, List[RenderFrame]]]:
|
||||
"""Compute the render frames as specified by render_mode attribute during initialization of the environment.
|
||||
|
||||
A set of supported modes varies per environment. (And some
|
||||
The set of supported modes varies per environment. (And some
|
||||
third-party environments may not support rendering at all.)
|
||||
By convention, if mode is:
|
||||
By convention, if render_mode is:
|
||||
|
||||
- human: render to the current display or terminal and
|
||||
return nothing. Usually for human consumption.
|
||||
- rgb_array: Return a numpy.ndarray with shape (x, y, 3),
|
||||
representing RGB values for an x-by-y pixel image, suitable
|
||||
for turning into a video.
|
||||
- ansi: Return a string (str) or StringIO.StringIO containing a
|
||||
terminal-style text representation. The text can include newlines
|
||||
and ANSI escape sequences (e.g. for colors).
|
||||
- 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.
|
||||
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
|
||||
terminal-style text representation for each time step.
|
||||
The text can include newlines and ANSI escape sequences (e.g. for colors).
|
||||
|
||||
Note:
|
||||
Rendering computations is performed internally even if you don't call render().
|
||||
To avoid this, you can set render_mode = None and, if the environment supports it,
|
||||
call render() specifying the argument 'mode'.
|
||||
|
||||
Note:
|
||||
Make sure that your class's metadata 'render_modes' key includes
|
||||
the list of supported modes. It's recommended to call super()
|
||||
in implementations to use the functionality of this method.
|
||||
|
||||
Example:
|
||||
>>> import numpy as np
|
||||
>>> class MyEnv(Env):
|
||||
... metadata = {'render_modes': ['human', 'rgb_array']}
|
||||
...
|
||||
... def render(self, mode='human'):
|
||||
... if mode == 'rgb_array':
|
||||
... return np.array(...) # return RGB frame suitable for video
|
||||
... elif mode == 'human':
|
||||
... ... # pop up a window and render
|
||||
... else:
|
||||
... super().render(mode=mode) # just raise an exception
|
||||
|
||||
Args:
|
||||
mode: the mode to render with, valid modes are `env.metadata["render_modes"]`
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
Reference in New Issue
Block a user