Skip to content

Commit

Permalink
Update readme and fix some import redundancies. (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjshoots authored Dec 13, 2022
1 parent a843d54 commit 3e7ce13
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 20 deletions.
164 changes: 160 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

An API conversion tool for popular external reinforcement learning environments to [Gymnasium](https://github.com/farama-Foundation/gymnasium) and [PettingZoo](https://github.com/farama-Foundation/pettingZoo/) APIs.

upported APIs for Gymnasium
Supported APIs for Gymnasium
* OpenAI Gym
* Atari Environments
* DMControl

Supported APIs for PettingZoo
Expand All @@ -13,10 +14,9 @@ Supported APIs for PettingZoo

We are open to supporting more external APIs, please create an issue or ideally, a pull request implementing the new API.

## At a glance

## Get started

The supported `dm_control` environments are as follows:
This is an example of using Shimmy to convert DM Control environments into a Gymnasium compatible environment:

```python
import gymnasium as gym
Expand All @@ -43,3 +43,159 @@ dm_control/acrobot-swingup-v0
```

For most usage, we recommend applying the `gym.wrappers.FlattenObservation(env)` wrapper to reduce the `Dict` observation space to a `Box` observation space.

## Installation and Usage

To install Shimmy from PyPI:
```
pip install shimmy
```
Out of the box, Shimmy doesn't install any of the dependencies required for the environments it supports.
To install them, you'll have to install the optional extras.
All single agent environments have registration under the Gymnasium API, while all multiagent environments must be wrapped using the corresponding compatibility wrappers.

### OpenAI Gym

#### Installation
```
pip install shimmy[gym]
```

#### Usage
```python
import gymnasium as gym

env = gym.make("GymV22CompatibilityV0", env_name="...")
```

### Atari Environments

#### Installation
```
pip install shimmy[atari]
```

#### Usage
```python
import gymnasium as gym

env = gym.make("ALE/Pong-v5")
```

### DM Control (both single and multiagent environments)

#### Installation
```
pip install shimmy[dm-control]
```

#### Usage (Multi agent)
```python
from dm_control.locomotion import soccer as dm_soccer
from shimmy.dm_control_multiagent_compatibility import (
DmControlMultiAgentCompatibilityV0,
)

walker_type = dm_soccer.WalkerType.BOXHEAD,

env = dm_soccer.load(
team_size=2,
time_limit=10.0,
disable_walker_contacts=False,
enable_field_box=True,
terminate_on_goal=False,
walker_type=walker_type,
)

env = DmControlMultiAgentCompatibilityV0(env)
```

#### Usage (Single agent)
```python
import gymnasium as gym

env = gym.make("dm_control/acrobot_swingup_sparse-v0")
```

### OpenSpiel

#### Installation
```
pip install shimmy[pettingzoo]
```

#### Usage
```python
import pyspiel
from shimmy.openspiel_compatibility import OpenspielCompatibilityV0

env = pyspiel.load_game("2048")
env = OpenspielCompatibilityV0(game=env, render_mode=None)
```

### DM Lab

#### Installation

Courtesy to [Danijar Hafner](https://github.com/deepmind/lab/issues/242) for providing this install script.
```bash
#!/bin/sh
set -eu

# Dependencies
apt-get update && apt-get install -y \
build-essential curl freeglut3 gettext git libffi-dev libglu1-mesa \
libglu1-mesa-dev libjpeg-dev liblua5.1-0-dev libosmesa6-dev \
libsdl2-dev lua5.1 pkg-config python-setuptools python3-dev \
software-properties-common unzip zip zlib1g-dev g++
pip3 install numpy

# Bazel
apt-get install -y apt-transport-https curl gnupg
curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
mv bazel.gpg /etc/apt/trusted.gpg.d/
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
apt-get update && apt-get install -y bazel

# Build
git clone https://github.com/deepmind/lab.git
cd lab
echo 'build --cxxopt=-std=c++17' > .bazelrc
bazel build -c opt //python/pip_package:build_pip_package
./bazel-bin/python/pip_package/build_pip_package /tmp/dmlab_pkg
pip3 install --force-reinstall /tmp/dmlab_pkg/deepmind_lab-*.whl
cd ..
rm -rf lab
```

#### Usage
```python
import deepmind_lab

from shimmy.dm_lab_compatibility import DmLabCompatibilityV0

observations = ["RGBD"]
config = {"width": "640", "height": "480", "botCount": "2"}
renderer = "hardware"

env = deepmind_lab.Lab("lt_chasm", observations, config=config, renderer=renderer)
env = DmLabCompatibilityV0(env)
```

### For Developers and Testing Only
```
pip install shimmy[testing]
```

### To just install everything
```
pip install shimmy[all, testing]
```

## Citation

If you use this in your research, please cite:
```
TBD
```

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def get_version():
keywords=["Reinforcement Learning", "game", "RL", "AI"],
python_requires=">=3.7",
packages=find_packages(),
install_requires=["numpy>=1.18.0", "gymnasium>=0.26.0"],
install_requires=["numpy>=1.18.0", "gymnasium>=0.27.0"],
tests_require=extras["testing"],
extras_require=extras,
classifiers=[
Expand Down
10 changes: 6 additions & 4 deletions shimmy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
pass

__all__ = [
"DmControlCompatibility",
"OpenspielWrapperV0",
"GymV22Compatibility",
"GymV26Compatibility",
"DmControlCompatibilityV0",
"DmControlMultiAgentCompatibilityV0",
"OpenspielCompatibilityV0",
"DmLabCompatibilityV0",
"GymV22CompatibilityV0",
"GymV26CompatibilityV0",
]
4 changes: 2 additions & 2 deletions shimmy/dm_control_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from dm_control import composer
from dm_control.rl import control
from gymnasium.core import ObsType
from gymnasium.envs.mujoco.mujoco_rendering import Viewer
from gymnasium.envs.mujoco.mujoco_rendering import MujocoRenderer

from shimmy.utils.dm_env import dm_control_step2gym_step, dm_spec2gym_space

Expand Down Expand Up @@ -68,7 +68,7 @@ def __init__(

if self.render_mode == "human":
# We use the gymnasium mujoco rendering, dm-control provides more complex rendering options.
self.viewer = Viewer(
self.viewer = MujocoRenderer(
self._env.physics.model.ptr, self._env.physics.data.ptr
)

Expand Down
4 changes: 2 additions & 2 deletions shimmy/dm_control_multiagent_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import dm_control.composer
import dm_env
import gymnasium
from gymnasium.envs.mujoco.mujoco_rendering import Viewer
from gymnasium.envs.mujoco.mujoco_rendering import MujocoRenderer
from pettingzoo import ParallelEnv

from shimmy.utils.dm_env import dm_obs2gym_obs, dm_spec2gym_space
Expand Down Expand Up @@ -100,7 +100,7 @@ def __init__(
self.act_spaces = dict(zip(self.possible_agents, all_act_spaces))

if self.render_mode == "human":
self.viewer = Viewer(
self.viewer = MujocoRenderer(
self._env.physics.model.ptr, self._env.physics.data.ptr
)

Expand Down
3 changes: 2 additions & 1 deletion tests/test_atari.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def test_all_atari_roms():
CHECK_ENV_IGNORE_WARNINGS = [
f"\x1b[33mWARN: {message}\x1b[0m"
for message in [
"Official support for the `seed` function is dropped. Standard practice is to reset gymnasium environments using `env.reset(seed=<desired seed>)`"
"Official support for the `seed` function is dropped. Standard practice is to reset gymnasium environments using `env.reset(seed=<desired seed>)`",
"No render fps was declared in the environment (env.metadata['render_fps'] is None or not defined), rendering may occur at inconsistent fps.",
]
]

Expand Down
8 changes: 6 additions & 2 deletions tests/test_dm_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ def test_dm_control_suite_envs():
"A Box observation space has an unconventional shape (neither an image, nor a 1D vector). We recommend flattening the observation to have only a 1D vector or use a custom policy to properly process the data. Actual observation shape: (1, 5)",
"It seems a Box observation space is an image but the `dtype` is not `np.uint8`, actual type: float64. If the Box observation space is not an image, we recommend flattening the observation to have only a 1D vector.",
"It seems a Box observation space is an image but the upper and lower bounds are not in [0, 255]. Generally, CNN policies assume observations are within that range, so you may encounter an issue if the observation values are not.",
"arrays to stack must be passed as a 'sequence' type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.",
]
]
CHECK_ENV_IGNORE_WARNINGS.append(
'arrays to stack must be passed as a "sequence" type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.',
)


@pytest.mark.parametrize("env_id", DM_CONTROL_ENV_IDS)
Expand Down Expand Up @@ -158,13 +162,13 @@ def test_dm_control_wrappers(
env = DmControlCompatibilityV0(wrapped_env)

with warnings.catch_warnings(record=True) as caught_warnings:
check_env(env)
check_env(env, skip_render_check=True)

for warning_message in caught_warnings:
assert isinstance(warning_message.message, Warning)
if warning_message.message.args[0] not in CHECK_ENV_IGNORE_WARNINGS:
raise Error(f"Unexpected warning: {warning_message.message}")

env = gym.make("dm_control/compatibility-env-v0", env=wrapped_env)
check_env(env)
check_env(env, skip_render_check=True)
env.close()
2 changes: 0 additions & 2 deletions tests/test_dm_control_multiagent.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Tests the multi-agent dm-control soccer environment."""

import gymnasium
import pytest
from dm_control.locomotion import soccer as dm_soccer
from gymnasium.utils.env_checker import data_equivalence
from pettingzoo.test import parallel_api_test

from shimmy.dm_control_multiagent_compatibility import (
Expand Down
25 changes: 25 additions & 0 deletions tests/test_dm_lab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Tests the multi-agent dm-control soccer environment."""

import gymnasium
import pytest
from gymnasium.utils.env_checker import check_env

from shimmy.dm_lab_compatibility import DmLabCompatibilityV0


@pytest.mark.skip(reason="no way of currently testing this")
def test_check_env():
"""Check that environment pass the gym check_env."""
import deepmind_lab

observations = ["RGBD"]
config = {"width": "640", "height": "480", "botCount": "2"}
renderer = "hardware"

env = deepmind_lab.Lab("lt_chasm", observations, config=config, renderer=renderer)

env = DmLabCompatibilityV0(env)

check_env(env)

env.close()
4 changes: 2 additions & 2 deletions tests/test_gym.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_gym_conversion_by_id(env_id):
env = gymnasium.make("GymV26Environment-v0", env_id=env_id).unwrapped

with warnings.catch_warnings(record=True) as caught_warnings:
check_env(env)
check_env(env, skip_render_check=True)

for warning in caught_warnings:
if (
Expand All @@ -55,7 +55,7 @@ def test_gym_conversion_instantiated(env_id):
env = gymnasium.make("GymV26Environment-v0", env=env).unwrapped

with warnings.catch_warnings(record=True) as caught_warnings:
check_env(env)
check_env(env, skip_render_check=True)

for warning in caught_warnings:
if (
Expand Down

0 comments on commit 3e7ce13

Please sign in to comment.