World-Action-Verifier / src /envs /robodesk.py
ffeng1017's picture
WAV interactive demo (ZeroGPU)
23a59ea verified
Raw
History Blame Contribute Delete
4.32 kB
import absl.logging
absl.logging.set_verbosity(absl.logging.ERROR)
import numpy as np
import gymnasium as gym
from dm_control import mujoco
import robodesk
ROBODESK_TASKS = {
"rd-open-slide": dict(
env="open_slide",
max_episode_steps=100,
),
"rd-open-drawer": dict(
env="open_drawer",
max_episode_steps=100,
),
"rd-stack": dict(
env="stack",
max_episode_steps=100,
),
"rd-upright-block-off-table": dict(
env="upright_block_off_table",
max_episode_steps=100,
),
"rd-flat-block-in-bin": dict(
env="flat_block_in_bin",
max_episode_steps=100,
),
"rd-lift-upright-block": dict(
env="lift_upright_block",
max_episode_steps=100,
),
"rd-lift-ball": dict(
env="lift_ball",
max_episode_steps=100,
),
"rd-ball-off-table": dict(
env="ball_off_table",
max_episode_steps=100,
),
"rd-ball-in-bin": dict(
env="ball_in_bin",
max_episode_steps=100,
),
"rd-push-red": dict(
env="push_red",
max_episode_steps=100,
),
"rd-push-green": dict(
env="push_green",
max_episode_steps=100,
),
"rd-push-blue": dict(
env="push_blue",
max_episode_steps=100,
),
}
class RoboDeskWrapper(gym.Wrapper):
def __init__(self, env, cfg):
super().__init__(env)
self.env = env
self.cfg = cfg
obs_dim = sum(space.shape[0] for k, space in env.observation_space.spaces.items() if k != 'image')
if self.cfg.obs == 'state':
self.observation_space = gym.spaces.Box(low=-np.inf, high=np.inf, shape=(obs_dim,), dtype=np.float32)
elif self.cfg.obs == 'rgb':
self.observation_space = gym.spaces.Dict({
'rgb': gym.spaces.Box(
low=0, high=255, shape=(3, self.cfg.render_size, self.cfg.render_size), dtype=np.uint8),
'state': gym.spaces.Box(low=-np.inf, high=np.inf, shape=(obs_dim,), dtype=np.float32)
})
self.action_space = env.action_space
self.max_episode_steps = env.episode_length
def render(mode='rgb_array', resize=True):
# _get_obs calls render with resize=True
assert mode == 'rgb_array', "Only 'rgb_array' mode is supported"
if resize and self.cfg.obs != 'rgb': # Skip rendering
return None
params = {'distance': 1.4, 'azimuth': 90, 'elevation': -60,
'crop_box': (16.75, 25.0, 105.0, 88.75), 'size': self.cfg.render_size}
camera = mujoco.Camera(
physics=self.env.physics, height=params['size'],
width=params['size'], camera_id=-1)
camera._render_camera.distance = params['distance']
camera._render_camera.azimuth = params['azimuth']
camera._render_camera.elevation = params['elevation']
camera._render_camera.lookat[:] = [0, 0.535, 1.1]
image = camera.render(depth=False, segmentation=False)
camera._scene.free()
return image
self.env.render = render
def _extract_info(self, info):
success = self.env.reward_functions[ROBODESK_TASKS[self.cfg.task]['env']]('success')
info = {
'terminated': info.get('terminated', False),
'truncated': info.get('truncated', False),
'success': float(success),
}
info['score'] = info['success']
return info
def _flatten(self, obs):
return np.concatenate([obs[k].flatten() for k in self.env.observation_space.spaces if k != 'image'], dtype=np.float32)
def get_observation(self, obs):
if self.cfg.obs == 'rgb':
return {'state': self._flatten(obs), 'rgb': self.render().copy().transpose(2, 0, 1)}
return self._flatten(obs)
def reset(self, **kwargs):
self.env.reset()
obs, _, _, info = self.env.step(np.zeros(self.env.action_space.shape, dtype=np.float32))
return self.get_observation(obs), self._extract_info(info)
def step(self, action):
obs, reward, truncated, info = self.env.step(action.copy())
info['truncated'] = truncated
return self.get_observation(obs), reward, False, truncated, self._extract_info(info)
@property
def unwrapped(self):
return self.env.unwrapped
def render(self, *args, **kwargs):
return self.env.render(resize=False)
def close(self):
self.env.close()
def make_env(cfg):
"""
Make RoboDesk environment.
"""
if cfg.task not in ROBODESK_TASKS:
raise ValueError('Unknown task:', cfg.task)
env = robodesk.RoboDesk(
task=ROBODESK_TASKS[cfg.task]['env'],
reward='dense',
action_repeat=10,
episode_length=10*ROBODESK_TASKS[cfg.task]['max_episode_steps']+1,
image_size=cfg.render_size if cfg.obs == 'rgb' else 1,
)
env = RoboDeskWrapper(env, cfg)
return env