Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions .appveyor.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ cymj.c
*.c
*.so
.python-version
/build
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ RUN curl -o /usr/local/bin/patchelf https://s3-us-west-2.amazonaws.com/openai-sc
ENV LANG C.UTF-8

RUN mkdir -p /root/.mujoco \
&& wget https://www.roboti.us/download/mjpro150_linux.zip -O mujoco.zip \
&& wget https://www.roboti.us/download/mujoco200_linux.zip -O mujoco.zip \
&& unzip mujoco.zip -d /root/.mujoco \
&& mv /root/.mujoco/mujoco200_linux /root/.mujoco/mujoco200 \
&& rm mujoco.zip
COPY ./mjkey.txt /root/.mujoco/
ENV LD_LIBRARY_PATH /root/.mujoco/mjpro150/bin:${LD_LIBRARY_PATH}
ENV LD_LIBRARY_PATH /root/.mujoco/mujoco200/bin:${LD_LIBRARY_PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib64:${LD_LIBRARY_PATH}

COPY vendor/Xdummy /usr/local/bin/Xdummy
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ cirra:
#
# Gather all *.so files.
upload:
test -f ./mujoco_py/generated/cymj_$(VERSION)_$(PYTHON_VERSION)_linuxcpuextensionbuilder.so || exit -1
test -f ./mujoco_py/generated/cymj_$(VERSION)_$(PYTHON_VERSION)_linuxgpuextensionbuilder.so || exit -1
# Commented out for now, binary distributions seem not to work very well
# test -f ./mujoco_py/generated/cymj_$(VERSION)_$(PYTHON_VERSION)_linuxcpuextensionbuilder.so || exit -1
# test -f ./mujoco_py/generated/cymj_$(VERSION)_$(PYTHON_VERSION)_linuxgpuextensionbuilder.so || exit -1
rm -rf dist
python setup.py sdist
twine upload dist/*
Expand Down
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

# mujoco-py [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat)](https://openai.github.io/mujoco-py/build/html/index.html) [![Build Status](https://travis-ci.org/openai/mujoco-py.svg?branch=master)](https://travis-ci.org/openai/mujoco-py)

[MuJoCo](http://mujoco.org/) is a physics engine for detailed, efficient rigid body simulations with contacts. `mujoco-py` allows using MuJoCo from Python 3.
[MuJoCo](http://mujoco.org/) is a physics engine for detailed, efficient rigid body simulations with contacts.
`mujoco-py` allows using MuJoCo from Python 3.

This library has been updated to be compatible with MuJoCo version 2.0 released on 10/1/2018.


## Synopsis

Expand All @@ -15,33 +19,32 @@ The following platforms are currently supported:

The following platforms are DEPRECATED and unsupported:

- Windows support is DEPRECATED and will be removed soon. One known good past version is [1.50.1.68](https://github.com/openai/mujoco-py/blob/9ea9bb000d6b8551b99f9aa440862e0c7f7b4191/README.md#requirements).
- Windows support has been DEPRECATED and removed in [2.0.2.0]. One known good past version is [1.50.1.68](https://github.com/openai/mujoco-py/blob/9ea9bb000d6b8551b99f9aa440862e0c7f7b4191/README.md#requirements).
- Python 2 has been DEPRECATED and removed in [1.50.1.0](https://github.com/openai/mujoco-py/releases/tag/1.50.1.0). Python 2 users can stay on the [`0.5` branch](https://github.com/openai/mujoco-py/tree/0.5). The latest release there is [`0.5.7`](https://github.com/openai/mujoco-py/releases/tag/0.5.7) which can be installed with `pip install mujoco-py==0.5.7`.

### Install MuJoCo

1. Obtain a 30-day free trial on the [MuJoCo website](https://www.roboti.us/license.html)
or free license if you are a student.
The license key will arrive in an email with your username and password.
2. Download the MuJoCo version 1.50 binaries for
[Linux](https://www.roboti.us/download/mjpro150_linux.zip),
[OSX](https://www.roboti.us/download/mjpro150_osx.zip), or
[Windows](https://www.roboti.us/download/mjpro150_win64.zip).
3. Unzip the downloaded `mjpro150` directory into `~/.mujoco/mjpro150`,
2. Download the MuJoCo version 2.0 binaries for
[Linux](https://www.roboti.us/download/mujoco200_linux.zip) or
[OSX](https://www.roboti.us/download/mujoco200_macos.zip).
3. Unzip the downloaded `mujoco200` directory into `~/.mujoco/mujoco200`,
and place your license key (the `mjkey.txt` file from your email)
at `~/.mujoco/mjkey.txt`.

If you want to specify a nonstandard location for the key and package,
use the env variables `MUJOCO_PY_MJKEY_PATH` and `MUJOCO_PY_MJPRO_PATH`.
use the env variables `MUJOCO_PY_MJKEY_PATH` and `MUJOCO_PY_MUJOCO_PATH`.

### Install and use `mujoco-py`
To include `mujoco-py` in your own package, add it to your requirements like so:
```
mujoco-py<1.50.2,>=1.50.1
mujoco-py<2.1,>=2.0
```
To play with `mujoco-py` interactively, follow these steps:
```
$ pip3 install -U 'mujoco-py<1.50.2,>=1.50.1'
$ pip3 install -U 'mujoco-py<2.1,>=2.0'
$ python3
import mujoco_py
import os
Expand Down Expand Up @@ -77,7 +80,7 @@ MuJoCo ships with its own copy of this library, which can be used during install

Add the path to the mujoco bin directory to your dynamic loader:

LD_LIBRARY_PATH=$HOME/.mujoco/mjpro150/bin pip install mujoco-py
LD_LIBRARY_PATH=$HOME/.mujoco/mujoco200/bin pip install mujoco-py

This is particularly useful on Ubuntu 14.04, which does not have a GLFW package.

Expand Down Expand Up @@ -124,3 +127,4 @@ This is somewhat dependent on internal OpenAI infrastructure at the moment, but
- Jonathan Ho
- Peter Welinder
- Wojciech Zaremba
- Jerry Tworek
5 changes: 3 additions & 2 deletions examples/mjvive.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import numpy as np
import OpenGL.GL as gl
from mujoco_py import functions
from mujoco_py.builder import mjpro_path
from mujoco_py.builder import mujoco_path
from mujoco_py.cymj import (MjRenderContext, MjSim, load_model_from_xml,
PyMjrRect, PyMjvCamera)
from mujoco_py.generated.const import (CAT_ALL, FB_OFFSCREEN, FONT_BIG,
Expand All @@ -37,6 +37,7 @@
class HMD(): # anonymous object we can set fields on
pass


window = None
sim = None
ctx = None
Expand Down Expand Up @@ -156,7 +157,7 @@ def v_render():


if __name__ == '__main__':
filename = os.path.join(mjpro_path, 'model', 'humanoid.xml')
filename = os.path.join(mujoco_path, 'model', 'humanoid.xml')
v_initPre()
initMuJoCo(filename, hmd.width * 2, hmd.height)
v_initPost()
Expand Down
66 changes: 33 additions & 33 deletions mujoco_py/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def get_nvidia_lib_dir():
return paths[-1]


def load_cython_ext(mjpro_path):
def load_cython_ext(mujoco_path):
"""
Loads the cymj Cython extension. This is safe to be called from
multiple processes running on the same machine.
Expand All @@ -62,7 +62,7 @@ def load_cython_ext(mjpro_path):
The easy solution is to `import mujoco_py` _before_ `import glfw`.
''')

lib_path = os.path.join(mjpro_path, "bin")
lib_path = os.path.join(mujoco_path, "bin")
if sys.platform == 'darwin':
Builder = MacExtensionBuilder
elif sys.platform == 'linux':
Expand All @@ -81,7 +81,7 @@ def load_cython_ext(mjpro_path):
else:
raise RuntimeError("Unsupported platform %s" % sys.platform)

builder = Builder(mjpro_path)
builder = Builder(mujoco_path)
cext_so_path = builder.get_so_file_path()

lockpath = os.path.join(os.path.dirname(cext_so_path), 'mujocopy-buildlock')
Expand Down Expand Up @@ -153,7 +153,7 @@ def fix_shared_library(so_file, name, library_path):
subprocess.check_call(['patchelf', '--add-needed', library_path, so_file])


def manually_link_libraries(mjpro_path, raw_cext_dll_path):
def manually_link_libraries(mujoco_path, raw_cext_dll_path):
''' Used to fix mujoco library linking on Mac '''
root, ext = os.path.splitext(raw_cext_dll_path)
final_cext_dll_path = root + '_final' + ext
Expand All @@ -167,12 +167,12 @@ def manually_link_libraries(mjpro_path, raw_cext_dll_path):
tmp_final_cext_dll_path = final_cext_dll_path + '~'
shutil.copyfile(raw_cext_dll_path, tmp_final_cext_dll_path)

mj_bin_path = join(mjpro_path, 'bin')
mj_bin_path = join(mujoco_path, 'bin')

# Fix the rpath of the generated library -- i lost the Stackoverflow
# reference here
from_mujoco_path = '@executable_path/libmujoco150.dylib'
to_mujoco_path = '%s/libmujoco150.dylib' % mj_bin_path
from_mujoco_path = '@executable_path/libmujoco200.dylib'
to_mujoco_path = '%s/libmujoco200.dylib' % mj_bin_path
subprocess.check_call(['install_name_tool',
'-change',
from_mujoco_path,
Expand All @@ -195,20 +195,20 @@ class MujocoExtensionBuilder():

CYMJ_DIR_PATH = abspath(dirname(__file__))

def __init__(self, mjpro_path):
self.mjpro_path = mjpro_path
def __init__(self, mujoco_path):
self.mujoco_path = mujoco_path
python_version = str(sys.version_info.major) + str(sys.version_info.minor)
self.version = '%s_%s_%s' % (get_version(), python_version, self.build_base())
self.extension = Extension(
'mujoco_py.cymj',
sources=[join(self.CYMJ_DIR_PATH, "cymj.pyx")],
include_dirs=[
self.CYMJ_DIR_PATH,
join(mjpro_path, 'include'),
join(mujoco_path, 'include'),
np.get_include(),
],
libraries=['mujoco150'],
library_dirs=[join(mjpro_path, 'bin')],
libraries=['mujoco200'],
library_dirs=[join(mujoco_path, 'bin')],
extra_compile_args=[
'-fopenmp', # needed for OpenMP
'-w', # suppress numpy compilation warnings
Expand Down Expand Up @@ -252,58 +252,58 @@ def get_so_file_path(self):

class WindowsExtensionBuilder(MujocoExtensionBuilder):

def __init__(self, mjpro_path):
super().__init__(mjpro_path)
os.environ["PATH"] += ";" + join(mjpro_path, "bin")
def __init__(self, mujoco_path):
super().__init__(mujoco_path)
os.environ["PATH"] += ";" + join(mujoco_path, "bin")
self.extension.sources.append(self.CYMJ_DIR_PATH + "/gl/dummyshim.c")


class LinuxCPUExtensionBuilder(MujocoExtensionBuilder):

def __init__(self, mjpro_path):
super().__init__(mjpro_path)
def __init__(self, mujoco_path):
super().__init__(mujoco_path)

self.extension.sources.append(
join(self.CYMJ_DIR_PATH, "gl", "osmesashim.c"))
self.extension.libraries.extend(['glewosmesa', 'OSMesa', 'GL'])
self.extension.runtime_library_dirs = [join(mjpro_path, 'bin')]
self.extension.runtime_library_dirs = [join(mujoco_path, 'bin')]

def _build_impl(self):
so_file_path = super()._build_impl()
# Removes absolute paths to libraries. Allows for dynamic loading.
fix_shared_library(so_file_path, 'libmujoco150.so', 'libmujoco150.so')
fix_shared_library(so_file_path, 'libmujoco200.so', 'libmujoco200.so')
fix_shared_library(so_file_path, 'libglewosmesa.so', 'libglewosmesa.so')
return so_file_path


class LinuxGPUExtensionBuilder(MujocoExtensionBuilder):

def __init__(self, mjpro_path):
super().__init__(mjpro_path)
def __init__(self, mujoco_path):
super().__init__(mujoco_path)

self.extension.sources.append(self.CYMJ_DIR_PATH + "/gl/eglshim.c")
self.extension.include_dirs.append(self.CYMJ_DIR_PATH + '/vendor/egl')
self.extension.libraries.extend(['glewegl'])
self.extension.runtime_library_dirs = [join(mjpro_path, 'bin')]
self.extension.runtime_library_dirs = [join(mujoco_path, 'bin')]

def _build_impl(self):
so_file_path = super()._build_impl()
fix_shared_library(so_file_path, 'libOpenGL.so', 'libOpenGL.so.0')
fix_shared_library(so_file_path, 'libEGL.so', 'libEGL.so.1')
fix_shared_library(so_file_path, 'libmujoco150.so', 'libmujoco150.so')
fix_shared_library(so_file_path, 'libmujoco200.so', 'libmujoco200.so')
fix_shared_library(so_file_path, 'libglewegl.so', 'libglewegl.so')
return so_file_path


class MacExtensionBuilder(MujocoExtensionBuilder):

def __init__(self, mjpro_path):
super().__init__(mjpro_path)
def __init__(self, mujoco_path):
super().__init__(mujoco_path)

self.extension.sources.append(self.CYMJ_DIR_PATH + "/gl/dummyshim.c")
self.extension.libraries.extend(['glfw.3'])
self.extension.define_macros = [('ONMAC', None)]
self.extension.runtime_library_dirs = [join(mjpro_path, 'bin')]
self.extension.runtime_library_dirs = [join(mujoco_path, 'bin')]

def _build_impl(self):
if not os.environ.get('CC'):
Expand All @@ -327,7 +327,7 @@ def _build_impl(self):
del os.environ['CC']
else: # User-directed c compiler
so_file_path = super()._build_impl()
return manually_link_libraries(self.mjpro_path, so_file_path)
return manually_link_libraries(self.mujoco_path, so_file_path)


class MujocoException(Exception):
Expand Down Expand Up @@ -467,9 +467,9 @@ def build_callback_fn(function_string, userdata_names=[]):
source_string += '\nuintptr_t __fun = (uintptr_t) fun;'
# Link against mujoco so we can call mujoco functions from within callback
ffibuilder.set_source(name, source_string,
include_dirs=[join(mjpro_path, 'include')],
library_dirs=[join(mjpro_path, 'bin')],
libraries=['mujoco150'])
include_dirs=[join(mujoco_path, 'include')],
library_dirs=[join(mujoco_path, 'bin')],
libraries=['mujoco200'])
# Catch compilation exceptions so we can cleanup partial files in that case
try:
library_path = ffibuilder.compile(verbose=True)
Expand All @@ -478,7 +478,7 @@ def build_callback_fn(function_string, userdata_names=[]):
raise e
# On Mac the MuJoCo library is linked strangely, so we have to fix it here
if sys.platform == 'darwin':
fixed_library_path = manually_link_libraries(mjpro_path, library_path)
fixed_library_path = manually_link_libraries(mujoco_path, library_path)
move(fixed_library_path, library_path) # Overwrite with fixed library
module = load_dynamic_ext(name, library_path)
# Now that the module is loaded into memory, we can actually delete it
Expand All @@ -499,8 +499,8 @@ def activate():
functions.mj_activate(key_path)


mjpro_path, key_path = discover_mujoco()
cymj = load_cython_ext(mjpro_path)
mujoco_path, key_path = discover_mujoco()
cymj = load_cython_ext(mujoco_path)


# Trick to expose all mj* functions from mujoco in mujoco_py.*
Expand Down
Loading