tinysim 0.0.4__tar.gz → 0.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tinysim-0.0.4 → tinysim-0.0.5}/PKG-INFO +5 -6
- {tinysim-0.0.4 → tinysim-0.0.5}/README.md +4 -5
- {tinysim-0.0.4 → tinysim-0.0.5}/pyproject.toml +1 -1
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/__init__.py +7 -2
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/_tk_base.py +20 -2
- tinysim-0.0.5/tinysim/_widget_base.py +41 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/flappy/__init__.py +5 -3
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/flappy/tk.py +10 -34
- tinysim-0.0.5/tinysim/flappy/widget.py +24 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/frogger/__init__.py +21 -4
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/frogger/tk.py +12 -28
- tinysim-0.0.5/tinysim/frogger/widget.py +31 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/mountain_car/__init__.py +17 -12
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/mountain_car/tk.py +9 -27
- tinysim-0.0.5/tinysim/mountain_car/widget.py +27 -0
- tinysim-0.0.5/tinysim/tinyspace.py +68 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/topdown_driving/__init__.py +16 -18
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/topdown_driving/tk.py +13 -38
- tinysim-0.0.5/tinysim/topdown_driving/track_0.json +1 -0
- tinysim-0.0.5/tinysim/topdown_driving/widget.py +25 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim.egg-info/PKG-INFO +5 -6
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim.egg-info/SOURCES.txt +5 -5
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/gl_viewer.py +36 -11
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/__init__.py +19 -5
- tinysim-0.0.5/tinysim_mujoco/manipulation/push_env.py +268 -0
- tinysim-0.0.5/tinysim_mujoco/manipulation/push_env_cam.py +274 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/panda.xml +59 -16
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/scene.xml +0 -3
- tinysim-0.0.5/tinysim_mujoco/manipulation/xmls/table.xml +41 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/notebook_viewer.py +3 -6
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/__init__.py +7 -10
- tinysim-0.0.5/tinysim_warp/__init__.py +108 -0
- tinysim-0.0.5/tinysim_warp/cart_pole/__init__.py +103 -0
- tinysim-0.0.5/tinysim_warp/quadruped/__init__.py +66 -0
- tinysim-0.0.5/tinysim_warp/simple_quadruped/__init__.py +97 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_warp/simple_quadruped/simple_quadruped.urdf +0 -9
- tinysim-0.0.4/tinysim/flappy/widget.py +0 -53
- tinysim-0.0.4/tinysim/frogger/widget.py +0 -60
- tinysim-0.0.4/tinysim/mountain_car/widget.py +0 -56
- tinysim-0.0.4/tinysim/simple_amr/example_maps.py +0 -121
- tinysim-0.0.4/tinysim/simple_amr/sim.js +0 -430
- tinysim-0.0.4/tinysim/simple_amr/styles.css +0 -54
- tinysim-0.0.4/tinysim/simple_amr/widget.py +0 -73
- tinysim-0.0.4/tinysim/topdown_driving/track_0.json +0 -753
- tinysim-0.0.4/tinysim/topdown_driving/widget.py +0 -59
- tinysim-0.0.4/tinysim_mujoco/__init__.py +0 -0
- tinysim-0.0.4/tinysim_mujoco/manipulation/xmls/table.xml +0 -37
- tinysim-0.0.4/tinysim_warp/cart_pole/__init__.py +0 -259
- tinysim-0.0.4/tinysim_warp/quadruped/__init__.py +0 -203
- tinysim-0.0.4/tinysim_warp/simple_quadruped/__init__.py +0 -168
- {tinysim-0.0.4 → tinysim-0.0.5}/setup.cfg +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/flappy/sim.js +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/frogger/sim.js +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/mountain_car/sim.js +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/mountain_car/styles.css +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim/topdown_driving/sim.js +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim.egg-info/dependency_links.txt +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim.egg-info/requires.txt +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim.egg-info/top_level.txt +0 -0
- {tinysim-0.0.4/tinysim/simple_amr → tinysim-0.0.5/tinysim_mujoco}/__init__.py +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/d405.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/finger_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/finger_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/hand_4.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_10.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_11.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_4.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_5.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_7.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_8.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link0_9.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link1.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link2.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link3.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link3_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link3_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link3_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link3_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link4.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link4_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link4_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link4_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link4_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_collision_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_collision_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link5_collision_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_10.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_11.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_12.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_13.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_14.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_15.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_16.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_4.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_5.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_6.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_7.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_8.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link6_9.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7.stl +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_0.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_1.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_2.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_3.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_4.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_5.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_6.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/manipulation/xmls/assets/link7_7.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/CHANGELOG.md +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/LICENSE +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/README.md +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/a1.xml +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/assets/calf.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/assets/hip.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/assets/thigh.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/assets/thigh_mirror.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/assets/trunk.obj +0 -0
- {tinysim-0.0.4 → tinysim-0.0.5}/tinysim_mujoco/unitree_a1/unitree_a1/scene.xml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinysim
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: small modular simulation environments
|
|
5
5
|
Author-email: Matthew Taylor <matthew.taylor.andre@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/MatthewAndreTaylor/TinySim
|
|
@@ -30,7 +30,7 @@ Requires-Dist: mujoco; extra == "mujoco"
|
|
|
30
30
|
# TinySim
|
|
31
31
|
|
|
32
32
|
[](https://pypi.org/project/tinysim)
|
|
33
|
-
[](https://matthewandretaylor.github.io/TinySim
|
|
33
|
+
[](https://matthewandretaylor.github.io/TinySim)
|
|
34
34
|
|
|
35
35
|
The goal of this project is to create more minimal simulation environments for robotics and machine learning.
|
|
36
36
|
|
|
@@ -73,8 +73,7 @@ To use the [mujoco](https://github.com/google-deepmind/mujoco) simulation enviro
|
|
|
73
73
|
```bash
|
|
74
74
|
pip install tinysim[mujoco]
|
|
75
75
|
```
|
|
76
|
-
| [UnitreeA1WalkEnv](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/unitree_a1) |
|
|
77
|
-
|
|
78
|
-
| <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/1109488e-0563-4694-8926-682edd0c8278" /> |
|
|
79
|
-
|
|
76
|
+
| [UnitreeA1WalkEnv](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/unitree_a1) | [ManipulationEnvV0](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/manipulation) |
|
|
77
|
+
|:-------------------------:|:-------------------------:|
|
|
78
|
+
| <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/1109488e-0563-4694-8926-682edd0c8278" /> | <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/07b406b5-15fc-4cfd-83c4-cf6b855d773a" /> |
|
|
80
79
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# TinySim
|
|
3
3
|
|
|
4
4
|
[](https://pypi.org/project/tinysim)
|
|
5
|
-
[](https://matthewandretaylor.github.io/TinySim
|
|
5
|
+
[](https://matthewandretaylor.github.io/TinySim)
|
|
6
6
|
|
|
7
7
|
The goal of this project is to create more minimal simulation environments for robotics and machine learning.
|
|
8
8
|
|
|
@@ -45,8 +45,7 @@ To use the [mujoco](https://github.com/google-deepmind/mujoco) simulation enviro
|
|
|
45
45
|
```bash
|
|
46
46
|
pip install tinysim[mujoco]
|
|
47
47
|
```
|
|
48
|
-
| [UnitreeA1WalkEnv](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/unitree_a1) |
|
|
49
|
-
|
|
50
|
-
| <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/1109488e-0563-4694-8926-682edd0c8278" /> |
|
|
51
|
-
|
|
48
|
+
| [UnitreeA1WalkEnv](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/unitree_a1) | [ManipulationEnvV0](https://github.com/MatthewAndreTaylor/TinySim/tree/main/tinysim_mujoco/manipulation) |
|
|
49
|
+
|:-------------------------:|:-------------------------:|
|
|
50
|
+
| <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/1109488e-0563-4694-8926-682edd0c8278" /> | <img width="312" alt="mujoco_sim" src="https://github.com/user-attachments/assets/07b406b5-15fc-4cfd-83c4-cf6b855d773a" /> |
|
|
52
51
|
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
|
|
3
|
+
from .tinyspace import Space
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
class SimEnvironment(ABC):
|
|
7
|
+
|
|
8
|
+
action_space: Space
|
|
9
|
+
|
|
5
10
|
@abstractmethod
|
|
6
|
-
def step(self,
|
|
11
|
+
def step(self, *args, **kwargs):
|
|
7
12
|
pass
|
|
8
13
|
|
|
9
14
|
@abstractmethod
|
|
10
|
-
def reset(self
|
|
15
|
+
def reset(self, *args, **kwargs):
|
|
11
16
|
pass
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
1
|
import threading
|
|
2
|
+
import tkinter as tk
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
|
|
5
|
+
from . import SimEnvironment
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
class TkBaseFrontend(ABC):
|
|
7
9
|
|
|
8
|
-
def __init__(self):
|
|
10
|
+
def __init__(self, sim_env: SimEnvironment):
|
|
11
|
+
self.sim_env = sim_env
|
|
9
12
|
self._root = None
|
|
10
13
|
self._canvas = None
|
|
11
14
|
self._thread = None
|
|
@@ -16,6 +19,21 @@ class TkBaseFrontend(ABC):
|
|
|
16
19
|
self._thread = threading.Thread(target=self._window_hook, daemon=True)
|
|
17
20
|
self._thread.start()
|
|
18
21
|
|
|
22
|
+
def step(self, *args, **kwargs):
|
|
23
|
+
state = self.sim_env.step(*args, **kwargs)
|
|
24
|
+
if self._root:
|
|
25
|
+
self._root.after(0, lambda: self._draw_state(state))
|
|
26
|
+
return state
|
|
27
|
+
|
|
28
|
+
def reset(self, *args, **kwargs):
|
|
29
|
+
state = self.sim_env.reset()
|
|
30
|
+
if self._canvas:
|
|
31
|
+
self._draw_state(state)
|
|
32
|
+
return state
|
|
33
|
+
|
|
34
|
+
def _draw_state(self, state):
|
|
35
|
+
raise NotImplementedError
|
|
36
|
+
|
|
19
37
|
def _window_hook(self):
|
|
20
38
|
root = tk.Tk()
|
|
21
39
|
root.protocol("WM_DELETE_WINDOW", self._on_close)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import anywidget
|
|
2
|
+
import traitlets
|
|
3
|
+
from IPython.display import display
|
|
4
|
+
from jupyter_ui_poll import ui_events
|
|
5
|
+
|
|
6
|
+
from . import SimEnvironment
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BaseWidget(anywidget.AnyWidget):
|
|
10
|
+
|
|
11
|
+
sim_env: SimEnvironment
|
|
12
|
+
_view_ready = traitlets.Bool(default_value=False).tag(sync=True)
|
|
13
|
+
|
|
14
|
+
def __init__(self, sim_env: SimEnvironment):
|
|
15
|
+
super().__init__()
|
|
16
|
+
self.sim_env = sim_env
|
|
17
|
+
self.sim_state = self.sim_env.reset()
|
|
18
|
+
self._update_props(self.sim_state)
|
|
19
|
+
|
|
20
|
+
def render(self):
|
|
21
|
+
display(self)
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
with ui_events() as ui_poll:
|
|
25
|
+
while not self._view_ready:
|
|
26
|
+
ui_poll(100)
|
|
27
|
+
except Exception:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def _update_props(self, sim_state):
|
|
31
|
+
self.sim_state = sim_state
|
|
32
|
+
|
|
33
|
+
def step(self, *args, **kwargs):
|
|
34
|
+
sim_state = self.sim_env.step(*args, **kwargs)
|
|
35
|
+
self._update_props(sim_state)
|
|
36
|
+
return sim_state
|
|
37
|
+
|
|
38
|
+
def reset(self, *args, **kwargs):
|
|
39
|
+
sim_state = self.sim_env.reset(*args, **kwargs)
|
|
40
|
+
self._update_props(sim_state)
|
|
41
|
+
return sim_state
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
|
|
2
3
|
from .. import SimEnvironment
|
|
4
|
+
from ..tinyspace import Discrete
|
|
3
5
|
|
|
4
6
|
WIDTH, HEIGHT = 800, 600
|
|
5
7
|
GRAVITY = 900.0
|
|
@@ -16,6 +18,7 @@ BIRD_SIZE = 35
|
|
|
16
18
|
class FlappyEnv(SimEnvironment):
|
|
17
19
|
def __init__(self, num_envs: int = 1):
|
|
18
20
|
self.num_envs = num_envs
|
|
21
|
+
self.action_space = Discrete(2) # 0: no flap, 1: flap
|
|
19
22
|
self.reset()
|
|
20
23
|
|
|
21
24
|
def reset(self):
|
|
@@ -54,16 +57,15 @@ class FlappyEnv(SimEnvironment):
|
|
|
54
57
|
self.pipes_x = self.pipes_x[keep]
|
|
55
58
|
self.pipes_y = self.pipes_y[keep]
|
|
56
59
|
|
|
57
|
-
def _check_collisions(self):
|
|
60
|
+
def _check_collisions(self):
|
|
58
61
|
hit_bounds = (self.bird_y < 0) | (self.bird_y + BIRD_SIZE > HEIGHT)
|
|
59
|
-
bx = BIRD_X
|
|
60
62
|
by = self.bird_y[:, None]
|
|
61
63
|
px = self.pipes_x[None, :]
|
|
62
64
|
upper_y = np.zeros_like(self.pipes_y)[None, :]
|
|
63
65
|
upper_h = self.pipes_y[None, :]
|
|
64
66
|
lower_y = (self.pipes_y + PIPE_GAP)[None, :]
|
|
65
67
|
lower_h = (HEIGHT - (self.pipes_y + PIPE_GAP))[None, :]
|
|
66
|
-
x_overlap = (
|
|
68
|
+
x_overlap = (BIRD_X < px + PIPE_WIDTH) & (BIRD_X + BIRD_SIZE > px)
|
|
67
69
|
upper_hit = x_overlap & (by < upper_y + upper_h) & (by + BIRD_SIZE > upper_y)
|
|
68
70
|
lower_hit = x_overlap & (by < lower_y + lower_h) & (by + BIRD_SIZE > lower_y)
|
|
69
71
|
hit_pipe = (upper_hit | lower_hit).any(axis=1)
|
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
1
|
try:
|
|
4
2
|
import tkinter as tk
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
from .._tk_base import TkBaseFrontend
|
|
6
5
|
except ImportError:
|
|
7
6
|
raise ImportError("tkinter is required for FlappyTkFrontend")
|
|
8
7
|
|
|
9
|
-
from . import
|
|
10
|
-
FlappyEnv,
|
|
11
|
-
WIDTH,
|
|
12
|
-
HEIGHT,
|
|
13
|
-
PIPE_WIDTH,
|
|
14
|
-
BIRD_SIZE,
|
|
15
|
-
BIRD_X,
|
|
16
|
-
PIPE_GAP,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class FlappyTkFrontend(_tk_base.TkBaseFrontend):
|
|
8
|
+
from . import BIRD_SIZE, BIRD_X, HEIGHT, PIPE_GAP, PIPE_WIDTH, WIDTH, FlappyEnv
|
|
21
9
|
|
|
22
|
-
def __init__(self, viewport_size=(800, 600), sim_env=None):
|
|
23
|
-
super().__init__()
|
|
24
|
-
if sim_env is None:
|
|
25
|
-
sim_env = FlappyEnv()
|
|
26
10
|
|
|
27
|
-
|
|
11
|
+
class FlappyTkFrontend(TkBaseFrontend):
|
|
12
|
+
def __init__(self, viewport_size=(800, 600), sim_env=FlappyEnv()):
|
|
13
|
+
super().__init__(sim_env)
|
|
28
14
|
self._viewport_size = viewport_size
|
|
29
15
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await asyncio.sleep(dt)
|
|
36
|
-
return state
|
|
37
|
-
|
|
38
|
-
async def reset(self):
|
|
39
|
-
state = self.sim_env.reset()
|
|
40
|
-
if self._root:
|
|
41
|
-
self._draw_state(state)
|
|
42
|
-
return state
|
|
16
|
+
if sim_env.num_envs != 1:
|
|
17
|
+
raise ValueError(
|
|
18
|
+
"FlappyTkFrontend currently only supports single environment."
|
|
19
|
+
)
|
|
43
20
|
|
|
44
21
|
def _create_window(self, root):
|
|
45
22
|
w, h = self._viewport_size
|
|
@@ -66,7 +43,6 @@ class FlappyTkFrontend(_tk_base.TkBaseFrontend):
|
|
|
66
43
|
|
|
67
44
|
# bird
|
|
68
45
|
by = state["bird_y"]
|
|
69
|
-
|
|
70
46
|
if not state.get("done", False):
|
|
71
47
|
canvas.create_oval(
|
|
72
48
|
BIRD_X,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
|
|
3
|
+
import traitlets
|
|
4
|
+
|
|
5
|
+
from .._widget_base import BaseWidget
|
|
6
|
+
from . import FlappyEnv
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FlappySim(BaseWidget):
|
|
10
|
+
_esm = pathlib.Path(__file__).parent / "sim.js"
|
|
11
|
+
|
|
12
|
+
sim_state = traitlets.Dict(default_value={}).tag(sync=True)
|
|
13
|
+
_viewport_size = traitlets.Tuple(default_value=(800, 600)).tag(sync=True)
|
|
14
|
+
_manual_control = traitlets.Bool(default_value=False).tag(sync=True)
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self, viewport_size=(800, 600), manual_control=False, sim_env=FlappyEnv()
|
|
18
|
+
):
|
|
19
|
+
super().__init__(sim_env)
|
|
20
|
+
self._viewport_size = viewport_size
|
|
21
|
+
self._manual_control = manual_control
|
|
22
|
+
|
|
23
|
+
if sim_env.num_envs != 1:
|
|
24
|
+
raise ValueError("FlappySim currently only supports single environment.")
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
|
|
2
3
|
from .. import SimEnvironment
|
|
4
|
+
from ..tinyspace import Discrete
|
|
3
5
|
|
|
4
6
|
WIDTH, HEIGHT = 800, 600
|
|
5
7
|
CELL = 40
|
|
@@ -14,6 +16,9 @@ class FroggerEnv(SimEnvironment):
|
|
|
14
16
|
self.car_width = CELL * 2
|
|
15
17
|
self.traffic_rows = np.array([4, 5, 6, 8, 9])
|
|
16
18
|
self.speeds = np.array([120, -150, 200, -180, 140], dtype=np.float32)
|
|
19
|
+
self.done = np.zeros(self.num_envs, dtype=bool)
|
|
20
|
+
|
|
21
|
+
self.action_space = Discrete(5) # 0: stay, 1: left, 2: right, 3: up, 4: down
|
|
17
22
|
self.reset()
|
|
18
23
|
|
|
19
24
|
def reset(self):
|
|
@@ -62,9 +67,17 @@ class FroggerEnv(SimEnvironment):
|
|
|
62
67
|
dx = np.array([action_map[a][0] for a in action])
|
|
63
68
|
dy = np.array([action_map[a][1] for a in action])
|
|
64
69
|
|
|
65
|
-
# Move frogs
|
|
66
|
-
self.frog_pos[:, 0] = np.
|
|
67
|
-
|
|
70
|
+
# Move frogs only move frog if not done
|
|
71
|
+
self.frog_pos[:, 0] = np.where(
|
|
72
|
+
~self.done,
|
|
73
|
+
np.clip(self.frog_pos[:, 0] + dx, 0, COLS - 1),
|
|
74
|
+
self.frog_pos[:, 0],
|
|
75
|
+
)
|
|
76
|
+
self.frog_pos[:, 1] = np.where(
|
|
77
|
+
~self.done,
|
|
78
|
+
np.clip(self.frog_pos[:, 1] + dy, 0, ROWS - 1),
|
|
79
|
+
self.frog_pos[:, 1],
|
|
80
|
+
)
|
|
68
81
|
|
|
69
82
|
# Update car positions
|
|
70
83
|
self.car_x += self.speeds[:, None] * dt
|
|
@@ -127,6 +140,10 @@ class FroggerEnv(SimEnvironment):
|
|
|
127
140
|
current_height = self.total_height - self.frog_pos[:, 1]
|
|
128
141
|
self.score = self.crossings + current_height / self.total_height
|
|
129
142
|
|
|
143
|
+
# Added to persist done state
|
|
144
|
+
self.done = done | self.done
|
|
145
|
+
done = self.done
|
|
146
|
+
|
|
130
147
|
frog_pos = self.frog_pos.tolist()
|
|
131
148
|
grid = self._build_car_grid().tolist()
|
|
132
149
|
scores = self.score.tolist()
|
|
@@ -140,6 +157,6 @@ class FroggerEnv(SimEnvironment):
|
|
|
140
157
|
return {
|
|
141
158
|
"frog_pos": frog_pos,
|
|
142
159
|
"grid": grid,
|
|
143
|
-
"done": done,
|
|
144
160
|
"score": scores,
|
|
161
|
+
"done": done,
|
|
145
162
|
}
|
|
@@ -1,41 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
from . import FroggerEnv, WIDTH, HEIGHT, CELL, ROWS, COLS
|
|
1
|
+
from . import CELL, COLS, HEIGHT, ROWS, WIDTH, FroggerEnv
|
|
3
2
|
|
|
4
3
|
try:
|
|
5
4
|
import tkinter as tk
|
|
6
|
-
|
|
5
|
+
|
|
6
|
+
from .._tk_base import TkBaseFrontend
|
|
7
7
|
except ImportError:
|
|
8
8
|
raise ImportError("tkinter is required for FroggerTkFrontend")
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class FroggerTkFrontend(
|
|
11
|
+
class FroggerTkFrontend(TkBaseFrontend):
|
|
12
|
+
|
|
13
|
+
def __init__(self, viewport_size=(800, 600), sim_env=FroggerEnv()):
|
|
14
|
+
super().__init__(sim_env)
|
|
15
|
+
self._viewport_size = viewport_size
|
|
16
|
+
self.keys = set()
|
|
12
17
|
|
|
13
|
-
def __init__(self, viewport_size=(800, 600), sim_env=None):
|
|
14
|
-
super().__init__()
|
|
15
|
-
if sim_env is None:
|
|
16
|
-
sim_env = FroggerEnv()
|
|
17
18
|
if sim_env.num_envs != 1:
|
|
18
19
|
raise ValueError(
|
|
19
20
|
"FroggerTkFrontend currently only supports single environment."
|
|
20
21
|
)
|
|
21
|
-
self.sim_env = sim_env
|
|
22
|
-
self._viewport_size = viewport_size
|
|
23
|
-
|
|
24
|
-
self.keys = set()
|
|
25
|
-
|
|
26
|
-
async def step(self, action, dt=0.01):
|
|
27
|
-
state = self.sim_env.step(action, dt=dt)
|
|
28
|
-
if self._root:
|
|
29
|
-
self._root.after(0, lambda: self._draw_state(self.sim_env))
|
|
30
|
-
|
|
31
|
-
await asyncio.sleep(dt)
|
|
32
|
-
return state
|
|
33
|
-
|
|
34
|
-
async def reset(self):
|
|
35
|
-
state = self.sim_env.reset()
|
|
36
|
-
if self._canvas:
|
|
37
|
-
self._draw_state(self.sim_env)
|
|
38
|
-
return state
|
|
39
22
|
|
|
40
23
|
def _create_window(self, root):
|
|
41
24
|
w, h = self._viewport_size
|
|
@@ -49,11 +32,12 @@ class FroggerTkFrontend(_tk_base.TkBaseFrontend):
|
|
|
49
32
|
root.bind("<KeyRelease>", lambda e: self.keys.discard(e.keysym))
|
|
50
33
|
|
|
51
34
|
self.bring_to_front(root)
|
|
52
|
-
self._draw_state(
|
|
35
|
+
self._draw_state()
|
|
53
36
|
self._pump()
|
|
54
37
|
root.mainloop()
|
|
55
38
|
|
|
56
|
-
def _draw_state(self,
|
|
39
|
+
def _draw_state(self, state=None):
|
|
40
|
+
sim_env = self.sim_env
|
|
57
41
|
if not self._canvas:
|
|
58
42
|
return
|
|
59
43
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import traitlets
|
|
5
|
+
|
|
6
|
+
from .._widget_base import BaseWidget
|
|
7
|
+
from . import FroggerEnv
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FroggerWidget(BaseWidget):
|
|
11
|
+
_esm = pathlib.Path(__file__).parent / "sim.js"
|
|
12
|
+
|
|
13
|
+
sim_state = traitlets.Dict(default_value={}).tag(sync=True)
|
|
14
|
+
car_positions = traitlets.List(default_value=[]).tag(sync=True)
|
|
15
|
+
_viewport_size = traitlets.Tuple(default_value=(800, 600)).tag(sync=True)
|
|
16
|
+
|
|
17
|
+
def get_car_positions(self):
|
|
18
|
+
return np.vstack(self.sim_env.car_rects).flatten().tolist()
|
|
19
|
+
|
|
20
|
+
def __init__(self, viewport_size=(800, 600), sim_env=FroggerEnv()):
|
|
21
|
+
super().__init__(sim_env)
|
|
22
|
+
self._viewport_size = viewport_size
|
|
23
|
+
|
|
24
|
+
if sim_env.num_envs != 1:
|
|
25
|
+
raise ValueError(
|
|
26
|
+
"FroggerWidget currently only supports single environment."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def _update_props(self, sim_state):
|
|
30
|
+
self.sim_state = sim_state
|
|
31
|
+
self.car_positions = self.get_car_positions()
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
|
|
2
3
|
from .. import SimEnvironment
|
|
4
|
+
from ..tinyspace import Discrete
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class MountainCarEnv(SimEnvironment):
|
|
@@ -12,12 +14,12 @@ class MountainCarEnv(SimEnvironment):
|
|
|
12
14
|
self.force = 0.001
|
|
13
15
|
self.gravity = 0.0025
|
|
14
16
|
self.goal_position = 0.5
|
|
17
|
+
self.reset()
|
|
15
18
|
|
|
16
|
-
#
|
|
17
|
-
self.
|
|
18
|
-
self.velocity = np.zeros(num_envs, dtype=np.float32)
|
|
19
|
+
# actions: 0 (left), 1 (no push), 2 (right)
|
|
20
|
+
self.action_space = Discrete(3)
|
|
19
21
|
|
|
20
|
-
def step(self, action)
|
|
22
|
+
def step(self, action):
|
|
21
23
|
if np.isscalar(action):
|
|
22
24
|
action = np.full(self.num_envs, action, dtype=np.float32)
|
|
23
25
|
else:
|
|
@@ -46,11 +48,14 @@ class MountainCarEnv(SimEnvironment):
|
|
|
46
48
|
|
|
47
49
|
return {"position": self.position, "velocity": self.velocity, "done": done}
|
|
48
50
|
|
|
49
|
-
def reset(self) -> dict:
|
|
50
|
-
self.position = -0.5
|
|
51
|
-
self.velocity =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
def reset(self, **kwargs) -> dict:
|
|
52
|
+
self.position = np.full(self.num_envs, -0.5, dtype=np.float32)
|
|
53
|
+
self.velocity = np.zeros(self.num_envs, dtype=np.float32)
|
|
54
|
+
done = self.position >= self.goal_position
|
|
55
|
+
|
|
56
|
+
if self.num_envs == 1:
|
|
57
|
+
self.position = float(self.position[0])
|
|
58
|
+
self.velocity = float(self.velocity[0])
|
|
59
|
+
done = bool(done[0])
|
|
60
|
+
|
|
61
|
+
return {"position": self.position, "velocity": self.velocity, "done": done}
|
|
@@ -1,39 +1,23 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
import math
|
|
2
|
+
|
|
3
3
|
import numpy as np
|
|
4
|
+
|
|
4
5
|
from . import MountainCarEnv
|
|
5
6
|
|
|
6
7
|
try:
|
|
7
8
|
import tkinter as tk
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
from .._tk_base import TkBaseFrontend
|
|
9
11
|
except ImportError:
|
|
10
12
|
raise ImportError("tkinter is required for MountainCarTkFrontend")
|
|
11
13
|
|
|
12
14
|
|
|
13
|
-
class MountainCarTkFrontend(
|
|
15
|
+
class MountainCarTkFrontend(TkBaseFrontend):
|
|
14
16
|
|
|
15
|
-
def __init__(self, viewport_size=(600, 400), sim_env=
|
|
16
|
-
super().__init__()
|
|
17
|
-
if sim_env is None:
|
|
18
|
-
sim_env = MountainCarEnv()
|
|
19
|
-
self.sim_env = sim_env
|
|
17
|
+
def __init__(self, viewport_size=(600, 400), sim_env=MountainCarEnv()):
|
|
18
|
+
super().__init__(sim_env)
|
|
20
19
|
self._viewport_size = viewport_size
|
|
21
20
|
|
|
22
|
-
async def step(self, action, dt=0.01):
|
|
23
|
-
state = self.sim_env.step(action)
|
|
24
|
-
|
|
25
|
-
if self._root:
|
|
26
|
-
self._root.after(0, lambda s=state: self._draw_state(s))
|
|
27
|
-
|
|
28
|
-
await asyncio.sleep(dt)
|
|
29
|
-
return state
|
|
30
|
-
|
|
31
|
-
async def reset(self):
|
|
32
|
-
state = self.sim_env.reset()
|
|
33
|
-
if self._canvas:
|
|
34
|
-
self._draw_state(state)
|
|
35
|
-
return state
|
|
36
|
-
|
|
37
21
|
def _create_window(self, root):
|
|
38
22
|
w, h = self._viewport_size
|
|
39
23
|
root.title("Mountain Car")
|
|
@@ -46,7 +30,7 @@ class MountainCarTkFrontend(_tk_base.TkBaseFrontend):
|
|
|
46
30
|
self._pump()
|
|
47
31
|
root.mainloop()
|
|
48
32
|
|
|
49
|
-
def _draw_state(self, state
|
|
33
|
+
def _draw_state(self, state=None):
|
|
50
34
|
if not self._canvas:
|
|
51
35
|
return
|
|
52
36
|
|
|
@@ -54,12 +38,10 @@ class MountainCarTkFrontend(_tk_base.TkBaseFrontend):
|
|
|
54
38
|
w = int(c.winfo_width() or self._viewport_size[0])
|
|
55
39
|
h = int(c.winfo_height() or self._viewport_size[1])
|
|
56
40
|
c.delete("all")
|
|
57
|
-
|
|
58
41
|
min_x = self.sim_env.min_position
|
|
59
42
|
max_x = self.sim_env.max_position
|
|
60
43
|
world_width = max_x - min_x
|
|
61
44
|
scale = w / world_width
|
|
62
|
-
clearance = 10
|
|
63
45
|
|
|
64
46
|
def heightFn(x):
|
|
65
47
|
return np.sin(3 * x) * 0.45 + 0.55
|
|
@@ -105,7 +87,7 @@ class MountainCarTkFrontend(_tk_base.TkBaseFrontend):
|
|
|
105
87
|
for i, x_world in enumerate(positions):
|
|
106
88
|
y_world = heightFn(x_world)
|
|
107
89
|
x_screen = (x_world - min_x) * scale
|
|
108
|
-
y_screen = h - y_world * scale
|
|
90
|
+
y_screen = h - y_world * scale
|
|
109
91
|
|
|
110
92
|
slope = math.cos(3 * x_world)
|
|
111
93
|
angle = -math.atan(slope)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
|
|
3
|
+
import traitlets
|
|
4
|
+
|
|
5
|
+
from .._widget_base import BaseWidget
|
|
6
|
+
from . import MountainCarEnv
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MountainCarWidget(BaseWidget):
|
|
10
|
+
_esm = pathlib.Path(__file__).parent / "sim.js"
|
|
11
|
+
_css = pathlib.Path(__file__).parent / "styles.css"
|
|
12
|
+
|
|
13
|
+
sim_state = traitlets.Dict(default_value={}).tag(sync=True)
|
|
14
|
+
_viewport_size = traitlets.Tuple(default_value=(600, 400)).tag(sync=True)
|
|
15
|
+
_manual_control = traitlets.Bool(default_value=False).tag(sync=True)
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self, manual_control=False, viewport_size=(600, 400), sim_env=MountainCarEnv()
|
|
19
|
+
):
|
|
20
|
+
super().__init__(sim_env)
|
|
21
|
+
self._manual_control = manual_control
|
|
22
|
+
self._viewport_size = viewport_size
|
|
23
|
+
|
|
24
|
+
if sim_env.num_envs != 1:
|
|
25
|
+
raise ValueError(
|
|
26
|
+
"MountainCarWidget currently only supports single environment."
|
|
27
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
# It is encouraged to implement your own Space classes or use existing ones from external libraries.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Space:
|
|
9
|
+
"""A minimal implementation of the Space class for TinySim."""
|
|
10
|
+
|
|
11
|
+
def sample(self) -> Any:
|
|
12
|
+
"""Randomly sample an element from this space."""
|
|
13
|
+
raise NotImplementedError
|
|
14
|
+
|
|
15
|
+
def contains(self, x: Any) -> bool:
|
|
16
|
+
"""Return boolean specifying if x is a valid member of this space."""
|
|
17
|
+
raise NotImplementedError
|
|
18
|
+
|
|
19
|
+
def __contains__(self, x: Any) -> bool:
|
|
20
|
+
return self.contains(x)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Discrete(Space):
|
|
24
|
+
"""A discrete space in TinySim."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, n: int):
|
|
27
|
+
assert n >= 0, "n (number of elements) must be non-negative"
|
|
28
|
+
self.n = n
|
|
29
|
+
|
|
30
|
+
def sample(self) -> int:
|
|
31
|
+
return np.random.randint(0, self.n)
|
|
32
|
+
|
|
33
|
+
def contains(self, x: Any) -> bool:
|
|
34
|
+
return isinstance(x, int) and 0 <= x < self.n
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Box(Space):
|
|
38
|
+
"""A box space in TinySim."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, low: float, high: float, shape: tuple, dtype=np.float32):
|
|
41
|
+
self.low = np.full(shape, low, dtype=dtype)
|
|
42
|
+
self.high = np.full(shape, high, dtype=dtype)
|
|
43
|
+
self.shape = shape
|
|
44
|
+
self.dtype = dtype
|
|
45
|
+
|
|
46
|
+
def sample(self) -> Any:
|
|
47
|
+
return np.random.uniform(self.low, self.high, self.shape)
|
|
48
|
+
|
|
49
|
+
def contains(self, x: Any) -> bool:
|
|
50
|
+
x = np.array(x)
|
|
51
|
+
return (
|
|
52
|
+
x.shape == self.shape and np.all(x >= self.low) and np.all(x <= self.high)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Dict(Space):
|
|
57
|
+
"""A dictionary space in TinySim."""
|
|
58
|
+
|
|
59
|
+
def __init__(self, spaces: dict):
|
|
60
|
+
self.spaces = spaces
|
|
61
|
+
|
|
62
|
+
def sample(self) -> dict:
|
|
63
|
+
return {key: space.sample() for key, space in self.spaces.items()}
|
|
64
|
+
|
|
65
|
+
def contains(self, x: Any) -> bool:
|
|
66
|
+
if isinstance(x, dict) and x.keys() == self.spaces.keys():
|
|
67
|
+
return all(x[key] in self.spaces[key] for key in self.spaces.keys())
|
|
68
|
+
return False
|