Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to gym v0.26.2 and mujoco_py v2.1.2.14 #17

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ To register that custom environment with Gym:
from gym.envs.registration import register

register(id='SafexpTestEnvironment-v0',
entry_point='safety_gym.envs.mujoco:Engine',
entry_point='safety_gym.envs.safety_mujoco:Engine',
kwargs={'config': config})
```

Expand Down
436 changes: 248 additions & 188 deletions safety_gym/envs/engine.py

Large diffs are not rendered by default.

File renamed without changes.
8 changes: 3 additions & 5 deletions safety_gym/envs/suite.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
#!/usr/bin/env python
import numpy as np
from copy import deepcopy
from string import capwords
from gym.envs.registration import register
import numpy as np


VERSION = 'v0'
MAX_EPISODE_STEPS = 1000

ROBOT_NAMES = ('Point', 'Car', 'Doggo')
ROBOT_XMLS = {name: f'xmls/{name.lower()}.xml' for name in ROBOT_NAMES}
Expand Down Expand Up @@ -70,7 +67,8 @@ def register(self, name='', config={}):
reg_config.update(robot_config)
reg_config.update(config)
register(id=env_name,
entry_point='safety_gym.envs.mujoco:Engine',
entry_point='safety_gym.envs.safety_mujoco:Engine',
max_episode_steps=MAX_EPISODE_STEPS,
kwargs={'config': reg_config})
if MAKE_VISION_ENVIRONMENTS:
# Vision: note, these environments are experimental! Correct behavior not guaranteed
Expand Down
42 changes: 22 additions & 20 deletions safety_gym/envs/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
from copy import deepcopy
from collections import OrderedDict
from mujoco_py import const, load_model_from_path, load_model_from_xml, MjSim, MjViewer, MjRenderContextOffscreen

from typing import Optional
import safety_gym
import sys

'''
Tools that allow the Safety Gym Engine to interface to MuJoCo.
Expand Down Expand Up @@ -61,19 +60,20 @@ class World:
'objects': {}, # map from name -> object dict
# Geoms -- similar to objects, but they are immovable and fixed in the scene.
'geoms': {}, # map from name -> geom dict
# Mocaps -- mocap objects which are used to control other objects
'mocaps': {},
# Mockups -- mockup objects which are used to control other objects
'mockups': {},

# Determine whether we create render contexts
'observe_vision': False,
}

def __init__(self, config={}, render_context=None):
def __init__(self, config={}, render_mode: Optional[str] = None, render_context=None):
''' config - JSON string or dict of configuration. See self.parse() '''
self.parse(config) # Parse configuration
self.first_reset = True
self.viewer = None
self.render_context = render_context
self.render_mode = render_mode
self.update_viewer_sim = False
self.robot = Robot(self.robot_base)

Expand Down Expand Up @@ -173,6 +173,7 @@ def build(self):
cameras = xmltodict.parse('''<b>
<camera name="fixednear" pos="0 -2 2" zaxis="0 -1 1"/>
<camera name="fixedfar" pos="0 -5 5" zaxis="0 -1 1"/>
<camera name="fixedfurthest" pos="0 -8 8" zaxis="0 -1 1"/>
</b>''')
worldbody['camera'] = cameras['b']['camera']

Expand Down Expand Up @@ -237,27 +238,27 @@ def build(self):
# Append new body to world, making it a list optionally
# Add the object to the world
worldbody['body'].append(body['body'])
# Add mocaps to the XML dictionary
for name, mocap in self.mocaps.items():
# Mocap names are suffixed with 'mocap'
assert mocap['name'] == name, f'Inconsistent {name} {object}'
assert name.replace('mocap', 'obj') in self.objects, f'missing object for {name}'
# Add mockups to the XML dictionary
for name, mockup in self.mockups.items():
# Mockup names are suffixed with 'mockup'
assert mockup['name'] == name, f'Inconsistent {name} {object}'
assert name.replace('mockup', 'obj') in self.objects, f'missing object for {name}'
# Add the object to the world
mocap = mocap.copy() # don't modify original object
mocap['quat'] = rot2quat(mocap['rot'])
mockup = mockup.copy() # don't modify original object
mockup['quat'] = rot2quat(mockup['rot'])
body = xmltodict.parse('''
<body name="{name}" mocap="true">
<body name="{name}" mockup="true">
<geom name="{name}" type="{type}" size="{size}" rgba="{rgba}"
pos="{pos}" quat="{quat}" contype="0" conaffinity="0" group="{group}"/>
</body>
'''.format(**{k: convert(v) for k, v in mocap.items()}))
'''.format(**{k: convert(v) for k, v in mockup.items()}))
worldbody['body'].append(body['body'])
# Add weld to equality list
mocap['body1'] = name
mocap['body2'] = name.replace('mocap', 'obj')
mockup['body1'] = name
mockup['body2'] = name.replace('mockup', 'obj')
weld = xmltodict.parse('''
<weld name="{name}" body1="{body1}" body2="{body2}" solref=".02 1.5"/>
'''.format(**{k: convert(v) for k, v in mocap.items()}))
'''.format(**{k: convert(v) for k, v in mockup.items()}))
equality['weld'].append(weld['weld'])
# Add geoms to XML dictionary
for name, geom in self.geoms.items():
Expand Down Expand Up @@ -313,8 +314,9 @@ def reset(self, build=True):
# set flag so that renderer knows to update sim
self.update_viewer_sim = True

def render(self, mode='human'):
def render(self):
''' Render the environment to the screen '''
mode = self.render_mode
if self.viewer is None:
self.viewer = MjViewer(self.sim)
# Turn all the geom groups on
Expand Down Expand Up @@ -401,7 +403,7 @@ def __init__(self, path):
elif sensor_type == const.SENS_JOINTVEL:
self.hinge_vel_names.append(name)
else:
t = self.sim.model.sensor_type[i]
t = self.sim.model.sensor_type[id]
raise ValueError('Unrecognized sensor type {} for joint'.format(t))
elif joint_type == const.JNT_BALL:
if sensor_type == const.SENS_BALLQUAT:
Expand All @@ -412,5 +414,5 @@ def __init__(self, path):
# Adding slide joints is trivially easy in code,
# but this removes one of the good properties about our observations.
# (That we are invariant to relative whole-world transforms)
# If slide joints are added we sould ensure this stays true!
# If slide joints are added we should ensure this stays true!
raise ValueError('Slide joints in robots not currently supported')
34 changes: 0 additions & 34 deletions safety_gym/random_agent.py

This file was deleted.

2 changes: 1 addition & 1 deletion safety_gym/xmls/point.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
</sensor>
<actuator>
<motor gear="0.3 0 0 0 0 0" site="robot" name="x"/>
<velocity gear="0.3" jointinparent="z" name="z"/>
<motor gear="0 0 0 0 0 0.1" site="robot" name="rz"/>
</actuator>
</mujoco>
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
name='safety_gym',
packages=['safety_gym'],
install_requires=[
'gym~=0.15.3',
'gym>=0.26.0',
'joblib~=0.14.0',
'mujoco_py==2.0.2.7',
'numpy~=1.17.4',
'mujoco_py<2.2,>= 2.1',
'numpy>=1.22.3',
'xmltodict~=0.12.0',
],
)