From 90dea1bdfb7053b05acfd6ff7687924ce31ed16a Mon Sep 17 00:00:00 2001 From: Saran Tunyasuvunakool Date: Mon, 4 Apr 2022 13:53:21 +0100 Subject: [PATCH] Version 2.1.4: Switch to GLAD, minor improvements to simulate. PiperOrigin-RevId: 439277749 Change-Id: I741d1c499ae88753338fcc6d141a65e92e13023e --- cmake/ShellTests.cmake | 2 +- doc/APIreference.rst | 28 ++-- doc/changelog.rst | 43 ++++++ doc/programming.rst | 93 +++---------- doc/python.rst | 17 +++ doc/unity.rst | 4 +- include/mjrender.h | 2 +- include/mjvisualize.h | 1 + include/mujoco.h | 22 +-- introspect/enums.py | 5 +- introspect/functions.py | 44 +++--- python/mujoco/CMakeLists.txt | 22 +-- python/mujoco/__init__.py | 73 ++++------ python/mujoco/bindings_test.py | 130 +++++++++--------- python/mujoco/render.cc | 2 +- python/mujoco/render_test.py | 2 +- python/setup.py | 24 ++-- sample/Makefile | 14 +- sample/Makefile.macos | 22 +-- sample/Makefile.windows | 8 +- sample/simulate.cc | 2 +- .../Runtime/Bindings/MujocoBinaryRetriever.cs | 4 +- unity/Runtime/Bindings/MujocoBindings.cs | 4 +- 23 files changed, 270 insertions(+), 298 deletions(-) diff --git a/cmake/ShellTests.cmake b/cmake/ShellTests.cmake index e1a75340..b26b1658 100644 --- a/cmake/ShellTests.cmake +++ b/cmake/ShellTests.cmake @@ -45,7 +45,7 @@ function(add_mujoco_shell_test TEST_NAME TARGET_BINARY) set_property( TEST "${TEST_NAME}" APPEND - PROPERTY ENVIRONMENT "MUJOCO_DLL_DIR=$" + PROPERTY ENVIRONMENT "MUJOCO_DLL_DIR=$" ) endif() endif() diff --git a/doc/APIreference.rst b/doc/APIreference.rst index f8d9fe5c..145048f7 100644 --- a/doc/APIreference.rst +++ b/doc/APIreference.rst @@ -2437,7 +2437,7 @@ mjrContext int charHeightBig; // character heights: big // capabilities - int glewInitialized; // is glew initialized + int glInitialized; // is OpenGL initialized int windowAvailable; // is default/window framebuffer available int windowSamples; // number of samples for default/window framebuffer int windowStereo; // is stereo available for default/window framebuffer @@ -2905,11 +2905,11 @@ mjcb_control fields, their values do not correspond to the current time step. | The control callback is called from within :ref:`mj_forward` and :ref:`mj_step`, just before the controls and applied - forces are needed. When using the RK integrator, it will be called 4 times per step. The alternative way of specifying - controls and applied forces is to set them before mj_step, or use mj_step1 and mj_step2. The latter approach allows - setting the controls after the position and velocity computations have been performed by mj_step1, allowing these - results to be utilized in computing the control (similar to using mjcb_control). However, the only way to change the - controls between sub-steps of the RK integrator is to define the control callback. +forces are needed. When using the RK integrator, it will be called 4 times per step. The alternative way of specifying +controls and applied forces is to set them before ``mj_step``, or use ``mj_step1`` and ``mj_step2``. The latter approach +allows setting the controls after the position and velocity computations have been performed by ``mj_step1``, allowing +these results to be utilized in computing the control (similar to using mjcb_control). However, the only way to change +the controls between sub-steps of the RK integrator is to define the control callback. .. _mjcb_contactfilter: @@ -3411,15 +3411,15 @@ Print internal XML schema as plain text or HTML, with style-padding or `` ` Main simulation ^^^^^^^^^^^^^^^ -| These are the main entry points to the simulator. Most users will only need to call mj_step, which computes everything - and advanced the simulation state by one time step. Controls and applied forces must either be set in advance (in - mjData.ctrl, qfrc_applied and xfrc_applied), or a control callback mjcb_control must be installed which will be called - just before the controls and applied forces are needed. Alternatively, one can use mj_step1 and mj_step2 which break - down the simulation pipeline into computations that are executed before and after the controls are needed; in this way - one can set controls that depend on the results from mj_step1. Keep in mind though that the RK4 solver does not work - with mj_step1/2. +| These are the main entry points to the simulator. Most users will only need to call ``mj_step``, which computes +everything and advanced the simulation state by one time step. Controls and applied forces must either be set in advance +(in mjData.ctrl, qfrc_applied and xfrc_applied), or a control callback mjcb_control must be installed which will be +called just before the controls and applied forces are needed. Alternatively, one can use ``mj_step1`` and ``mj_step2`` +which break down the simulation pipeline into computations that are executed before and after the controls are needed; +in this way one can set controls that depend on the results from ``mj_step1``. Keep in mind though that the RK4 solver +does not work with mj_step1/2. -| mj_forward performs the same computations as mj_step but without the integration. It is useful after loading or +| mj_forward performs the same computations as ``mj_step`` but without the integration. It is useful after loading or resetting a model (to put the entire mjData in a valid state), and also for out-of-order computations that involve sampling or finite-difference approximations. diff --git a/doc/changelog.rst b/doc/changelog.rst index 4a3e75aa..8834b9a5 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -2,6 +2,49 @@ Changelog ========= +Version 2.1.4 (Apr. 4, 2022) +----------------------------- + +General +^^^^^^^ + +1. MuJoCo now uses GLAD to manage OpenGL API access instead of GLEW. On Linux, there is no longer a need to link against + different GL wrangling libraries depending on whether GLX, EGL, or OSMesa is being used. Instead, users can simply + use GLX, EGL, or OSMesa to create a GL context and ``mjr_makeContext`` will detect which one is being used. + +#. Add visualisation for contact frames. This is useful when writing or modifying collision functions, when the actual + direction of the x and y axes of a contact can be important. + +Binary build +^^^^^^^^^^^^ + +3. The ``_nogl`` dynamic library is no longer provided on Linux and Windows. The switch to GLAD allows us to resolve + OpenGL symbols when ``mjr_makeContext`` is called rather than when the library is loaded. As a result, the MuJoCo + library no longer has an explicit dynamic dependency on OpenGL, and can be used on system where OpenGL is not + present. + +Simulate +^^^^^^^^ + +4. Fix a bug in simulate where pressing '[' or ']' when a model is not loaded causes a crash. + +#. Contact frame visualisation is added to the Simulate GUI. + +#. Rename "set key", "reset to key" to "save key" and "load key", respectively. + +#. Change bindings of F6 and F7 from the not very useful "vertical sync" and "busy wait" to the more useful cycling of + frames and labels. + +Bug fixes +^^^^^^^^^ + +8. ``mj_resetData`` zeroes out the ``solver_nnz`` field. + +#. Remove a special branch in ``mju_quat2mat`` for unit quaternions. Previously, ``mju_quat2mat`` skipped all + computation if the real part of the quaternion equals 1.0. For very small angles (e.g. when finite differencing), the + cosine can evaluate to exactly 1.0 at double precision while the sine is still nonzero. + + Version 2.1.3 (Mar. 23, 2022) ----------------------------- diff --git a/doc/programming.rst b/doc/programming.rst index 2a9b628c..9b2080a8 100644 --- a/doc/programming.rst +++ b/doc/programming.rst @@ -12,29 +12,16 @@ be used in C++ programs. MuJoCo is a free product currently distributed as a pre-built dynamic library and will soon be made available as an open-source project. The software distribution contains a compiled version of GLFW which is used in the code samples to -create an OpenGL window and direct user input to it. The Linux distribution also contains compiled versions of GLEW -which is used for OpenGL symbol loading and allow the user to choose between X11, EGL or MESA. For projects where -rendering is not needed, there is a smaller "nogl" library which does not have a dependence on OpenGL. This is suitable -for running on headless servers without video drivers installed. The distribution for each platform contains the -following dynamic libraries: +create an OpenGL window and direct user input to it. The distribution for each platform contains the following dynamic +library: .. code-block:: Text - Windows: mujoco210.dll (stub library: mujoco210.lib) - mujoco210nogl.dll (stub library: mujoco210nogl.lib) - glfw3.dll (stub library: glfw3.lib) + Windows: mujoco.dll (stub library: mujoco.lib) - Linux: mujoco210.so - mujoco210nogl.so - glewXXX.so - glfw.so.3 + Linux: mujoco.so.2.1.4 - macOS: mujoco210.dylib - mujoco210nogl.dylib - glfw.3.dylib - -Note that the software :ref:`version ` number is contained in the library name (and obviously changes with -every release), so for example ``mujoco210`` means version 2.1. + macOS: mujoco.2.1.4.dylib Even though MuJoCo is a single dynamic library with unified C API, it contains several modules, some of which are implemented in C++. We have taken advantage of the convenience of C++ for functionality that is used before the @@ -154,11 +141,6 @@ API. While we encourage users to upgrade to the latest version, we recognize tha especially when other developers release software that relies on MuJoCo. Therefore we have introduced simple mechanisms to help avoid version conflicts, as follows. -As noted above, the version number is contained in the name of the dynamic library, e.g. mujoco210.dll for version 2.1. -Thus if an executable was compiled and linked with version 2.1 and the currently installed MuJoCo version is different, -the dynamic library will not be found. Please avoid the temptation to rename the library so as to fool the dynamic -linker; this is never a good idea. Instead you should obtain the required version of the library. - The situation is more subtle if existing code was developed with a certain version of MuJoCo, and is now being compiled and linked with a different version. If the definitions of the API functions used in that code have changed, either the compiler or the linker will generate errors. But even if the function definitions have not changed, it may @@ -224,55 +206,22 @@ mjcb\_ Using OpenGL ~~~~~~~~~~~~ -The use of MuJoCo's native OpenGL renderer will be explained in :ref:`Rendering`. Here we only cover issues -related to external libraries and resolving dependencies. For projects that do not need rendering, one can use the -"nogl" version of the MuJoCo library. +The use of MuJoCo's native OpenGL renderer will be explained in :ref:`Rendering`. For rendering, MuJoCo uses OpenGL 1.5 +in the compatibility profile with the ``ARB_framebuffer_object`` and ``ARB_vertex_buffer_object`` extensions. OpenGL +symbols are loaded via `GLAD `_ the first time the :ref:`mjr_makeContext` function +is called. This means that the MuJoCo library itself does not have an explicit dependency on OpenGL and can be used +on systems without OpenGL support, as long as ``mjr_`` functions are not called. -For rendering MuJoCo uses OpenGL 1.5 with the ARB_framebuffer_object extension (provided by all modern drivers.) It -also uses GLEW 2.0.0 for loading OpenGL symbols. On Windows and macOS, both GLEW and the OpenGL library (OpenGL32.lib -or OpenGL.framework respectively) are linked with MuJoCo. On these platforms the user does not have to take additional -steps to resolve dependencies. +Applications that use MuJoCo's built-in rendering functionalities are responsible for linking against an appropriate +OpenGL context creation library and for ensuring that there is an OpenGL context that is made current on the running +thread. On Windows and macOS, there is a canonical OpenGL library provided by the operating system. On Linux, MuJoCo +currently supports GLX for rendering to an X11 window, OSMesa for headless software rendering, and EGL for hardware +accelerated headless rendering. -On Linux the situation is more complex, because there are multiple OpenGL implementations and ways to load symbols. -The renderer and linking process are organized so as to allow multiple use cases shown below. libmujoco210.so calls -GLEW and OpenGL functions without linking the corresponding libraries. Users must resolve the dependencies by linking -whatever flavor of GLEW and OpenGL are suitable for their needs. For illustration, see how -:ref:`record.cc ` on Linux is compiled and linked in three different ways (makefile in the sample -directory). - -No OpenGL: link with **libmujoco210nogl**.so - This version of the MuJoCo library is compiled without the renderer, so it does not make any calls to OpenGL or GLEW. - It can be used on compute servers where graphics drivers are not installed. The main header file mujoco.h still - declares the rendering functions (mjr_XXX), but the library does not implement them, therefore calling these - functions from user code will result in unresolved symbols at link time. In the code samples, we use this version of - the library in text-only applications. -X11 OpenGL: link with **libmujoco210**.so, **libglew**.so, **libGL**.so - This is the most common way of using OpenGL on Linux desktop, with X11 for context creation and symbol loading. -OSMESA OpenGL: link with **libmujoco210**.so, **libglewosmesa**.so, **libOSMesa**.so - This can be used for software rendering with the OSMesa library. Note that we are linking a different version of GLEW - here, built with OSMesa support instead of the standard GLX. Ideally users will find a way to avoid software - rendering and use hardware acceleration. But OSMesa is a convenient fall-back option when all else fails. -EGL OpenGL: link with **libmujoco210**.so, **libEGL**.so, **libglewegl**.so, **libOpenGL**.so - This is the key feature for headless rendering. It enables hardware-accelerated OpenGL on servers without X11. User - code must use EGL for context creation, as illustrated in :ref:`record.cc `. libglewegl.so uses EGL to - load OpenGL symbols instead of using GLX. libOpenGL.so is the vendor-independent library which exposes only OpenGL - functionality without introducing a dependence on X11 (as opposed to libGL.so which depends on libGLX.so). NVidia's - drivers provide libOpenGL.so when installed with the "--install-libglvnd" option. libEGL.so can be obtained from Mesa - and is driver-independent (sudo apt-get install libegl1-mesa-dev). - -Finally, instead of using the compiled libglew we have provided, users can compile their own, or link glew.c statically -in their project (it is a single C file). Static linking requires the GLEW_STATIC symbol to be defined. In addition, the -following symbols must be defined when building GLEW 2.0.0 for different use cases: - -:: - - libglew.so: GLEW_NO_GLU - libglewegl.so: GLEW_NO_GLU GLEW_EGL - libgleweomesa.so: GLEW_NO_GLU GLEW_OSMESA - -For headless rendering to work, it is essential to eliminate the dependence on GLU, because otherwise a dependence on -X11 will be introduced via libGLU.so. Note that GLEW can also be built for Mir and Wayland. We have not tested these, -but in theory they should work. +Before version 2.1.4, MuJoCo used GLEW rather than GLAD to manage OpenGL symbols, which required linking against +different GLEW libraries at build time depending on the GL implementation used. In order to avoid having manage OpenGL +dependency when no rendering was required, "nogl" builds of the library was made available. Since OpenGL symbols are +now lazily resolved at runtime after the switch to GLAD, the "nogl" libraries are no longer provided. .. _Sample: @@ -641,7 +590,7 @@ but these are finer points). Instead of relying on a control callback, we could set the control vector ``mjData.ctrl`` directly. Alternatively we could set applied forces as explained in :ref:`state and control `. If we could compute these control- -related quantities before mj_step is called, then the simulation loop for the controlled dynamics (without using a +related quantities before ``mj_step`` is called, then the simulation loop for the controlled dynamics (without using a control callback) would become .. code-block:: C @@ -652,7 +601,7 @@ control callback) would become mj_step(m, d); } -Why would we not be able to compute the controls before mj_step is called? After all, isn't this what causality means? +Why would we not be able to compute the controls before ``mj_step`` is called? After all, isn't this what causality means? The answer is subtle but important, and has to do with the fact that we are simulating in discrete time. The top-level simulation function ``mj_step`` basically does two things: compute the :ref:`forward dynamics ` in continuous time, and then integrate over a time period specified by ``mjModel.opt.timestep``. Forward dynamics computes the diff --git a/doc/python.rst b/doc/python.rst index 97065ab9..b055407b 100644 --- a/doc/python.rst +++ b/doc/python.rst @@ -101,6 +101,23 @@ Functions This allows for some thread-based parallelism, however users should bear in mind that the GIL is only released for the duration of the MuJoCo C function itself, and not during the execution of any other Python code. + .. note:: + One place where the bindings do offer added functionality is the top-level :ref:`mj_step` function. Since it is + often called in a loop, we have added an additional ``nstep`` argument, indicating how many times the underlying + :ref:`mj_step` should be called. If not specified, ``nstep`` takes the default value of 1. The following two code + snippets perform the same computation, but the first one does so without acquiring the GIL in between subsequent + physics steps: + + .. code-block:: python + + mj_step(model, data, nstep=20) + + .. code-block:: python + + for _ in range(20): + mj_step(model, data) + + Enums and constants =================== diff --git a/doc/unity.rst b/doc/unity.rst index 8633b78d..24b62f14 100644 --- a/doc/unity.rst +++ b/doc/unity.rst @@ -29,14 +29,14 @@ _____ The MuJoCo app needs to be run at least once before the native library can be used, in order to register the library as a trusted binary. Then, copy the dynamic library file from -``/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.framework/Versions/Current/libmujoco.2.1.1.dylib`` (it can be +``/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.framework/Versions/Current/libmujoco.2.1.4.dylib`` (it can be found by browsing the contents of ``MuJoCo.app``) and rename it as ``mujoco.dylib``. Linux _____ Expand the ``tar.gz`` archive to ``~/.mujoco``. Then copy the dynamic library from -``~/.mujoco/mujoco-2.1.1/lib/libmujoco_nogl.so.2.1.1`` (note the ``_nogl`` suffix) and rename it as ``libmujoco.so``. +``~/.mujoco/mujoco-2.1.4/lib/libmujoco.so.2.1.4`` and rename it as ``libmujoco.so``. Windows _______ diff --git a/include/mjrender.h b/include/mjrender.h index 05d01935..de15fc9d 100644 --- a/include/mjrender.h +++ b/include/mjrender.h @@ -141,7 +141,7 @@ struct mjrContext_ { // custom OpenGL context int charHeightBig; // character heights: big // capabilities - int glewInitialized; // is glew initialized + int glInitialized; // is OpenGL initialized int windowAvailable; // is default/window framebuffer available int windowSamples; // number of samples for default/window framebuffer int windowStereo; // is stereo available for default/window framebuffer diff --git a/include/mjvisualize.h b/include/mjvisualize.h index 879f4f7e..b1cd6859 100644 --- a/include/mjvisualize.h +++ b/include/mjvisualize.h @@ -88,6 +88,7 @@ typedef enum mjtFrame_ { // frame visualization mjFRAME_SITE, // site frames mjFRAME_CAMERA, // camera frames mjFRAME_LIGHT, // light frames + mjFRAME_CONTACT, // contact frames mjFRAME_WORLD, // world frame mjNFRAME // number of visualization frames diff --git a/include/mujoco.h b/include/mujoco.h index 5de35744..7e262082 100644 --- a/include/mujoco.h +++ b/include/mujoco.h @@ -24,7 +24,7 @@ extern "C" { #endif // header version; should match the library version as returned by mj_version() -#define mjVERSION_HEADER 213 +#define mjVERSION_HEADER 214 // needed to define size_t, fabs and log10 #include "stdlib.h" @@ -79,21 +79,12 @@ MJAPI extern const char* mjVISSTRING[mjNVISFLAG][3]; MJAPI extern const char* mjRNDSTRING[mjNRNDFLAG][3]; -//---------------------------------- Activation ---------------------------------------------------- - -// Return 1 (for backward compatibility). -MJAPI int mj_activate(const char* filename); - -// Do nothing (for backward compatibility). -MJAPI void mj_deactivate(void); - - //---------------------------------- Virtual file system ------------------------------------------- // Initialize VFS to empty (no deallocation). MJAPI void mj_defaultVFS(mjVFS* vfs); -// Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: not found on disk. +// Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: failed to load. MJAPI int mj_addFileVFS(mjVFS* vfs, const char* directory, const char* filename); // Make empty file in VFS, return 0: success, 1: full, 2: repeated name. @@ -768,6 +759,15 @@ MJAPI void mj_warning(mjData* d, int warning, int info); MJAPI void mju_writeLog(const char* type, const char* msg); +//---------------------------------- Activation ---------------------------------------------------- + +// Return 1 (for backward compatibility). +MJAPI int mj_activate(const char* filename); + +// Do nothing (for backward compatibility). +MJAPI void mj_deactivate(void); + + //---------------------------------- Standard math ------------------------------------------------- #define mjMAX(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/introspect/enums.py b/introspect/enums.py index 05b881b2..288fe6c8 100755 --- a/introspect/enums.py +++ b/introspect/enums.py @@ -569,8 +569,9 @@ ENUMS: Mapping[str, EnumDecl] = dict([ ('mjFRAME_SITE', 3), ('mjFRAME_CAMERA', 4), ('mjFRAME_LIGHT', 5), - ('mjFRAME_WORLD', 6), - ('mjNFRAME', 7), + ('mjFRAME_CONTACT', 6), + ('mjFRAME_WORLD', 7), + ('mjNFRAME', 8), ]), )), ('mjtVisFlag', diff --git a/introspect/functions.py b/introspect/functions.py index e0a3b009..1cc65883 100644 --- a/introspect/functions.py +++ b/introspect/functions.py @@ -26,27 +26,6 @@ from .ast_nodes import PointerType from .ast_nodes import ValueType FUNCTIONS: Mapping[str, FunctionDecl] = dict([ - ('mj_activate', - FunctionDecl( - name='mj_activate', - return_type=ValueType(name='int'), - parameters=( - FunctionParameterDecl( - name='filename', - type=PointerType( - inner_type=ValueType(name='char', is_const=True), - ), - ), - ), - doc='Return 1 (for backward compatibility).', - )), - ('mj_deactivate', - FunctionDecl( - name='mj_deactivate', - return_type=ValueType(name='void'), - parameters=(), - doc='Do nothing (for backward compatibility).', - )), ('mj_defaultVFS', FunctionDecl( name='mj_defaultVFS', @@ -85,7 +64,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), ), ), - doc='Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: not found on disk.', # pylint: disable=line-too-long + doc='Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: failed to load.', # pylint: disable=line-too-long )), ('mj_makeEmptyFileVFS', FunctionDecl( @@ -4738,6 +4717,27 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Write [datetime, type: message] to MUJOCO_LOG.TXT.', )), + ('mj_activate', + FunctionDecl( + name='mj_activate', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='filename', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Return 1 (for backward compatibility).', + )), + ('mj_deactivate', + FunctionDecl( + name='mj_deactivate', + return_type=ValueType(name='void'), + parameters=(), + doc='Do nothing (for backward compatibility).', + )), ('mju_zero3', FunctionDecl( name='mju_zero3', diff --git a/python/mujoco/CMakeLists.txt b/python/mujoco/CMakeLists.txt index 1ee5c8e4..825b89f8 100644 --- a/python/mujoco/CMakeLists.txt +++ b/python/mujoco/CMakeLists.txt @@ -55,7 +55,7 @@ include(FindOrFetch) # ==================== MUJOCO LIBRARY ========================================== if(NOT TARGET mujoco) - find_library(MUJOCO_LIBRARY mujoco mujoco.2.1.3 HINTS ${MUJOCO_LIBRARY_DIR} REQUIRED) + find_library(MUJOCO_LIBRARY mujoco mujoco.2.1.4 HINTS ${MUJOCO_LIBRARY_DIR} REQUIRED) find_path(MUJOCO_INCLUDE mujoco.h HINTS ${MUJOCO_INCLUDE_DIR} REQUIRED) message("MuJoCo is at ${MUJOCO_LIBRARY}") message("MuJoCo headers are at ${MUJOCO_INCLUDE}") @@ -152,7 +152,7 @@ else() GIT_REPO https://github.com/pybind/pybind11 GIT_TAG - 08ea85b0ac0d4d46ac081ff24f481b41322d7159 + a8f1a5567608f346bdba293b3d062a288ee16cd4 TARGETS pybind11::pybind11_headers EXCLUDE_FROM_ALL @@ -257,12 +257,7 @@ macro(mujoco_pybind11_module name) @rpath/$ -add_rpath @loader_path $ ) elseif(NOT WIN32) - add_custom_command( - TARGET ${name} - POST_BUILD - COMMAND patchelf --remove-needed $ - $ - ) + set_target_properties(${name} PROPERTIES INSTALL_RPATH $ORIGIN BUILD_WITH_INSTALL_RPATH TRUE) endif() endmacro() @@ -347,17 +342,6 @@ set(LIBRARIES_FOR_WHEEL "$" "$" ) -if(NOT APPLE) - set(LIBRARIES_FOR_WHEEL ${LIBRARIES_FOR_WHEEL} $) -endif() -if(NOT (APPLE OR WIN32)) - set(LIBRARIES_FOR_WHEEL - ${LIBRARIES_FOR_WHEEL} - "$" - "$" - "$" - ) -endif() if(MUJOCO_PYTHON_MAKE_WHEEL) add_custom_target( diff --git a/python/mujoco/__init__.py b/python/mujoco/__init__.py index ea0e3e6d..a2c192d5 100644 --- a/python/mujoco/__init__.py +++ b/python/mujoco/__init__.py @@ -15,69 +15,44 @@ """Python bindings for MuJoCo.""" import ctypes +import ctypes.util import os import platform import subprocess -HEADERS_DIR = os.path.join(os.path.dirname(__file__), 'include') - -_MUJOCO_GL_ENABLE = ('enable', 'enabled', 'on', 'true', '1' , '') -_MUJOCO_GL_DISABLE = ('disable', 'disabled', 'off', 'false', '0') -_MUJOCO_GL = os.environ.get('MUJOCO_GL', '').lower().strip() -_MUJOCO_GL_IS_VALID = True - _SYSTEM = platform.system() -if _SYSTEM == 'Linux': - libglew_name = None - if _MUJOCO_GL in _MUJOCO_GL_ENABLE + ('glfw', 'glx'): - libglew_name = 'libglew.so' - elif _MUJOCO_GL == 'egl': - libglew_name = 'libglewegl.so' - elif _MUJOCO_GL == 'osmesa': - libglew_name = 'libglewosmesa.so' - elif _MUJOCO_GL not in _MUJOCO_GL_DISABLE: - _MUJOCO_GL_IS_VALID = False - if libglew_name is not None: - ctypes.CDLL(os.path.join(os.path.dirname(__file__), libglew_name), - ctypes.RTLD_GLOBAL) - ctypes.CDLL( - os.path.join(os.path.dirname(__file__), 'libmujoco.so.2.1.3'), - ctypes.RTLD_GLOBAL) - else: - ctypes.CDLL( - os.path.join(os.path.dirname(__file__), 'libmujoco_nogl.so.2.1.3'), - ctypes.RTLD_GLOBAL) -elif _SYSTEM == 'Windows': - if _MUJOCO_GL in _MUJOCO_GL_ENABLE + ('glfw', 'wgl'): - ctypes.WinDLL(os.path.join(os.path.dirname(__file__), 'mujoco.dll')) - elif _MUJOCO_GL in _MUJOCO_GL_DISABLE: - ctypes.WinDLL(os.path.join(os.path.dirname(__file__), 'mujoco_nogl.dll')) - else: - _MUJOCO_GL_IS_VALID = False - -if not _MUJOCO_GL_IS_VALID: - raise RuntimeError( - f'invalid value for environment variable MUJOCO_GL: {_MUJOCO_GL}') +if _SYSTEM == 'Windows': + ctypes.WinDLL(os.path.join(os.path.dirname(__file__), 'mujoco.dll')) from mujoco._callbacks import * from mujoco._constants import * from mujoco._enums import * from mujoco._errors import * from mujoco._functions import * +from mujoco._render import * from mujoco._structs import * # pylint: disable=g-import-not-at-top -if _MUJOCO_GL not in _MUJOCO_GL_DISABLE: - from mujoco._render import * - if _SYSTEM != 'Linux': - from mujoco.glfw import GLContext +_MUJOCO_GL = os.environ.get('MUJOCO_GL', '').lower().strip() +if _MUJOCO_GL not in ('disable', 'disabled', 'off', 'false', '0'): + _VALID_MUJOCO_GL = ('enable', 'enabled', 'on', 'true', '1' , 'glfw', '') + if _SYSTEM == 'Linux': + _VALID_MUJOCO_GL += ('glx', 'egl', 'osmesa') + elif _SYSTEM == 'Windows': + _VALID_MUJOCO_GL += ('wgl',) + elif _SYSTEM == 'Darwin': + _VALID_MUJOCO_GL += ('cgl',) + if _MUJOCO_GL not in _VALID_MUJOCO_GL: + raise RuntimeError( + f'invalid value for environment variable MUJOCO_GL: {_MUJOCO_GL}') + + if _SYSTEM == 'Linux' and _MUJOCO_GL == 'osmesa': + from mujoco.osmesa import GLContext + elif _SYSTEM == 'Linux' and _MUJOCO_GL == 'egl': + from mujoco.egl import GLContext else: - _dl_handle = ctypes.CDLL(None) - if hasattr(_dl_handle, 'OSMesaCreateContextExt'): - from mujoco.osmesa import GLContext - elif hasattr(_dl_handle, 'eglCreateContext'): - from mujoco.egl import GLContext - else: - from mujoco.glfw import GLContext + from mujoco.glfw import GLContext + +HEADERS_DIR = os.path.join(os.path.dirname(__file__), 'include') __version__ = mj_versionString() # pylint: disable=undefined-variable diff --git a/python/mujoco/bindings_test.py b/python/mujoco/bindings_test.py index d499d80c..65165953 100644 --- a/python/mujoco/bindings_test.py +++ b/python/mujoco/bindings_test.py @@ -665,7 +665,7 @@ Euler integrator, semi-implicit in velocity. def test_enum_as_index(self): x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'] - self.assertEqual(x[mujoco.mjtFrame.mjNFRAME], 'h') + self.assertEqual(x[mujoco.mjtFrame.mjFRAME_WORLD], 'h') self.assertEqual( x[mujoco.mjtFrame.mjFRAME_GEOM:mujoco.mjtFrame.mjFRAME_CAMERA], ['c', 'd']) @@ -673,83 +673,85 @@ Euler integrator, semi-implicit in velocity. def test_enum_ops(self): # Note: when modifying this test, make sure the enum value is an odd number # so that the division tests are correctly exercised. - self.assertEqual(mujoco.mjtFrame.mjNFRAME, 7) - self.assertEqual(mujoco.mjtFrame.mjNFRAME, 7.0) - self.assertEqual(7, mujoco.mjtFrame.mjNFRAME) - self.assertEqual(7.0, mujoco.mjtFrame.mjNFRAME) - self.assertEqual(mujoco.mjtFrame.mjNFRAME, mujoco.mjtFrame.mjNFRAME) - self.assertNotEqual(mujoco.mjtFrame.mjNFRAME, mujoco.mjtFrame.mjFRAME_NONE) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD, 7) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD, 7.0) + self.assertEqual(7, mujoco.mjtFrame.mjFRAME_WORLD) + self.assertEqual(7.0, mujoco.mjtFrame.mjFRAME_WORLD) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD, + mujoco.mjtFrame.mjFRAME_WORLD) + self.assertNotEqual(mujoco.mjtFrame.mjFRAME_WORLD, + mujoco.mjtFrame.mjFRAME_NONE) - self.assertEqual(-mujoco.mjtFrame.mjNFRAME, -7) - self.assertIsInstance(-mujoco.mjtFrame.mjNFRAME, int) + self.assertEqual(-mujoco.mjtFrame.mjFRAME_WORLD, -7) + self.assertIsInstance(-mujoco.mjtFrame.mjFRAME_WORLD, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME + 1, 8) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME + 1, int) - self.assertEqual(2 + mujoco.mjtFrame.mjNFRAME, 9) - self.assertIsInstance(2 + mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME + 1.75, 8.75) - self.assertEqual(2.75 + mujoco.mjtFrame.mjNFRAME, 9.75) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD + 1, 8) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD + 1, int) + self.assertEqual(2 + mujoco.mjtFrame.mjFRAME_WORLD, 9) + self.assertIsInstance(2 + mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD + 1.75, 8.75) + self.assertEqual(2.75 + mujoco.mjtFrame.mjFRAME_WORLD, 9.75) - self.assertEqual(mujoco.mjtFrame.mjNFRAME - 2, 5) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME - 2, int) - self.assertEqual(8 - mujoco.mjtFrame.mjNFRAME, 1) - self.assertIsInstance(8 - mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME - 2.25, 4.75) - self.assertEqual(8.25 - mujoco.mjtFrame.mjNFRAME, 1.25) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD - 2, 5) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD - 2, int) + self.assertEqual(8 - mujoco.mjtFrame.mjFRAME_WORLD, 1) + self.assertIsInstance(8 - mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD - 2.25, 4.75) + self.assertEqual(8.25 - mujoco.mjtFrame.mjFRAME_WORLD, 1.25) - self.assertEqual(mujoco.mjtFrame.mjNFRAME * 3, 21) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME * 3, int) - self.assertEqual(3 * mujoco.mjtFrame.mjNFRAME, 21) - self.assertIsInstance(3 * mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME * 3.5, 24.5) - self.assertEqual(3.5 * mujoco.mjtFrame.mjNFRAME, 24.5) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD * 3, 21) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD * 3, int) + self.assertEqual(3 * mujoco.mjtFrame.mjFRAME_WORLD, 21) + self.assertIsInstance(3 * mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD * 3.5, 24.5) + self.assertEqual(3.5 * mujoco.mjtFrame.mjFRAME_WORLD, 24.5) - self.assertEqual(mujoco.mjtFrame.mjNFRAME / 2, 3.5) - self.assertEqual(17.5 / mujoco.mjtFrame.mjNFRAME, 2.5) - self.assertEqual(mujoco.mjtFrame.mjNFRAME // 2, 3) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME // 2, int) - self.assertEqual(-mujoco.mjtFrame.mjNFRAME // 2, -4) - self.assertIsInstance(-mujoco.mjtFrame.mjNFRAME // 2, int) - self.assertEqual(20 // mujoco.mjtFrame.mjNFRAME, 2) - self.assertIsInstance(20 // mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(-20 // mujoco.mjtFrame.mjNFRAME, -3) - self.assertIsInstance(-20 // mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME // 2.0, 3) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME // 2.0, float) - self.assertEqual(-mujoco.mjtFrame.mjNFRAME // 2.0, -4) - self.assertIsInstance(-mujoco.mjtFrame.mjNFRAME // 2.0, float) - self.assertEqual(20.0 // mujoco.mjtFrame.mjNFRAME, 2) - self.assertIsInstance(20.0 // mujoco.mjtFrame.mjNFRAME, float) - self.assertEqual(-20 // mujoco.mjtFrame.mjNFRAME, -3) - self.assertIsInstance(-20.0 // mujoco.mjtFrame.mjNFRAME, float) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD / 2, 3.5) + self.assertEqual(17.5 / mujoco.mjtFrame.mjFRAME_WORLD, 2.5) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD // 2, 3) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD // 2, int) + self.assertEqual(-mujoco.mjtFrame.mjFRAME_WORLD // 2, -4) + self.assertIsInstance(-mujoco.mjtFrame.mjFRAME_WORLD // 2, int) + self.assertEqual(20 // mujoco.mjtFrame.mjFRAME_WORLD, 2) + self.assertIsInstance(20 // mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(-20 // mujoco.mjtFrame.mjFRAME_WORLD, -3) + self.assertIsInstance(-20 // mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD // 2.0, 3) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD // 2.0, float) + self.assertEqual(-mujoco.mjtFrame.mjFRAME_WORLD // 2.0, -4) + self.assertIsInstance(-mujoco.mjtFrame.mjFRAME_WORLD // 2.0, float) + self.assertEqual(20.0 // mujoco.mjtFrame.mjFRAME_WORLD, 2) + self.assertIsInstance(20.0 // mujoco.mjtFrame.mjFRAME_WORLD, float) + self.assertEqual(-20 // mujoco.mjtFrame.mjFRAME_WORLD, -3) + self.assertIsInstance(-20.0 // mujoco.mjtFrame.mjFRAME_WORLD, float) - self.assertEqual(mujoco.mjtFrame.mjNFRAME % 4, 3) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME % 4, int) - self.assertEqual(-mujoco.mjtFrame.mjNFRAME % -4, -3) - self.assertIsInstance(-mujoco.mjtFrame.mjNFRAME % -4, int) - self.assertEqual(-mujoco.mjtFrame.mjNFRAME % 4, 1) - self.assertIsInstance(-mujoco.mjtFrame.mjNFRAME % 4, int) - self.assertEqual(mujoco.mjtFrame.mjNFRAME % -4, -1) - self.assertIsInstance(mujoco.mjtFrame.mjNFRAME % -4, int) - self.assertEqual(9 % mujoco.mjtFrame.mjNFRAME, 2) - self.assertIsInstance(9 % mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(-9 % -mujoco.mjtFrame.mjNFRAME, -2) - self.assertIsInstance(-9 % -mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(-9 % mujoco.mjtFrame.mjNFRAME, 5) - self.assertIsInstance(-9 % mujoco.mjtFrame.mjNFRAME, int) - self.assertEqual(9 % -mujoco.mjtFrame.mjNFRAME, -5) - self.assertIsInstance(9 % -mujoco.mjtFrame.mjNFRAME, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD % 4, 3) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD % 4, int) + self.assertEqual(-mujoco.mjtFrame.mjFRAME_WORLD % -4, -3) + self.assertIsInstance(-mujoco.mjtFrame.mjFRAME_WORLD % -4, int) + self.assertEqual(-mujoco.mjtFrame.mjFRAME_WORLD % 4, 1) + self.assertIsInstance(-mujoco.mjtFrame.mjFRAME_WORLD % 4, int) + self.assertEqual(mujoco.mjtFrame.mjFRAME_WORLD % -4, -1) + self.assertIsInstance(mujoco.mjtFrame.mjFRAME_WORLD % -4, int) + self.assertEqual(9 % mujoco.mjtFrame.mjFRAME_WORLD, 2) + self.assertIsInstance(9 % mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(-9 % -mujoco.mjtFrame.mjFRAME_WORLD, -2) + self.assertIsInstance(-9 % -mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(-9 % mujoco.mjtFrame.mjFRAME_WORLD, 5) + self.assertIsInstance(-9 % mujoco.mjtFrame.mjFRAME_WORLD, int) + self.assertEqual(9 % -mujoco.mjtFrame.mjFRAME_WORLD, -5) + self.assertIsInstance(9 % -mujoco.mjtFrame.mjFRAME_WORLD, int) with self.assertRaises(ZeroDivisionError): - _ = mujoco.mjtFrame.mjNFRAME / 0 + _ = mujoco.mjtFrame.mjFRAME_WORLD / 0 with self.assertRaises(ZeroDivisionError): _ = 1 / mujoco.mjtFrame.mjFRAME_NONE with self.assertRaises(ZeroDivisionError): - _ = mujoco.mjtFrame.mjNFRAME // 0 + _ = mujoco.mjtFrame.mjFRAME_WORLD // 0 with self.assertRaises(ZeroDivisionError): _ = 1 // mujoco.mjtFrame.mjFRAME_NONE with self.assertRaises(ZeroDivisionError): - _ = mujoco.mjtFrame.mjNFRAME % 0 + _ = mujoco.mjtFrame.mjFRAME_WORLD % 0 with self.assertRaises(ZeroDivisionError): _ = 1 % mujoco.mjtFrame.mjFRAME_NONE diff --git a/python/mujoco/render.cc b/python/mujoco/render.cc index 22699f24..1d73e415 100644 --- a/python/mujoco/render.cc +++ b/python/mujoco/render.cc @@ -206,7 +206,7 @@ PYBIND11_MODULE(_render, pymodule) { X(nskin); X(charHeight); X(charHeightBig); - X(glewInitialized); + X(glInitialized); X(windowAvailable); X(windowSamples); X(windowStereo); diff --git a/python/mujoco/render_test.py b/python/mujoco/render_test.py index 5f27a7a8..5bb52615 100644 --- a/python/mujoco/render_test.py +++ b/python/mujoco/render_test.py @@ -19,7 +19,7 @@ import mujoco import numpy as np -@absltest.skipUnless(hasattr(mujoco, 'mjr_render'), +@absltest.skipUnless(hasattr(mujoco, 'GLContext'), 'MuJoCo rendering is disabled') class MuJoCoRenderTest(absltest.TestCase): diff --git a/python/setup.py b/python/setup.py index 837d5b3e..9db2dd52 100644 --- a/python/setup.py +++ b/python/setup.py @@ -30,7 +30,7 @@ from setuptools import find_packages from setuptools import setup from setuptools.command import build_ext -__version__ = '2.1.3' +__version__ = '2.1.4' MUJOCO_CMAKE = 'MUJOCO_CMAKE' MUJOCO_CMAKE_ARGS = 'MUJOCO_CMAKE_ARGS' @@ -54,20 +54,20 @@ def get_long_description(): def get_mujoco_lib_pattern(): if platform.system() == 'Windows': - return 'mujoco*.lib' + return 'mujoco.lib' elif platform.system() == 'Darwin': - return 'libmujoco*.dylib' + return 'libmujoco.*.dylib' else: - return 'libmujoco*.so*' + return 'libmujoco.so.*' def get_external_lib_patterns(): if platform.system() == 'Windows': - return ['mujoco*.dll'] + return ['mujoco.dll'] elif platform.system() == 'Darwin': - return ['libmujoco*.dylib'] + return ['libmujoco.*.dylib'] else: - return ['libmujoco*.so*', 'libglew*.so'] + return ['libmujoco.so.*'] def start_and_end(iterable): @@ -290,12 +290,10 @@ setup( find_data_files( package_dir='mujoco', patterns=[ - 'libmujoco*.dylib', - 'libmujoco*.so*', - 'mujoco*.dll', - 'libglew*.so*', - 'mujoco.h', - 'mj*.h', + 'libmujoco.*.dylib', + 'libmujoco*.so.*', + 'mujoco.dll', + 'include/*.h', ]), }, ) diff --git a/sample/Makefile b/sample/Makefile index 997b0b80..900f48d1 100644 --- a/sample/Makefile +++ b/sample/Makefile @@ -5,12 +5,12 @@ COMMON=-O2 -I../include -L../lib -std=c++11 -pthread -Wl,-rpath,'$$ORIGIN'/../lib all: - $(CXX) $(COMMON) testxml.cc -lmujoco_nogl -o ../bin/testxml - $(CXX) $(COMMON) testspeed.cc -lmujoco_nogl -o ../bin/testspeed - $(CXX) $(COMMON) compile.cc -lmujoco_nogl -o ../bin/compile - $(CXX) $(COMMON) derivative.cc -lmujoco_nogl -fopenmp -o ../bin/derivative - $(CXX) $(COMMON) basic.cc -lmujoco -lGL -lglew -lglfw -o ../bin/basic - $(CXX) $(COMMON) record.cc -lmujoco -lGL -lglew -lglfw -o ../bin/record + $(CXX) $(COMMON) testxml.cc -lmujoco -o ../bin/testxml + $(CXX) $(COMMON) testspeed.cc -lmujoco -o ../bin/testspeed + $(CXX) $(COMMON) compile.cc -lmujoco -o ../bin/compile + $(CXX) $(COMMON) derivative.cc -lmujoco -fopenmp -o ../bin/derivative + $(CXX) $(COMMON) basic.cc -lmujoco -lGL -lglfw -o ../bin/basic + $(CXX) $(COMMON) record.cc -lmujoco -lGL -lglfw -o ../bin/record $(CC) -c -O2 -I../include uitools.c - $(CXX) $(COMMON) uitools.o simulate.cc -lmujoco -lGL -lglew -lglfw -o ../bin/simulate + $(CXX) $(COMMON) uitools.o simulate.cc -lmujoco -lGL -lglfw -o ../bin/simulate rm *.o diff --git a/sample/Makefile.macos b/sample/Makefile.macos index 592d7c50..ad1d18c5 100644 --- a/sample/Makefile.macos +++ b/sample/Makefile.macos @@ -2,20 +2,22 @@ # packages are installed in /usr/local. If your setup is different, you will # need to adjust the HOMEBREW variable accordingly. +# This Makefile also assumes that MuJoCo.app is present in /Applications. + HOMEBREW?=/usr/local -MUJOCO_LIBDIR=../MuJoCo.Framework/Versions/A -MUJOCO_INCLUDEDIR=../MuJoCo.Framework/Versions/A/Headers +MUJOCO_LIBDIR=/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.Framework/Versions/A +MUJOCO_INCLUDEDIR=/Applications/MuJoCo.app/Contents/Frameworks/MuJoCo.Framework/Versions/A/Headers CFLAGS=-O2 -I$(MUJOCO_INCLUDEDIR) -I$(HOMEBREW)/include -pthread -ALLFLAGS=$(CFLAGS) -L$(MUJOCO_LIBDIR) -L$(HOMEBREW)/lib -std=c++11 -stdlib=libc++ +ALLFLAGS=$(CFLAGS) -L$(MUJOCO_LIBDIR) -L$(HOMEBREW)/lib -std=c++11 -stdlib=libc++ -Wl,-rpath,/Applications/MuJoCo.app/Contents/Frameworks all: - clang++ $(ALLFLAGS) testxml.cc -lmujoco.2.1.3 -o testxml - clang++ $(ALLFLAGS) testspeed.cc -lmujoco.2.1.3 -o testspeed - clang++ $(ALLFLAGS) compile.cc -lmujoco.2.1.3 -o compile - clang++ $(ALLFLAGS) derivative.cc -lmujoco.2.1.3 -o derivative - clang++ $(ALLFLAGS) basic.cc -lmujoco.2.1.3 -lglfw -o basic - clang++ $(ALLFLAGS) record.cc -lmujoco.2.1.3 -lglfw -o record + clang++ $(ALLFLAGS) testxml.cc -lmujoco.2.1.4 -o testxml + clang++ $(ALLFLAGS) testspeed.cc -lmujoco.2.1.4 -o testspeed + clang++ $(ALLFLAGS) compile.cc -lmujoco.2.1.4 -o compile + clang++ $(ALLFLAGS) derivative.cc -lmujoco.2.1.4 -o derivative + clang++ $(ALLFLAGS) basic.cc -lmujoco.2.1.4 -lglfw -o basic + clang++ $(ALLFLAGS) record.cc -lmujoco.2.1.4 -lglfw -o record clang -c $(CFLAGS) uitools.c - clang++ $(ALLFLAGS) uitools.o simulate.cc -lmujoco.2.1.3 -lglfw -o simulate + clang++ $(ALLFLAGS) uitools.o simulate.cc -lmujoco.2.1.4 -lglfw -o simulate rm *.o diff --git a/sample/Makefile.windows b/sample/Makefile.windows index 5c6926e1..74117395 100644 --- a/sample/Makefile.windows +++ b/sample/Makefile.windows @@ -9,10 +9,10 @@ COMMON=/O2 /MT /EHsc /arch:AVX /I../include /Fe../bin/ all: - cl $(COMMON) testxml.cc ../lib/mujoco_nogl.lib - cl $(COMMON) testspeed.cc ../lib/mujoco_nogl.lib - cl $(COMMON) compile.cc ../lib/mujoco_nogl.lib - cl $(COMMON) derivative.cc /openmp ../lib/mujoco_nogl.lib + cl $(COMMON) testxml.cc ../lib/mujoco.lib + cl $(COMMON) testspeed.cc ../lib/mujoco.lib + cl $(COMMON) compile.cc ../lib/mujoco.lib + cl $(COMMON) derivative.cc /openmp ../lib/mujoco.lib cl $(COMMON) basic.cc ../lib/glfw3.lib ../lib/mujoco.lib cl $(COMMON) record.cc ../lib/glfw3.lib ../lib/mujoco.lib cl $(COMMON) simulate.cc uitools.c ../lib/glfw3.lib ../lib/mujoco.lib diff --git a/sample/simulate.cc b/sample/simulate.cc index b8241361..30066a2b 100644 --- a/sample/simulate.cc +++ b/sample/simulate.cc @@ -762,7 +762,7 @@ void makerendering(int oldstate) { "Frame", 2, &(vopt.frame), - "None\nBody\nGeom\nSite\nCamera\nLight\nWorld" + "None\nBody\nGeom\nSite\nCamera\nLight\nContact\nWorld" }, { mjITEM_BUTTON, diff --git a/unity/Runtime/Bindings/MujocoBinaryRetriever.cs b/unity/Runtime/Bindings/MujocoBinaryRetriever.cs index 8f68fe2d..2c696913 100644 --- a/unity/Runtime/Bindings/MujocoBinaryRetriever.cs +++ b/unity/Runtime/Bindings/MujocoBinaryRetriever.cs @@ -35,7 +35,7 @@ public class MujocoBinaryRetriever { if (AssetDatabase.LoadMainAssetAtPath(mujocoPath + "/mujoco.dylib") == null) { File.Copy( "/Applications/MuJoCo.app/Contents/Frameworks" + - "/MuJoCo.framework/Versions/Current/libmujoco.2.1.3.dylib", + "/MuJoCo.framework/Versions/Current/libmujoco.2.1.4.dylib", mujocoPath + "/mujoco.dylib"); AssetDatabase.Refresh(); } @@ -43,7 +43,7 @@ public class MujocoBinaryRetriever { if (AssetDatabase.LoadMainAssetAtPath(mujocoPath + "/libmujoco.so") == null) { File.Copy( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + - "/.mujoco/mujoco-2.1.3/lib/libmujoco_nogl.so.2.1.3", + "/.mujoco/mujoco-2.1.4/lib/libmujoco.so.2.1.4", mujocoPath + "/libmujoco.so"); AssetDatabase.Refresh(); } diff --git a/unity/Runtime/Bindings/MujocoBindings.cs b/unity/Runtime/Bindings/MujocoBindings.cs index 8a85ec3b..f05c83ba 100644 --- a/unity/Runtime/Bindings/MujocoBindings.cs +++ b/unity/Runtime/Bindings/MujocoBindings.cs @@ -83,7 +83,7 @@ public const int mjMAXOVERLAY = 500; public const int mjMAXLINE = 100; public const int mjMAXLINEPNT = 1000; public const int mjMAXPLANEGRID = 200; -public const int mjVERSION_HEADER = 213; +public const int mjVERSION_HEADER = 214; // ------------------------------------Enums------------------------------------ @@ -2201,7 +2201,7 @@ public unsafe struct mjrContext_ { public fixed int charWidthBig[127]; public int charHeight; public int charHeightBig; - public int glewInitialized; + public int glInitialized; public int windowAvailable; public int windowSamples; public int windowStereo;