Skip to content

Commit

Permalink
Update tutorials (#40)
Browse files Browse the repository at this point in the history
* Update tutorials

* Update tutorials readme
  • Loading branch information
jagdeepsb authored Jun 13, 2024
1 parent 59ecb3f commit bc6212e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
24 changes: 23 additions & 1 deletion tutorials/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Tutorials

This folder contains completed code for all tutorials on our [website](https://evolutiongym.github.io/tutorials).
This folder contains completed code for all tutorials on our [website](https://evolutiongym.github.io/tutorials).

## Custom Environment

To see an example of custom environment creation, see `envs/simple_env.py`. This environment is registered in `envs/__init__.py`, and can be visualized by running `python .\visualize_simple_env.py` from this directory.

## Evogym Simulator API

See `basic_api.py` for a simple example of how to create, step, and render an Evogym simulator with objects of your choice. Evogym can be used to simulate any number of objects and robots (although simulation speed may slow with many objects).

To see understand the different rendering options available in Evogym, see `rendering_options.py`.
You can run:

```bash
python .\rendering_options.py --render-option to-debug-screen
```

| Option | Description |
|--------------------|------------------------------------------------------------------------|
| to-debug-screen | Render to Evogym's default viewer |
| to-numpy-array | Render to a numpy array (visualized with open cv) |
| special-options | Render with special flags (for pretty visualization) |
| very-fast | Render without fps limit |
2 changes: 1 addition & 1 deletion tutorials/envs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# import envs and necessary gym packages
from envs.simple_env import SimpleWalkerEnvClass
from gym.envs.registration import register
from gymnasium.envs.registration import register

# register the env using gym's interface
register(
Expand Down
29 changes: 18 additions & 11 deletions tutorials/envs/simple_env.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
from gym import spaces
from gymnasium import spaces
from evogym import EvoWorld
from evogym.envs import EvoGymBase

from typing import Optional, Dict, Any, Tuple
import numpy as np
import os

class SimpleWalkerEnvClass(EvoGymBase):

def __init__(self, body, connections=None):
def __init__(
self,
body: np.ndarray,
connections: Optional[np.ndarray] = None,
render_mode: Optional[str] = None,
render_options: Optional[Dict[str, Any]] = None,
):

# make world
self.world = EvoWorld.from_json(os.path.join('world_data', 'simple_walker_env.json'))
self.world.add_from_array('robot', body, 1, 1, connections=connections)

# init sim
EvoGymBase.__init__(self, self.world)
EvoGymBase.__init__(self, world=self.world, render_mode=render_mode, render_options=render_options)

# set action space and observation space
num_actuators = self.get_actuator_indices('robot').size
obs_size = self.reset().size
obs_size = self.reset()[0].size

self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=np.float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(obs_size,), dtype=np.float)
self.action_space = spaces.Box(low= 0.6, high=1.6, shape=(num_actuators,), dtype=float)
self.observation_space = spaces.Box(low=-100.0, high=100.0, shape=(obs_size,), dtype=float)

# set viewer to track objects
self.default_viewer.track_objects('robot')
Expand Down Expand Up @@ -58,17 +65,17 @@ def step(self, action):
self.get_relative_pos_obs("robot"),
))

# observation, reward, has simulation met termination conditions, debugging info
return obs, reward, done, {}
# observation, reward, has simulation met termination conditions, truncated, debugging info
return obs, reward, done, False, {}

def reset(self):
def reset(self, seed: Optional[int] = None, options: Optional[Dict[str, Any]] = None) -> Tuple[np.ndarray, Dict[str, Any]]:

super().reset()
super().reset(seed=seed, options=options)

# observation
obs = np.concatenate((
self.get_vel_com_obs("robot"),
self.get_relative_pos_obs("robot"),
))

return obs
return obs, {}
25 changes: 16 additions & 9 deletions tutorials/rendering_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import numpy as np
import cv2
import argparse

### CREATE A SIMPLE ENVIRONMENT ###

Expand All @@ -27,13 +28,18 @@

### SELECT A RENDERING OPTION ###

options = ['to-debug-screen', 'to-numpy-array', 'special-options', 'very-fast']
option = options[0]

print(f'\nUsing rendering option {option}...\n')
parser = argparse.ArgumentParser()
parser.add_argument(
'--render-option',
choices=['to-debug-screen', 'to-numpy-array', 'special-options', 'very-fast'],
help='Select a rendering option from: to-debug-screen, to-numpy-array, special-options, very-fast',
default='to-debug-screen',
)
args = parser.parse_args()
print(f'\nUsing rendering option {args.render_option}...\n')

# if the 'very-fast' option is chosen, set the rendering speed to be unlimited
if option == 'very-fast':
if args.render_option == 'very-fast':
viewer.set_target_rps(None)

for i in range(1000):
Expand All @@ -48,19 +54,19 @@
sim.step()

# step and render to a debug screen
if option == 'to-debug-screen':
if args.render_option == 'to-debug-screen':
viewer.render('screen')

# step and render to a numpy array
# use open cv to visualize output
if option == 'to-numpy-array':
if args.render_option == 'to-numpy-array':
img = viewer.render('img')
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.waitKey(1)
cv2.imshow("Open CV Window", img)

# rendering with more options
if option == 'special-options':
if args.render_option == 'special-options':
img = viewer.render(
'screen',
verbose = True,
Expand All @@ -70,7 +76,8 @@
hide_voxels = False)

# rendering as fast as possible
if option == 'very-fast':
if args.render_option == 'very-fast':
viewer.render('screen', verbose=True)

cv2.destroyAllWindows()
viewer.close()
14 changes: 9 additions & 5 deletions tutorials/visualize_simple_env.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import gym
import gymnasium as gym
from evogym import sample_robot

# import envs from the envs folder and register them
Expand All @@ -10,17 +10,21 @@
body, connections = sample_robot((5,5))

# make the SimpleWalkingEnv using gym.make and with the robot information
env = gym.make('SimpleWalkingEnv-v0', body=body)
env = gym.make(
'SimpleWalkingEnv-v0',
body=body,
render_mode='human',
render_options={'verbose': True}
)
env.reset()

# step the environment for 500 iterations
for i in range(500):

action = env.action_space.sample()
ob, reward, done, info = env.step(action)
env.render(verbose=True)
ob, reward, terminated, truncated, info = env.step(action)

if done:
if terminated or truncated:
env.reset()

env.close()

0 comments on commit bc6212e

Please sign in to comment.