Skip to content
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
20 changes: 13 additions & 7 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,23 @@ It is common to run into issues when installing **robosuite** on a Windows machi

Within the MuJoCo package, there should be a file called `mujoco.dll`. If you installed robosuite using pip, copy and paste this file into `anaconda3\envs\{your env name}\Lib\site-packages\robosuite\utils `. If you installed robosuite from source, copy and paste this file directly into `robosuite\utils`.

4. You may also get an `EGL` issue. If this happens, please go into `robosuite\utils\binding_utils.py` (either in site-packages or in cloned repository depending on whether you installed from pip or source) and change `"egl"` to `"wgl"` at line 43. It should look like this:
4. If you need a non-default MuJoCo render backend, set `MUJOCO_GL` before importing robosuite. robosuite now honors an explicit `MUJOCO_GL` value instead of overwriting it.

```python
if _SYSTEM == "Darwin":
os.environ["MUJOCO_GL"] = "cgl"
else:
os.environ["MUJOCO_GL"] = "wgl"
Common examples:

```sh
# Windows
set MUJOCO_GL=wgl

# Linux GPU / headless EGL
export MUJOCO_GL=egl

# Linux CPU under xvfb-run
xvfb-run -a env MUJOCO_GL=glfw python robosuite/demos/demo_random_action.py
```

5. Test your **robosuite** installation by running

```sh
$ python robosuite/demos/demo_random_action.py
```
```
11 changes: 2 additions & 9 deletions robosuite/utils/binding_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import subprocess

import robosuite.macros as macros
from robosuite.utils.gl_backend import configure_mujoco_gl_backend

_SYSTEM = platform.system()
if _SYSTEM == "Windows":
Expand All @@ -34,15 +35,7 @@
MUJOCO_EGL_DEVICE_ID in CUDA_VISIBLE_DEVICES
), "MUJOCO_EGL_DEVICE_ID needs to be set to one of the device id specified in CUDA_VISIBLE_DEVICES"

if macros.MUJOCO_GPU_RENDERING and os.environ.get("MUJOCO_GL", None) not in ["osmesa", "glx"]:
# If gpu rendering is specified in macros, then we enforce gpu
# option for rendering
if _SYSTEM == "Darwin":
os.environ["MUJOCO_GL"] = "cgl"
elif _SYSTEM == "Windows":
os.environ["MUJOCO_GL"] = "wgl"
else:
os.environ["MUJOCO_GL"] = "egl"
configure_mujoco_gl_backend(macros, system=_SYSTEM)
_MUJOCO_GL = os.environ.get("MUJOCO_GL", "").lower().strip()


Expand Down
56 changes: 56 additions & 0 deletions robosuite/utils/gl_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from __future__ import annotations

import os
import platform
from typing import Any, MutableMapping


def _normalize_backend(value: str | None) -> str | None:
if value is None:
return None
backend = value.strip().lower()
return backend or None


def platform_default_backend(system: str | None = None) -> str:
system_name = platform.system() if system is None else system
if system_name == "Darwin":
return "cgl"
if system_name == "Windows":
return "wgl"
return "egl"


def resolve_mujoco_gl_backend(
macros_module: Any,
*,
environ: MutableMapping[str, str] | None = None,
system: str | None = None,
) -> str:
environ = os.environ if environ is None else environ

explicit_backend = _normalize_backend(environ.get("MUJOCO_GL"))
if explicit_backend is not None:
return explicit_backend

if getattr(macros_module, "MUJOCO_GPU_RENDERING", False):
return platform_default_backend(system=system)

return ""


def configure_mujoco_gl_backend(
macros_module: Any,
*,
environ: MutableMapping[str, str] | None = None,
system: str | None = None,
) -> str:
environ = os.environ if environ is None else environ
backend = resolve_mujoco_gl_backend(
macros_module,
environ=environ,
system=system,
)
if backend and _normalize_backend(environ.get("MUJOCO_GL")) is None:
environ["MUJOCO_GL"] = backend
return backend
90 changes: 90 additions & 0 deletions tests/test_renderers/test_gl_backend_selection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import os
import platform
import subprocess
import sys
from pathlib import Path
from types import SimpleNamespace

from robosuite.utils.gl_backend import configure_mujoco_gl_backend, resolve_mujoco_gl_backend

REPO_ROOT = Path(__file__).resolve().parents[2]


def _macros(**kwargs):
values = {
"MUJOCO_GPU_RENDERING": True,
}
values.update(kwargs)
return SimpleNamespace(**values)


def _run_binding_utils_probe(*, env_updates=None, unset=None):
env = os.environ.copy()
existing_pythonpath = env.get("PYTHONPATH")
env["PYTHONPATH"] = (
str(REPO_ROOT)
if not existing_pythonpath
else str(REPO_ROOT) + os.pathsep + existing_pythonpath
)

if unset is not None:
for key in unset:
env.pop(key, None)

if env_updates is not None:
env.update(env_updates)

result = subprocess.run(
[sys.executable, "-c", "import os, robosuite; print(os.environ.get('MUJOCO_GL', ''))"],
cwd=REPO_ROOT,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
check=True,
)
return result.stdout.strip().splitlines()[-1]


def test_explicit_env_backend_is_preserved():
environ = {"MUJOCO_GL": "glfw"}

backend = configure_mujoco_gl_backend(_macros(), environ=environ, system="Linux")

assert backend == "glfw"
assert environ["MUJOCO_GL"] == "glfw"


def test_linux_gpu_default_remains_egl():
backend = resolve_mujoco_gl_backend(
_macros(MUJOCO_GPU_RENDERING=True),
environ={},
system="Linux",
)

assert backend == "egl"


def test_gpu_default_is_empty_when_gpu_rendering_is_disabled():
backend = resolve_mujoco_gl_backend(
_macros(MUJOCO_GPU_RENDERING=False),
environ={},
system="Linux",
)

assert backend == ""


def test_binding_utils_import_preserves_explicit_env():
resolved_backend = _run_binding_utils_probe(env_updates={"MUJOCO_GL": "glfw"})

assert resolved_backend == "glfw"


def test_binding_utils_import_defaults_to_egl_on_linux():
if platform.system() != "Linux":
return

resolved_backend = _run_binding_utils_probe(unset={"MUJOCO_GL"})

assert resolved_backend == "egl"