Version 2.1.1: Binaries for ARM64, proper macOS bundles, minor bugfixes.

Closes #2
Closes #42
Closes #59

PiperOrigin-RevId: 416794598
Change-Id: I1306df1127d6acecf2323873c0da0910f35d31a0
This commit is contained in:
Saran Tunyasuvunakool
2021-12-16 14:36:53 +00:00
parent 4bf5630558
commit a499b38120
49 changed files with 6055 additions and 5712 deletions
+4 -8
View File
@@ -1,7 +1,3 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
============= =============
API Reference API Reference
============= =============
@@ -3205,8 +3201,8 @@ Virtual file system
| Virtual file system (VFS) functionality was introduced in MuJoCo 1.50. It enables the user to load all necessary files | Virtual file system (VFS) functionality was introduced in MuJoCo 1.50. It enables the user to load all necessary files
in memory, including MJB binary model files, XML files (MJCF, URDF and included files), STL meshes, PNGs for textures in memory, including MJB binary model files, XML files (MJCF, URDF and included files), STL meshes, PNGs for textures
and height fields, and HF files in our custom height field format. Model and resource files in the VFS can also be and height fields, and HF files in our custom height field format. Model and resource files in the VFS can also be
constructed programmatically (say using an XML library that writes to memory). Once all desired files are in the VFS, constructed programmatically (say using a Python library that writes to memory). Once all desired files are in the
the user can call :ref:`mj_loadModel` or :ref:`mj_loadXML` with a pointer to the VFS. When VFS, the user can call :ref:`mj_loadModel` or :ref:`mj_loadXML` with a pointer to the VFS. When
this pointer is not NULL, the loaders will first check the VFS for any file they are about to load, and only access this pointer is not NULL, the loaders will first check the VFS for any file they are about to load, and only access
the disk if the file is not found in the VFS. The file names stored in the VFS have their name and extension but the the disk if the file is not found in the VFS. The file names stored in the VFS have their name and extension but the
path information is stripped; this can be bypassed however by using a custom path symbol in the file names, say path information is stripped; this can be bypassed however by using a custom path symbol in the file names, say
@@ -5254,7 +5250,7 @@ mjui_add
Add definitions to UI. Add definitions to UI.
mjui_addToSection mjui_addToSection
~~~~~~~~ ~~~~~~~~~~~~~~~~~
.. code-block:: C .. code-block:: C
@@ -6426,7 +6422,7 @@ Insertion sort, resulting list is in increasing order.
.. _mju_insertionSortInt: .. _mju_insertionSortInt:
mju_insertionSortInt mju_insertionSortInt
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
.. code-block:: C .. code-block:: C
+1 -5
View File
@@ -1,7 +1,3 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
============= =============
XML Reference XML Reference
============= =============
@@ -1512,7 +1508,7 @@ any effect. The settings here are global and apply to the entire model.
hull computation is the slowest operation performed by the compiler). However once model design is finished, this hull computation is the slowest operation performed by the compiler). However once model design is finished, this
feature should be enabled, because the availability of convex hulls substantially speeds up collision detection with feature should be enabled, because the availability of convex hulls substantially speeds up collision detection with
large meshes. large meshes.
:at:`userthread`: :at-val:`[false, true], "true"` :at:`usethread`: :at-val:`[false, true], "true"`
If this attribute is "true", the model compiler will run in multi-threaded mode. Currently multi-threading is only If this attribute is "true", the model compiler will run in multi-threaded mode. Currently multi-threading is only
used when computing the length ranges of actuators, but in the future additional compiler phases may be used when computing the length ranges of actuators, but in the future additional compiler phases may be
multi-threaded. multi-threaded.
+109 -5
View File
@@ -1,12 +1,111 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
========= =========
Changelog Changelog
========= =========
Version 2.1 (Oct. 18, 2021) Version 2.1.1 (Dec. 16, 2021)
--------------------------- -----------------------------
API changes
^^^^^^^^^^^
1. Added ``mj_printFormattedModel``, which accepts a format string for floating point numbers, for example to increase
precision.
#. Added ``mj_versionString``, which returns human-readable string that represents the version of the MuJoCo binary.
#. Converted leading underscores to trailing underscores in private instances of API struct definitions, to conform to
reserved identifier directive, see
`C standard: Section 7.1.3 <www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>`__.
.. attention::
This is a minor breaking change. Code which references private instances will break. To fix, replace leading
underscores with trailing underscores, e.g. ``_mjModel`` |rarr| ``mjModel_``.
General
^^^^^^^
4. Safer string handling: replaced ``strcat``, ``strcpy``, and ``sprintf`` with ``strncat``, ``strncpy``, and
``snprintf`` respectively.
#. Changed indentation from 4 spaces to 2 spaces everywhere.
Bug Fixes
^^^^^^^^^
6. Fixed reading from uninitialized memory in PGS solver.
#. Computed capsule inertias are now exact. Until this change, capsule masses and inertias computed by the
:ref:`compiler <compiler>`'s :at:`inertiafromgeom` mechanism were approximated by a cylinder, formed by the
capsule's cylindrical middle section, extended on both ends by half the capsule radius. Capsule inertias are now
computed with the `Parallel Axis theorem <https://en.wikipedia.org/wiki/Parallel_axis_theorem>`_, applied to the two
hemispherical end-caps.
.. attention::
This is a minor breaking change. Simulation of a model with automatically-computed capsule inertias will be
numerically different, leading to, for example, breakage of golden-value tests.
#. Fixed bug related to :ref:`force <sensor-force>` and :ref:`torque <sensor-torque>` sensors. Until this change, forces
torques reported by F/T sensors ignored out-of-tree constraint wrenches except those produced by contacts. Force and
and torque sensors now correctly take into account the effects of :ref:`connect <equality-connect>` and
:ref:`weld <equality-weld>` constraints.
.. note::
Forces generated by :ref:`spatial tendons <spatial>` which are outside the kinematic tree (i.e. between bodies
which have no ancestral relationship) are still not taken into account by force and torque sensors. This remains a
future work item.
Code samples
^^^^^^^^^^^^
9. ``testspeed``: Added injection of pseudo-random control noise, turned on by default. This is to avoid settling into
some fixed contact configuration and providing an unrealistic timing measure.
#. ``simulate``:
a. Added slower-than-real-time functionality, which is controlled via the '+' and '-' keys.
#. Added sliders for injecting Brownian noise into the controls.
#. Added "Print Camera" button to print an MJCF clause with the pose of the current camera.
#. The camera pose is not reset when reloading the same model file.
Updated dependencies
^^^^^^^^^^^^^^^^^^^^
11. ``TinyXML`` was replaced with ``TinyXML2`` 6.2.0.
#. ``qhull`` was upgraded to version 8.0.2.
#. ``libCCD`` was upgraded to version 1.4.
#. On Linux, ``libstdc++`` was replaced with ``libc++``.
Binary build
^^^^^^^^^^^^
15. MacOS packaging. We now ship Universal binaries that natively support both Apple Silicon and Intel CPUs.
a. MuJoCo library is now packaged as a
`Framework Bundle <https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html>`_,
allowing it to be incorporated more easily into Xcode projects (including Swift projects). Developers are
encouraged to compile and link against MuJoCo using the ``-framework mujoco`` flag, however all header files and
the ``libmujoco.2.1.1.dylib`` library can still be directly accessed inside the framework.
#. Sample applications are now packaged into an Application Bundle called ``MuJoCo.app``. When launched via GUI,
the bundle launches the ``simulate`` executable. Other precompiled sample programs are shipped inside that bundle
(in ``MuJoCo.app/Contents/MacOS``) and can be launched via command line.
#. Binaries are now signed and the disk image is notarized.
#. Windows binaries and libraries are now signed.
#. Link-time optimization is enabled on Linux and macOS, leading to an average of \~20% speedup when benchmarked on
three test models (``cloth.xml``, ``humanoid.xml``, and ``humanoid100.xml``).
#. Linux binaries are now built with LLVM/Clang instead of GCC.
#. An AArch64 (aka ARM64) Linux build is also provided.
#. Private symbols are no longer stripped from shared libraries on Linux and MacOS.
Sample models
^^^^^^^^^^^^^
21. Clean-up of the ``model/`` directory.
a. Rearranged into subdirectories which include all dependencies.
#. Added descriptions in XML comments, cleaned up XMLs.
#. Deleted some composite models: ``grid1``, ``grid1pin``, ``grid2``, ``softcylinder``, ``softellipsoid``.
#. Added descriptive animations in ``docs/images/models/`` :
|humanoid| |particle|
Version 2.1.0 (Oct. 18, 2021)
-----------------------------
New features New features
^^^^^^^^^^^^ ^^^^^^^^^^^^
@@ -63,3 +162,8 @@ Earlier Versions
---------------- ----------------
For changelogs of earlier versions please see `roboti.us <https://www.roboti.us/download.html>`_. For changelogs of earlier versions please see `roboti.us <https://www.roboti.us/download.html>`_.
.. |humanoid| image:: images/models/humanoid.gif
:width: 270px
.. |particle| image:: images/models/particle.gif
:width: 270px
+6
View File
@@ -60,6 +60,12 @@ redirects = {
'index': 'overview.html', 'index': 'overview.html',
} }
rst_prolog = """
.. include:: includes/macros.rst
.. include:: includes/roles.rst
.. include:: <isonum.txt>
"""
# -- Options for autodoc ----------------------------------------------------- # -- Options for autodoc -----------------------------------------------------
autodoc_default_options = { autodoc_default_options = {
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

+30 -35
View File
@@ -1,7 +1,3 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
======== ========
Modeling Modeling
======== ========
@@ -94,7 +90,7 @@ MJCF Mechanisms
MJCF uses several mechanisms for model creation which span multiple model elements. To avoid repetition we describe them MJCF uses several mechanisms for model creation which span multiple model elements. To avoid repetition we describe them
in detail only once in this section. These mechanisms do not correspond to new simulation concepts beyond those in detail only once in this section. These mechanisms do not correspond to new simulation concepts beyond those
introduced in the Computation chapter. Their role is to simplify the creation of MJFC models, and to enable the use of introduced in the Computation chapter. Their role is to simplify the creation of MJCF models, and to enable the use of
different data formats without need for manual conversion to a canonical format. different data formats without need for manual conversion to a canonical format.
.. _CTree: .. _CTree:
@@ -144,7 +140,7 @@ the model. We start with an example.
<geom type="ellipsoid"/> <geom type="ellipsoid"/>
<geom type="sphere" rgba="0 0 1 0"/> <geom type="sphere" rgba="0 0 1 0"/>
<geom type="cylinder" class="main"/> <geom type="cylinder" class="main"/>
</geom> </body>
</worldbody> </worldbody>
</mujoco> </mujoco>
@@ -189,7 +185,7 @@ Some attributes, such as body position in models defined in global coordinates,
This instructs the compiler to infer the corresponding value from other information, in this case the positions of the This instructs the compiler to infer the corresponding value from other information, in this case the positions of the
geoms attached to the body. The undefined state cannot be entered in the XML file. Therefore once an attribute is geoms attached to the body. The undefined state cannot be entered in the XML file. Therefore once an attribute is
defined in a given class, it cannot be undefined in that class or in any of its child classes. So if the goal is to defined in a given class, it cannot be undefined in that class or in any of its child classes. So if the goal is to
leave a certain attribute undefined in a given model element, in must be undefined in the active defaults class. leave a certain attribute undefined in a given model element, it must be undefined in the active defaults class.
A final twist here are actuators. They are different because some of the actuator-related elements are actually A final twist here are actuators. They are different because some of the actuator-related elements are actually
shortcuts, and shortcuts interact with the defaults setting mechanism in a non-obvious way. This is explained in the shortcuts, and shortcuts interact with the defaults setting mechanism in a non-obvious way. This is explained in the
@@ -236,7 +232,7 @@ When this model is compiled and saved as MJCF (in local coordinates) the same fr
The body position was set to the geom position (1 0 0), while the geom and inertial positions were set to (0 0 0) The body position was set to the geom position (1 0 0), while the geom and inertial positions were set to (0 0 0)
relative to the body. relative to the body.
In principle the user always has a choice between local and global coordinates, but in practice this choice if viable In principle the user always has a choice between local and global coordinates, but in practice this choice is viable
only when using geometric primitives rather than meshes. For meshes, the 3D vertex positions are expressed in either only when using geometric primitives rather than meshes. For meshes, the 3D vertex positions are expressed in either
local and global coordinates depending on how the mesh was designed - effectively forcing the user to adopt the same local and global coordinates depending on how the mesh was designed - effectively forcing the user to adopt the same
convention for the entire model. The alternative would be to pre-process the mesh data outside MuJoCo so as to change convention for the entire model. The alternative would be to pre-process the mesh data outside MuJoCo so as to change
@@ -298,7 +294,7 @@ contact-related solver parameters at runtime, so as to experiment interactively
continuation methods for numerical optimization. continuation methods for numerical optimization.
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let a1 Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let a1
denote the acceleration, v the velocity, r the position or residual (defined as 0 in friction dimensions), b and k the denote the acceleration, v the velocity, r the position or residual (defined as 0 in friction dimensions), k and b the
stiffness and damping of the virtual spring used to define the reference acceleration aref = -b*v - k*r. Let d be the stiffness and damping of the virtual spring used to define the reference acceleration aref = -b*v - k*r. Let d be the
constraint impedance, and a0 the acceleration in the absence of constraint force. Our earlier analysis revealed that constraint impedance, and a0 the acceleration in the absence of constraint force. Our earlier analysis revealed that
the dynamics in constraint space are approximately the dynamics in constraint space are approximately
@@ -405,7 +401,7 @@ friction
function always generates contact frames oriented in the same way - which we do not describe here but it can be seen function always generates contact frames oriented in the same way - which we do not describe here but it can be seen
in the visualizer. For individual geoms however, we do not know which other geoms they might collide with and what in the visualizer. For individual geoms however, we do not know which other geoms they might collide with and what
their geom types might be, so there is no way to know how the contact tangent plane will be oriented when specifying their geom types might be, so there is no way to know how the contact tangent plane will be oriented when specifying
an individual geom. This is why MuJoCo does now allow anisotropic friction in the individual geom specifications, but an individual geom. This is why MuJoCo does not allow anisotropic friction in the individual geom specifications, but
only in the explicit contact pair specifications. only in the explicit contact pair specifications.
margin, gap margin, gap
The maximum of the two geom margins (or gaps respectively) is used. The geom priority is ignored here, because the The maximum of the two geom margins (or gaps respectively) is used. The geom priority is ignored here, because the
@@ -794,14 +790,13 @@ range.
Pennation angle (i.e. the angle between the muscle and the line of force) is not modeled in MuJoCo and is assumed to Pennation angle (i.e. the angle between the muscle and the line of force) is not modeled in MuJoCo and is assumed to
be 0. This effect can be approximated by scaling down the muscle force and also adjusting the operating range. be 0. This effect can be approximated by scaling down the muscle force and also adjusting the operating range.
Tendon wrapping is also more limited in MuJoCo. We allow spheres and infinite cylinders as wrapping objects, and Tendon wrapping is also more limited in MuJoCo. We allow spheres and infinite cylinders as wrapping objects, and require
require two wrapping objects to be separated by a fixed site in the tendon path. This is to avoid the need for two wrapping objects to be separated by a fixed site in the tendon path. This is to avoid the need for iterative
iterative computations of tendon paths. As of MuJoCo 2.0 we also allow "side sites" to be placed inside the sphere or computations of tendon paths. As of MuJoCo 2.0 we also allow "side sites" to be placed inside the sphere or cylinder,
cylinder, which causes an inverse wrap: the tendon path is constrained to pass through the object instead of go around which causes an inverse wrap: the tendon path is constrained to pass through the object instead of going around it. This
it. This can replace torus wrapping objects used in OpenSim to keep the tendon path within a given area. Overall, can replace torus wrapping objects used in OpenSim to keep the tendon path within a given area. Overall, tendon wrapping
tendon wrapping is the most challenging part of converting an OpenSim model to a MuJoCo model, and requires some is the most challenging part of converting an OpenSim model to a MuJoCo model, and requires some manual work. On the
manual work. On the bright side, there is a small number of high-quality OpenSim models in use, so once they are bright side, there is a small number of high-quality OpenSim models in use, so once they are converted we are done.
converted we are done.
Below we illustrate the four types of tendon wrapping available in MuJoCo 2.0. Note that the curved sections of the Below we illustrate the four types of tendon wrapping available in MuJoCo 2.0. Note that the curved sections of the
wrapping tendons are rendered as straight, but the geometry pipeline works with the actual curves and computes their wrapping tendons are rendered as straight, but the geometry pipeline works with the actual curves and computes their
@@ -848,17 +843,17 @@ of regular model elements that were automatically generated. So think of it as a
compiler. compiler.
Composite objects are made up of regular MuJoCo bodies, which we call "element bodies" in this context. The element Composite objects are made up of regular MuJoCo bodies, which we call "element bodies" in this context. The element
bodies are created as children of the body within which :el:`composite` appears; thus a composite object appears in bodies are created as children of the body within which :el:`composite` appears; thus a composite object appears in the
the same place in the XML where a regular child body may have been defined. Each automatically-generated element body same place in the XML where a regular child body may have been defined. Each automatically-generated element body has a
has a single geom attached to it, usually a sphere but could also be capsule or ellipsoid. Thus the composite object single geom attached to it, usually a sphere but could also be a capsule or an ellipsoid. Thus the composite object is
is essentially a particle system, however the particles can be constrained to move together in ways that simulate essentially a particle system, however the particles can be constrained to move together in ways that simulate various
various flexible objects. The initial positions of the element bodies form a regular grid in 1D, 2D or 3D. They could flexible objects. The initial positions of the element bodies form a regular grid in 1D, 2D or 3D. They could all be
all be children of the parent body (which can be the world or another regular body; composite objects cannot be children of the parent body (which can be the world or another regular body; composite objects cannot be nested) and
nested) and have joints allowing motion relative to the parent, or they could form a kinematic tree with joints have joints allowing motion relative to the parent, or they could form a kinematic tree with joints between the element
between the element bodies. They can also be connected with tendons with soft equality constraints on the tendon bodies. They can also be connected with tendons with soft equality constraints on the tendon length, creating the
length, creating the necessary coupling. Joint equality constraints are also used in some cases. The :at:`solref` necessary coupling. Joint equality constraints are also used in some cases. The :at:`solref` and :at:`solimp` attributes
and :at:`solimp` attributes of these equality constraints can be adjusted by the user, thereby adjusting the of these equality constraints can be adjusted by the user, thereby adjusting the softness and flexibility of the
softness and flexibility of the composite objects. composite objects.
In addition to setting up the physics, the composite object generator creates suitable rendering. 2D and 3D objects In addition to setting up the physics, the composite object generator creates suitable rendering. 2D and 3D objects
can be rendered as :ref:`skins <skin>` which are also new in MuJoCo 2.0. The skin is generated can be rendered as :ref:`skins <skin>` which are also new in MuJoCo 2.0. The skin is generated
@@ -1046,7 +1041,7 @@ points to the outside, thus creating a thicker shell which is harder to penetrat
</composite> </composite>
</body> </body>
Cylinders and ellipsoids are created in the same was as boxes. The only difference is that the reference positions of Cylinders and ellipsoids are created in the same way as boxes. The only difference is that the reference positions of
the element bodies (relative to the parent) are projected on a cylinder or ellipsoid, with size implied by the the element bodies (relative to the parent) are projected on a cylinder or ellipsoid, with size implied by the
:at:`count` attribute. The automatic skin generator is aware of the smooth surfaces, and adjusts the skin normals :at:`count` attribute. The automatic skin generator is aware of the smooth surfaces, and adjusts the skin normals
accordingly. In the plots we have used the capsule probe to press on each body, then paused the simulation and moved the accordingly. In the plots we have used the capsule probe to press on each body, then paused the simulation and moved the
@@ -1129,7 +1124,7 @@ modeled. This is why we have implemented support for URDF even though it can onl
elements available in MuJoCo. In addition to standard URDF files, MuJoCo can load files that have a custom (from the elements available in MuJoCo. In addition to standard URDF files, MuJoCo can load files that have a custom (from the
viewpoint of URDF) :el:`mujoco` element as a child of the top-level element :el:`robot`. This custom element can have viewpoint of URDF) :el:`mujoco` element as a child of the top-level element :el:`robot`. This custom element can have
sub-elements :ref:`compiler <compiler>`, :ref:`option <option>`, sub-elements :ref:`compiler <compiler>`, :ref:`option <option>`,
:ref:`size <size>` with the same functionality as in MJFC, except that the default compiler settings :ref:`size <size>` with the same functionality as in MJCF, except that the default compiler settings
are modified so as to accomodate the URDF modeling convention. The :ref:`compiler <compiler>` extension are modified so as to accomodate the URDF modeling convention. The :ref:`compiler <compiler>` extension
in particular has proven very useful, and indeed several of its attributes were introduced because a number of in particular has proven very useful, and indeed several of its attributes were introduced because a number of
existing URDF models have non-physical dynamics parameters which MuJoCo's built-in compiler will reject if left existing URDF models have non-physical dynamics parameters which MuJoCo's built-in compiler will reject if left
@@ -1300,10 +1295,10 @@ virtual objects cannot push on your physical hand, so your hand (and thereby the
violate the simulated physics. But at the same time we want the resulting simulation to be reasonable. How do we do violate the simulated physics. But at the same time we want the resulting simulation to be reasonable. How do we do
this? this?
The first step is to define a mocap body in the MJCF model, and at implement code that reads the data stream at The first step is to define a mocap body in the MJCF model, and implement code that reads the data stream at runtime and
runtime and sets mjModel.mocap_pos and mjModel.mocap_quat to the position and orientation received from the motion sets mjModel.mocap_pos and mjModel.mocap_quat to the position and orientation received from the motion capture system.
capture system. The `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ code sample uses The `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ code sample uses the mouse as a
the mouse as a motion capture device, allowing the user to move mocap bodies around. motion capture device, allowing the user to move mocap bodies around.
The key thing to understand about mocap bodies is that the simulator treats them as being fixed. We are causing them The key thing to understand about mocap bodies is that the simulator treats them as being fixed. We are causing them
to move from one simulation time step to the next by updating their position and orientation directly, but as far as to move from one simulation time step to the next by updating their position and orientation directly, but as far as
-4
View File
@@ -1,7 +1,3 @@
.. include:: includes/macros.rst
.. include:: includes/roles.rst
=========== ===========
Programming Programming
=========== ===========
Executable → Regular
+19 -24
View File
@@ -15,10 +15,11 @@
#ifndef MUJOCO_MJDATA_H_ #ifndef MUJOCO_MJDATA_H_
#define MUJOCO_MJDATA_H_ #define MUJOCO_MJDATA_H_
//---------------------------- primitive types (mjt) ------------------------------------ #include "mjmodel.h"
typedef enum _mjtWarning // warning types //---------------------------------- primitive types (mjt) -----------------------------------------
{
typedef enum mjtWarning_ { // warning types
mjWARN_INERTIA = 0, // (near) singular inertia matrix mjWARN_INERTIA = 0, // (near) singular inertia matrix
mjWARN_CONTACTFULL, // too many contacts in contact list mjWARN_CONTACTFULL, // too many contacts in contact list
mjWARN_CNSTRFULL, // too many constraints mjWARN_CNSTRFULL, // too many constraints
@@ -32,8 +33,7 @@ typedef enum _mjtWarning // warning types
} mjtWarning; } mjtWarning;
typedef enum _mjtTimer typedef enum mjtTimer_ {
{
// main api // main api
mjTIMER_STEP = 0, // step mjTIMER_STEP = 0, // step
mjTIMER_FORWARD, // forward mjTIMER_FORWARD, // forward
@@ -57,10 +57,9 @@ typedef enum _mjtTimer
} mjtTimer; } mjtTimer;
//------------------------------ mjContact ---------------------------------------------- //---------------------------------- mjContact -----------------------------------------------------
struct _mjContact // result of collision detection functions struct mjContact_ { // result of collision detection functions
{
// contact parameters set by geom-specific collision detector // contact parameters set by geom-specific collision detector
mjtNum dist; // distance between nearest points; neg: penetration mjtNum dist; // distance between nearest points; neg: penetration
mjtNum pos[3]; // position of contact point: midpoint between geoms mjtNum pos[3]; // position of contact point: midpoint between geoms
@@ -87,29 +86,26 @@ struct _mjContact // result of collision detection functions
// address computed by mj_instantiateContact // address computed by mj_instantiateContact
int efc_address; // address in efc; -1: not included, -2-i: distance constraint i int efc_address; // address in efc; -1: not included, -2-i: distance constraint i
}; };
typedef struct _mjContact mjContact; typedef struct mjContact_ mjContact;
//------------------------------ diagnostics -------------------------------------------- //---------------------------------- diagnostics ---------------------------------------------------
struct _mjWarningStat // warning statistics struct mjWarningStat_ { // warning statistics
{
int lastinfo; // info from last warning int lastinfo; // info from last warning
int number; // how many times was warning raised int number; // how many times was warning raised
}; };
typedef struct _mjWarningStat mjWarningStat; typedef struct mjWarningStat_ mjWarningStat;
struct _mjTimerStat // timer statistics struct mjTimerStat_ { // timer statistics
{
mjtNum duration; // cumulative duration mjtNum duration; // cumulative duration
int number; // how many times was timer called int number; // how many times was timer called
}; };
typedef struct _mjTimerStat mjTimerStat; typedef struct mjTimerStat_ mjTimerStat;
struct _mjSolverStat // per-iteration solver statistics struct mjSolverStat_ { // per-iteration solver statistics
{
mjtNum improvement; // cost reduction, scaled by 1/trace(M(qpos0)) mjtNum improvement; // cost reduction, scaled by 1/trace(M(qpos0))
mjtNum gradient; // gradient norm (primal only, scaled) mjtNum gradient; // gradient norm (primal only, scaled)
mjtNum lineslope; // slope in linesearch mjtNum lineslope; // slope in linesearch
@@ -118,13 +114,12 @@ struct _mjSolverStat // per-iteration solver statistics
int neval; // number of cost evaluations in line search int neval; // number of cost evaluations in line search
int nupdate; // number of Cholesky updates in line search int nupdate; // number of Cholesky updates in line search
}; };
typedef struct _mjSolverStat mjSolverStat; typedef struct mjSolverStat_ mjSolverStat;
//---------------------------------- mjData --------------------------------------------- //---------------------------------- mjData --------------------------------------------------------
struct _mjData struct mjData_ {
{
// constant sizes // constant sizes
int nstack; // number of mjtNums that can fit in stack int nstack; // number of mjtNums that can fit in stack
int nbuffer; // size of main buffer in bytes int nbuffer; // size of main buffer in bytes
@@ -315,10 +310,10 @@ struct _mjData
mjtNum* cfrc_int; // com-based interaction force with parent (nbody x 6) mjtNum* cfrc_int; // com-based interaction force with parent (nbody x 6)
mjtNum* cfrc_ext; // com-based external force on body (nbody x 6) mjtNum* cfrc_ext; // com-based external force on body (nbody x 6)
}; };
typedef struct _mjData mjData; typedef struct mjData_ mjData;
//---------------------------------- callback function types ---------------------------- //---------------------------------- callback function types ---------------------------------------
// generic MuJoCo function // generic MuJoCo function
typedef void (*mjfGeneric)(const mjModel* m, mjData* d); typedef void (*mjfGeneric)(const mjModel* m, mjData* d);
Executable → Regular
+51 -88
View File
@@ -15,11 +15,10 @@
#ifndef MUJOCO_MJMODEL_H_ #ifndef MUJOCO_MJMODEL_H_
#define MUJOCO_MJMODEL_H_ #define MUJOCO_MJMODEL_H_
//---------------------------- floating-point definitions ------------------------------- //---------------------------------- floating-point definitions ------------------------------------
// compile-time configuration options // compile-time configuration options
#define mjUSEDOUBLE // single or double precision for mjtNum #define mjUSEDOUBLE // single or double precision for mjtNum
#define mjUSEAVX // C or AVX intrinsics for custom BLAS
// floating point data type and minval // floating point data type and minval
@@ -43,7 +42,7 @@
#define mjMAXVFSNAME 1000 // maximum filename size in virtual file system #define mjMAXVFSNAME 1000 // maximum filename size in virtual file system
//---------------------------- sizes ---------------------------------------------------- //---------------------------------- sizes ---------------------------------------------------------
#define mjNEQDATA 7 // number of eq_data fields #define mjNEQDATA 7 // number of eq_data fields
#define mjNDYN 10 // number of actuator dynamics parameters #define mjNDYN 10 // number of actuator dynamics parameters
@@ -54,13 +53,12 @@
#define mjNSOLVER 1000 // size of mjData.solver_XXX arrays #define mjNSOLVER 1000 // size of mjData.solver_XXX arrays
//---------------------------- primitive types (mjt) ------------------------------------ //---------------------------------- primitive types (mjt) -----------------------------------------
typedef unsigned char mjtByte; // used for true/false typedef unsigned char mjtByte; // used for true/false
typedef enum _mjtDisableBit // disable default feature bitflags typedef enum mjtDisableBit_ { // disable default feature bitflags
{
mjDSBL_CONSTRAINT = 1<<0, // entire constraint solver mjDSBL_CONSTRAINT = 1<<0, // entire constraint solver
mjDSBL_EQUALITY = 1<<1, // equality constraints mjDSBL_EQUALITY = 1<<1, // equality constraints
mjDSBL_FRICTIONLOSS = 1<<2, // joint and tendon frictionloss constraints mjDSBL_FRICTIONLOSS = 1<<2, // joint and tendon frictionloss constraints
@@ -78,8 +76,7 @@ typedef enum _mjtDisableBit // disable default feature bitflags
} mjtDisableBit; } mjtDisableBit;
typedef enum _mjtEnableBit // enable optional feature bitflags typedef enum mjtEnableBit_ { // enable optional feature bitflags
{
mjENBL_OVERRIDE = 1<<0, // override contact parameters mjENBL_OVERRIDE = 1<<0, // override contact parameters
mjENBL_ENERGY = 1<<1, // energy computation mjENBL_ENERGY = 1<<1, // energy computation
mjENBL_FWDINV = 1<<2, // record solver statistics mjENBL_FWDINV = 1<<2, // record solver statistics
@@ -89,8 +86,7 @@ typedef enum _mjtEnableBit // enable optional feature bitflags
} mjtEnableBit; } mjtEnableBit;
typedef enum _mjtJoint // type of degree of freedom typedef enum mjtJoint_ { // type of degree of freedom
{
mjJNT_FREE = 0, // global position and orientation (quat) (7) mjJNT_FREE = 0, // global position and orientation (quat) (7)
mjJNT_BALL, // orientation (quat) relative to parent (4) mjJNT_BALL, // orientation (quat) relative to parent (4)
mjJNT_SLIDE, // sliding distance along body-fixed axis (1) mjJNT_SLIDE, // sliding distance along body-fixed axis (1)
@@ -98,8 +94,7 @@ typedef enum _mjtJoint // type of degree of freedom
} mjtJoint; } mjtJoint;
typedef enum _mjtGeom // type of geometric shape typedef enum mjtGeom_ { // type of geometric shape
{
// regular geom types // regular geom types
mjGEOM_PLANE = 0, // plane mjGEOM_PLANE = 0, // plane
mjGEOM_HFIELD, // height field mjGEOM_HFIELD, // height field
@@ -124,8 +119,7 @@ typedef enum _mjtGeom // type of geometric shape
} mjtGeom; } mjtGeom;
typedef enum _mjtCamLight // tracking mode for camera and light typedef enum mjtCamLight_ { // tracking mode for camera and light
{
mjCAMLIGHT_FIXED = 0, // pos and rot fixed in body mjCAMLIGHT_FIXED = 0, // pos and rot fixed in body
mjCAMLIGHT_TRACK, // pos tracks body, rot fixed in global mjCAMLIGHT_TRACK, // pos tracks body, rot fixed in global
mjCAMLIGHT_TRACKCOM, // pos tracks subtree com, rot fixed in body mjCAMLIGHT_TRACKCOM, // pos tracks subtree com, rot fixed in body
@@ -134,54 +128,47 @@ typedef enum _mjtCamLight // tracking mode for camera and light
} mjtCamLight; } mjtCamLight;
typedef enum _mjtTexture // type of texture typedef enum mjtTexture_ { // type of texture
{
mjTEXTURE_2D = 0, // 2d texture, suitable for planes and hfields mjTEXTURE_2D = 0, // 2d texture, suitable for planes and hfields
mjTEXTURE_CUBE, // cube texture, suitable for all other geom types mjTEXTURE_CUBE, // cube texture, suitable for all other geom types
mjTEXTURE_SKYBOX // cube texture used as skybox mjTEXTURE_SKYBOX // cube texture used as skybox
} mjtTexture; } mjtTexture;
typedef enum _mjtIntegrator // integrator mode typedef enum mjtIntegrator_ { // integrator mode
{
mjINT_EULER = 0, // semi-implicit Euler mjINT_EULER = 0, // semi-implicit Euler
mjINT_RK4 // 4th-order Runge Kutta mjINT_RK4 // 4th-order Runge Kutta
} mjtIntegrator; } mjtIntegrator;
typedef enum _mjtCollision // collision mode for selecting geom pairs typedef enum mjtCollision_ { // collision mode for selecting geom pairs
{
mjCOL_ALL = 0, // test precomputed and dynamic pairs mjCOL_ALL = 0, // test precomputed and dynamic pairs
mjCOL_PAIR, // test predefined pairs only mjCOL_PAIR, // test predefined pairs only
mjCOL_DYNAMIC // test dynamic pairs only mjCOL_DYNAMIC // test dynamic pairs only
} mjtCollision; } mjtCollision;
typedef enum _mjtCone // type of friction cone typedef enum mjtCone_ { // type of friction cone
{
mjCONE_PYRAMIDAL = 0, // pyramidal mjCONE_PYRAMIDAL = 0, // pyramidal
mjCONE_ELLIPTIC // elliptic mjCONE_ELLIPTIC // elliptic
} mjtCone; } mjtCone;
typedef enum _mjtJacobian // type of constraint Jacobian typedef enum mjtJacobian_ { // type of constraint Jacobian
{
mjJAC_DENSE = 0, // dense mjJAC_DENSE = 0, // dense
mjJAC_SPARSE, // sparse mjJAC_SPARSE, // sparse
mjJAC_AUTO // dense if nv<60, sparse otherwise mjJAC_AUTO // dense if nv<60, sparse otherwise
} mjtJacobian; } mjtJacobian;
typedef enum _mjtSolver // constraint solver algorithm typedef enum mjtSolver_ { // constraint solver algorithm
{
mjSOL_PGS = 0, // PGS (dual) mjSOL_PGS = 0, // PGS (dual)
mjSOL_CG, // CG (primal) mjSOL_CG, // CG (primal)
mjSOL_NEWTON // Newton (primal) mjSOL_NEWTON // Newton (primal)
} mjtSolver; } mjtSolver;
typedef enum _mjtEq // type of equality constraint typedef enum mjtEq_ { // type of equality constraint
{
mjEQ_CONNECT = 0, // connect two bodies at a point (ball joint) mjEQ_CONNECT = 0, // connect two bodies at a point (ball joint)
mjEQ_WELD, // fix relative position and orientation of two bodies mjEQ_WELD, // fix relative position and orientation of two bodies
mjEQ_JOINT, // couple the values of two scalar joints with cubic mjEQ_JOINT, // couple the values of two scalar joints with cubic
@@ -190,8 +177,7 @@ typedef enum _mjtEq // type of equality constraint
} mjtEq; } mjtEq;
typedef enum _mjtWrap // type of tendon wrap object typedef enum mjtWrap_ { // type of tendon wrap object
{
mjWRAP_NONE = 0, // null object mjWRAP_NONE = 0, // null object
mjWRAP_JOINT, // constant moment arm mjWRAP_JOINT, // constant moment arm
mjWRAP_PULLEY, // pulley used to split tendon mjWRAP_PULLEY, // pulley used to split tendon
@@ -201,8 +187,7 @@ typedef enum _mjtWrap // type of tendon wrap object
} mjtWrap; } mjtWrap;
typedef enum _mjtTrn // type of actuator transmission typedef enum mjtTrn_ { // type of actuator transmission
{
mjTRN_JOINT = 0, // force on joint mjTRN_JOINT = 0, // force on joint
mjTRN_JOINTINPARENT, // force on joint, expressed in parent frame mjTRN_JOINTINPARENT, // force on joint, expressed in parent frame
mjTRN_SLIDERCRANK, // force via slider-crank linkage mjTRN_SLIDERCRANK, // force via slider-crank linkage
@@ -213,8 +198,7 @@ typedef enum _mjtTrn // type of actuator transmission
} mjtTrn; } mjtTrn;
typedef enum _mjtDyn // type of actuator dynamics typedef enum mjtDyn_ { // type of actuator dynamics
{
mjDYN_NONE = 0, // no internal dynamics; ctrl specifies force mjDYN_NONE = 0, // no internal dynamics; ctrl specifies force
mjDYN_INTEGRATOR, // integrator: da/dt = u mjDYN_INTEGRATOR, // integrator: da/dt = u
mjDYN_FILTER, // linear filter: da/dt = (u-a) / tau mjDYN_FILTER, // linear filter: da/dt = (u-a) / tau
@@ -223,16 +207,14 @@ typedef enum _mjtDyn // type of actuator dynamics
} mjtDyn; } mjtDyn;
typedef enum _mjtGain // type of actuator gain typedef enum mjtGain_ { // type of actuator gain
{
mjGAIN_FIXED = 0, // fixed gain mjGAIN_FIXED = 0, // fixed gain
mjGAIN_MUSCLE, // muscle FLV curve computed by mju_muscleGain() mjGAIN_MUSCLE, // muscle FLV curve computed by mju_muscleGain()
mjGAIN_USER // user-defined gain type mjGAIN_USER // user-defined gain type
} mjtGain; } mjtGain;
typedef enum _mjtBias // type of actuator bias typedef enum mjtBias_ { // type of actuator bias
{
mjBIAS_NONE = 0, // no bias mjBIAS_NONE = 0, // no bias
mjBIAS_AFFINE, // const + kp*length + kv*velocity mjBIAS_AFFINE, // const + kp*length + kv*velocity
mjBIAS_MUSCLE, // muscle passive force computed by mju_muscleBias() mjBIAS_MUSCLE, // muscle passive force computed by mju_muscleBias()
@@ -240,8 +222,7 @@ typedef enum _mjtBias // type of actuator bias
} mjtBias; } mjtBias;
typedef enum _mjtObj // type of MujoCo object typedef enum mjtObj_ { // type of MujoCo object
{
mjOBJ_UNKNOWN = 0, // unknown object type mjOBJ_UNKNOWN = 0, // unknown object type
mjOBJ_BODY, // body mjOBJ_BODY, // body
mjOBJ_XBODY, // body, used to access regular frame instead of i-frame mjOBJ_XBODY, // body, used to access regular frame instead of i-frame
@@ -269,8 +250,7 @@ typedef enum _mjtObj // type of MujoCo object
} mjtObj; } mjtObj;
typedef enum _mjtConstraint // type of constraint typedef enum mjtConstraint_ { // type of constraint
{
mjCNSTR_EQUALITY = 0, // equality constraint mjCNSTR_EQUALITY = 0, // equality constraint
mjCNSTR_FRICTION_DOF, // dof friction mjCNSTR_FRICTION_DOF, // dof friction
mjCNSTR_FRICTION_TENDON, // tendon friction mjCNSTR_FRICTION_TENDON, // tendon friction
@@ -282,8 +262,7 @@ typedef enum _mjtConstraint // type of constraint
} mjtConstraint; } mjtConstraint;
typedef enum _mjtConstraintState // constraint state typedef enum mjtConstraintState_ { // constraint state
{
mjCNSTRSTATE_SATISFIED = 0, // constraint satisfied, zero cost (limit, contact) mjCNSTRSTATE_SATISFIED = 0, // constraint satisfied, zero cost (limit, contact)
mjCNSTRSTATE_QUADRATIC, // quadratic cost (equality, friction, limit, contact) mjCNSTRSTATE_QUADRATIC, // quadratic cost (equality, friction, limit, contact)
mjCNSTRSTATE_LINEARNEG, // linear cost, negative side (friction) mjCNSTRSTATE_LINEARNEG, // linear cost, negative side (friction)
@@ -292,8 +271,7 @@ typedef enum _mjtConstraintState // constraint state
} mjtConstraintState; } mjtConstraintState;
typedef enum _mjtSensor // type of sensor typedef enum mjtSensor_ { // type of sensor
{
// common robotic sensors, attached to a site // common robotic sensors, attached to a site
mjSENS_TOUCH = 0, // scalar contact normal forces summed over sensor zone mjSENS_TOUCH = 0, // scalar contact normal forces summed over sensor zone
mjSENS_ACCELEROMETER, // 3D linear acceleration, in local frame mjSENS_ACCELEROMETER, // 3D linear acceleration, in local frame
@@ -346,8 +324,7 @@ typedef enum _mjtSensor // type of sensor
} mjtSensor; } mjtSensor;
typedef enum _mjtStage // computation stage typedef enum mjtStage_ { // computation stage
{
mjSTAGE_NONE = 0, // no computations mjSTAGE_NONE = 0, // no computations
mjSTAGE_POS, // position-dependent computations mjSTAGE_POS, // position-dependent computations
mjSTAGE_VEL, // velocity-dependent computations mjSTAGE_VEL, // velocity-dependent computations
@@ -355,8 +332,7 @@ typedef enum _mjtStage // computation stage
} mjtStage; } mjtStage;
typedef enum _mjtDataType // data type for sensors typedef enum mjtDataType_ { // data type for sensors
{
mjDATATYPE_REAL = 0, // real values, no constraints mjDATATYPE_REAL = 0, // real values, no constraints
mjDATATYPE_POSITIVE, // positive values; 0 or negative: inactive mjDATATYPE_POSITIVE, // positive values; 0 or negative: inactive
mjDATATYPE_AXIS, // 3D unit vector mjDATATYPE_AXIS, // 3D unit vector
@@ -364,8 +340,7 @@ typedef enum _mjtDataType // data type for sensors
} mjtDataType; } mjtDataType;
typedef enum _mjtLRMode // mode for actuator length range computation typedef enum mjtLRMode_ { // mode for actuator length range computation
{
mjLRMODE_NONE = 0, // do not process any actuators mjLRMODE_NONE = 0, // do not process any actuators
mjLRMODE_MUSCLE, // process muscle actuators mjLRMODE_MUSCLE, // process muscle actuators
mjLRMODE_MUSCLEUSER, // process muscle and user actuators mjLRMODE_MUSCLEUSER, // process muscle and user actuators
@@ -373,10 +348,9 @@ typedef enum _mjtLRMode // mode for actuator length range computatio
} mjtLRMode; } mjtLRMode;
//------------------------------ mjLROpt ------------------------------------------------ //---------------------------------- mjLROpt -------------------------------------------------------
struct _mjLROpt // options for mj_setLengthRange() struct mjLROpt_ { // options for mj_setLengthRange()
{
// flags // flags
int mode; // which actuators to process (mjtLRMode) int mode; // which actuators to process (mjtLRMode)
int useexisting; // use existing length range if available int useexisting; // use existing length range if available
@@ -391,25 +365,23 @@ struct _mjLROpt // options for mj_setLengthRange()
mjtNum inteval; // evaluation time interval (at the end) mjtNum inteval; // evaluation time interval (at the end)
mjtNum tolrange; // convergence tolerance (relative to range) mjtNum tolrange; // convergence tolerance (relative to range)
}; };
typedef struct _mjLROpt mjLROpt; typedef struct mjLROpt_ mjLROpt;
//------------------------------ mjVFS -------------------------------------------------- //---------------------------------- mjVFS ---------------------------------------------------------
struct _mjVFS // virtual file system for loading from memory struct mjVFS_ { // virtual file system for loading from memory
{
int nfile; // number of files present int nfile; // number of files present
char filename[mjMAXVFS][mjMAXVFSNAME]; // file name without path char filename[mjMAXVFS][mjMAXVFSNAME]; // file name without path
int filesize[mjMAXVFS]; // file size in bytes int filesize[mjMAXVFS]; // file size in bytes
void* filedata[mjMAXVFS]; // buffer with file data void* filedata[mjMAXVFS]; // buffer with file data
}; };
typedef struct _mjVFS mjVFS; typedef struct mjVFS_ mjVFS;
//------------------------------ mjOption ----------------------------------------------- //---------------------------------- mjOption ------------------------------------------------------
struct _mjOption // physics options struct mjOption_ { // physics options
{
// timing parameters // timing parameters
mjtNum timestep; // timestep mjtNum timestep; // timestep
mjtNum apirate; // update rate for remote API (Hz) mjtNum apirate; // update rate for remote API (Hz)
@@ -444,15 +416,13 @@ struct _mjOption // physics options
int disableflags; // bit flags for disabling standard features int disableflags; // bit flags for disabling standard features
int enableflags; // bit flags for enabling optional features int enableflags; // bit flags for enabling optional features
}; };
typedef struct _mjOption mjOption; typedef struct mjOption_ mjOption;
//------------------------------ mjVisual ----------------------------------------------- //---------------------------------- mjVisual ------------------------------------------------------
struct _mjVisual // visualization options struct mjVisual_ { // visualization options
{ struct { // global parameters
struct // global parameters
{
float fovy; // y-field of view (deg) for free camera float fovy; // y-field of view (deg) for free camera
float ipd; // inter-pupilary distance for free camera float ipd; // inter-pupilary distance for free camera
float linewidth; // line width for wireframe and ray rendering float linewidth; // line width for wireframe and ray rendering
@@ -461,8 +431,7 @@ struct _mjVisual // visualization options
int offheight; // height of offscreen buffer int offheight; // height of offscreen buffer
} global; } global;
struct // rendering quality struct { // rendering quality
{
int shadowsize; // size of shadowmap texture int shadowsize; // size of shadowmap texture
int offsamples; // number of multisamples for offscreen rendering int offsamples; // number of multisamples for offscreen rendering
int numslices; // number of slices for builtin geom drawing int numslices; // number of slices for builtin geom drawing
@@ -470,16 +439,14 @@ struct _mjVisual // visualization options
int numquads; // number of quads for box rendering int numquads; // number of quads for box rendering
} quality; } quality;
struct // head light struct { // head light
{
float ambient[3]; // ambient rgb (alpha=1) float ambient[3]; // ambient rgb (alpha=1)
float diffuse[3]; // diffuse rgb (alpha=1) float diffuse[3]; // diffuse rgb (alpha=1)
float specular[3]; // specular rgb (alpha=1) float specular[3]; // specular rgb (alpha=1)
int active; // is headlight active int active; // is headlight active
} headlight; } headlight;
struct // mapping struct { // mapping
{
float stiffness; // mouse perturbation stiffness (space->force) float stiffness; // mouse perturbation stiffness (space->force)
float stiffnessrot; // mouse perturbation stiffness (space->torque) float stiffnessrot; // mouse perturbation stiffness (space->torque)
float force; // from force units to space units float force; // from force units to space units
@@ -495,8 +462,7 @@ struct _mjVisual // visualization options
float actuatortendon; // scale tendon width float actuatortendon; // scale tendon width
} map; } map;
struct // scale of decor elements relative to mean body size struct { // scale of decor elements relative to mean body size
{
float forcewidth; // width of force arrow float forcewidth; // width of force arrow
float contactwidth; // contact width float contactwidth; // contact width
float contactheight; // contact height float contactheight; // contact height
@@ -515,8 +481,7 @@ struct _mjVisual // visualization options
float slidercrank; // slidercrank width float slidercrank; // slidercrank width
} scale; } scale;
struct // color of decor elements struct { // color of decor elements
{
float fog[4]; // fog float fog[4]; // fog
float haze[4]; // haze float haze[4]; // haze
float force[4]; // external force float force[4]; // external force
@@ -541,26 +506,24 @@ struct _mjVisual // visualization options
float crankbroken[4]; // used when crank must be stretched/broken float crankbroken[4]; // used when crank must be stretched/broken
} rgba; } rgba;
}; };
typedef struct _mjVisual mjVisual; typedef struct mjVisual_ mjVisual;
//------------------------------ mjStatistic -------------------------------------------- //---------------------------------- mjStatistic ---------------------------------------------------
struct _mjStatistic // model statistics (in qpos0) struct mjStatistic_ { // model statistics (in qpos0)
{
mjtNum meaninertia; // mean diagonal inertia mjtNum meaninertia; // mean diagonal inertia
mjtNum meanmass; // mean body mass mjtNum meanmass; // mean body mass
mjtNum meansize; // mean body size mjtNum meansize; // mean body size
mjtNum extent; // spatial extent mjtNum extent; // spatial extent
mjtNum center[3]; // center of model mjtNum center[3]; // center of model
}; };
typedef struct _mjStatistic mjStatistic; typedef struct mjStatistic_ mjStatistic;
//---------------------------------- mjModel -------------------------------------------- //---------------------------------- mjModel -------------------------------------------------------
struct _mjModel struct mjModel_ {
{
// ------------------------------- sizes // ------------------------------- sizes
// sizes needed at mjModel construction // sizes needed at mjModel construction
@@ -952,6 +915,6 @@ struct _mjModel
int* name_keyadr; // keyframe name pointers (nkey x 1) int* name_keyadr; // keyframe name pointers (nkey x 1)
char* names; // names of all objects, 0-terminated (nnames x 1) char* names; // names of all objects, 0-terminated (nnames x 1)
}; };
typedef struct _mjModel mjModel; typedef struct mjModel_ mjModel;
#endif // MUJOCO_MJMODEL_H_ #endif // MUJOCO_MJMODEL_H_
Executable → Regular
+14 -14
View File
@@ -15,12 +15,15 @@
#ifndef MUJOCO_MJRENDER_H_ #ifndef MUJOCO_MJRENDER_H_
#define MUJOCO_MJRENDER_H_ #define MUJOCO_MJRENDER_H_
#include "mjmodel.h"
#define mjNAUX 10 // number of auxiliary buffers #define mjNAUX 10 // number of auxiliary buffers
#define mjMAXTEXTURE 1000 // maximum number of textures #define mjMAXTEXTURE 1000 // maximum number of textures
typedef enum _mjtGridPos // grid position for overlay //---------------------------------- primitive types (mjt) -----------------------------------------
{
typedef enum mjtGridPos_ { // grid position for overlay
mjGRID_TOPLEFT = 0, // top left mjGRID_TOPLEFT = 0, // top left
mjGRID_TOPRIGHT, // top right mjGRID_TOPRIGHT, // top right
mjGRID_BOTTOMLEFT, // bottom left mjGRID_BOTTOMLEFT, // bottom left
@@ -28,15 +31,13 @@ typedef enum _mjtGridPos // grid position for overlay
} mjtGridPos; } mjtGridPos;
typedef enum _mjtFramebuffer // OpenGL framebuffer option typedef enum mjtFramebuffer_ { // OpenGL framebuffer option
{
mjFB_WINDOW = 0, // default/window buffer mjFB_WINDOW = 0, // default/window buffer
mjFB_OFFSCREEN // offscreen buffer mjFB_OFFSCREEN // offscreen buffer
} mjtFramebuffer; } mjtFramebuffer;
typedef enum _mjtFontScale // font scale, used at context creation typedef enum mjtFontScale_ { // font scale, used at context creation
{
mjFONTSCALE_50 = 50, // 50% scale, suitable for low-res rendering mjFONTSCALE_50 = 50, // 50% scale, suitable for low-res rendering
mjFONTSCALE_100 = 100, // normal scale, suitable in the absence of DPI scaling mjFONTSCALE_100 = 100, // normal scale, suitable in the absence of DPI scaling
mjFONTSCALE_150 = 150, // 150% scale mjFONTSCALE_150 = 150, // 150% scale
@@ -46,26 +47,25 @@ typedef enum _mjtFontScale // font scale, used at context creation
} mjtFontScale; } mjtFontScale;
typedef enum _mjtFont // font type, used at each text operation typedef enum mjtFont_ { // font type, used at each text operation
{
mjFONT_NORMAL = 0, // normal font mjFONT_NORMAL = 0, // normal font
mjFONT_SHADOW, // normal font with shadow (for higher contrast) mjFONT_SHADOW, // normal font with shadow (for higher contrast)
mjFONT_BIG // big font (for user alerts) mjFONT_BIG // big font (for user alerts)
} mjtFont; } mjtFont;
struct _mjrRect // OpenGL rectangle struct mjrRect_ { // OpenGL rectangle
{
int left; // left (usually 0) int left; // left (usually 0)
int bottom; // bottom (usually 0) int bottom; // bottom (usually 0)
int width; // width (usually buffer width) int width; // width (usually buffer width)
int height; // height (usually buffer height) int height; // height (usually buffer height)
}; };
typedef struct _mjrRect mjrRect; typedef struct mjrRect_ mjrRect;
struct _mjrContext // custom OpenGL context //---------------------------------- mjrContext ----------------------------------------------------
{
struct mjrContext_ { // custom OpenGL context
// parameters copied from mjVisual // parameters copied from mjVisual
float lineWidth; // line width for wireframe rendering float lineWidth; // line width for wireframe rendering
float shadowClip; // clipping radius for directional lights float shadowClip; // clipping radius for directional lights
@@ -146,6 +146,6 @@ struct _mjrContext // custom OpenGL context
// framebuffer // framebuffer
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
}; };
typedef struct _mjrContext mjrContext; typedef struct mjrContext_ mjrContext;
#endif // MUJOCO_MJRENDER_H_ #endif // MUJOCO_MJRENDER_H_
Executable → Regular
+44 -41
View File
@@ -15,6 +15,8 @@
#ifndef MUJOCO_MJUI_H_ #ifndef MUJOCO_MJUI_H_
#define MUJOCO_MJUI_H_ #define MUJOCO_MJUI_H_
#include "mjrender.h"
#define mjMAXUISECT 10 // maximum number of sections #define mjMAXUISECT 10 // maximum number of sections
#define mjMAXUIITEM 80 // maximum number of items per section #define mjMAXUIITEM 80 // maximum number of items per section
#define mjMAXUITEXT 300 // maximum number of chars in edittext and other #define mjMAXUITEXT 300 // maximum number of chars in edittext and other
@@ -55,8 +57,9 @@
#define mjKEY_F12 301 #define mjKEY_F12 301
typedef enum _mjtButton // mouse button //---------------------------------- primitive types (mjt) -----------------------------------------
{
typedef enum mjtButton_ { // mouse button
mjBUTTON_NONE = 0, // no button mjBUTTON_NONE = 0, // no button
mjBUTTON_LEFT, // left button mjBUTTON_LEFT, // left button
mjBUTTON_RIGHT, // right button mjBUTTON_RIGHT, // right button
@@ -64,8 +67,7 @@ typedef enum _mjtButton // mouse button
} mjtButton; } mjtButton;
typedef enum _mjtEvent // mouse and keyboard event type typedef enum mjtEvent_ { // mouse and keyboard event type
{
mjEVENT_NONE = 0, // no event mjEVENT_NONE = 0, // no event
mjEVENT_MOVE, // mouse move mjEVENT_MOVE, // mouse move
mjEVENT_PRESS, // mouse button press mjEVENT_PRESS, // mouse button press
@@ -76,8 +78,7 @@ typedef enum _mjtEvent // mouse and keyboard event type
} mjtEvent; } mjtEvent;
typedef enum _mjtItem // UI item type typedef enum mjtItem_ { // UI item type
{
mjITEM_END = -2, // end of definition list (not an item) mjITEM_END = -2, // end of definition list (not an item)
mjITEM_SECTION = -1, // section (not an item) mjITEM_SECTION = -1, // section (not an item)
mjITEM_SEPARATOR = 0, // separator mjITEM_SEPARATOR = 0, // separator
@@ -104,8 +105,9 @@ typedef enum _mjtItem // UI item type
typedef int (*mjfItemEnable)(int category, void* data); typedef int (*mjfItemEnable)(int category, void* data);
struct _mjuiState // mouse and keyboard state //---------------------------------- mjuiState -----------------------------------------------------
{
struct mjuiState_ { // mouse and keyboard state
// constants set by user // constants set by user
int nrect; // number of rectangles used int nrect; // number of rectangles used
mjrRect rect[mjMAXUIRECT]; // rectangles (index 0: entire window) mjrRect rect[mjMAXUIRECT]; // rectangles (index 0: entire window)
@@ -142,11 +144,12 @@ struct _mjuiState // mouse and keyboard state
int dragrect; // which rectangle is dragged with mouse int dragrect; // which rectangle is dragged with mouse
int dragbutton; // which button started drag (mjtButton) int dragbutton; // which button started drag (mjtButton)
}; };
typedef struct _mjuiState mjuiState; typedef struct mjuiState_ mjuiState;
struct _mjuiThemeSpacing // UI visualization theme spacing //---------------------------------- mjuiThemeSpacing ----------------------------------------------
{
struct mjuiThemeSpacing_ { // UI visualization theme spacing
int total; // total width int total; // total width
int scroll; // scrollbar width int scroll; // scrollbar width
int label; // label width int label; // label width
@@ -159,11 +162,12 @@ struct _mjuiThemeSpacing // UI visualization theme spacing
int linescroll; // number of pixels to scroll int linescroll; // number of pixels to scroll
int samples; // number of multisamples int samples; // number of multisamples
}; };
typedef struct _mjuiThemeSpacing mjuiThemeSpacing; typedef struct mjuiThemeSpacing_ mjuiThemeSpacing;
struct _mjuiThemeColor // UI visualization theme color //---------------------------------- mjuiThemeColor ------------------------------------------------
{
struct mjuiThemeColor_ { // UI visualization theme color
float master[3]; // master background float master[3]; // master background
float thumb[3]; // scrollbar thumb float thumb[3]; // scrollbar thumb
float secttitle[3]; // section title float secttitle[3]; // section title
@@ -186,39 +190,36 @@ struct _mjuiThemeColor // UI visualization theme color
float edit2[3]; // edit invalid float edit2[3]; // edit invalid
float cursor[3]; // edit cursor float cursor[3]; // edit cursor
}; };
typedef struct _mjuiThemeColor mjuiThemeColor; typedef struct mjuiThemeColor_ mjuiThemeColor;
struct _mjuiItemSingle // check and button-related //---------------------------------- mjuiItem ------------------------------------------------------
{
struct mjuiItemSingle_ { // check and button-related
int modifier; // 0: none, 1: control, 2: shift; 4: alt int modifier; // 0: none, 1: control, 2: shift; 4: alt
int shortcut; // shortcut key; 0: undefined int shortcut; // shortcut key; 0: undefined
}; };
struct _mjuiItemMulti // static, radio and select-related struct mjuiItemMulti_ { // static, radio and select-related
{
int nelem; // number of elements in group int nelem; // number of elements in group
char name[mjMAXUIMULTI][mjMAXUINAME]; // element names char name[mjMAXUIMULTI][mjMAXUINAME]; // element names
}; };
struct _mjuiItemSlider // slider-related struct mjuiItemSlider_ { // slider-related
{
double range[2]; // slider range double range[2]; // slider range
double divisions; // number of range divisions double divisions; // number of range divisions
}; };
struct _mjuiItemEdit // edit-related struct mjuiItemEdit_ { // edit-related
{
int nelem; // number of elements in list int nelem; // number of elements in list
double range[mjMAXUIEDIT][2]; // element range (min>=max: ignore) double range[mjMAXUIEDIT][2]; // element range (min>=max: ignore)
}; };
struct _mjuiItem // UI item struct mjuiItem_ { // UI item
{
// common properties // common properties
int type; // type (mjtItem) int type; // type (mjtItem)
char name[mjMAXUINAME]; // name char name[mjMAXUINAME]; // name
@@ -228,22 +229,22 @@ struct _mjuiItem // UI item
int itemid; // id of item within section int itemid; // id of item within section
// type-specific properties // type-specific properties
union union {
{ struct mjuiItemSingle_ single; // check and button
struct _mjuiItemSingle single; // check and button struct mjuiItemMulti_ multi; // static, radio and select
struct _mjuiItemMulti multi; // static, radio and select struct mjuiItemSlider_ slider; // slider
struct _mjuiItemSlider slider; // slider struct mjuiItemEdit_ edit; // edit
struct _mjuiItemEdit edit; // edit
}; };
// internal // internal
mjrRect rect; // rectangle occupied by item mjrRect rect; // rectangle occupied by item
}; };
typedef struct _mjuiItem mjuiItem; typedef struct mjuiItem_ mjuiItem;
struct _mjuiSection // UI section //---------------------------------- mjuiSection ---------------------------------------------------
{
struct mjuiSection_ { // UI section
// properties // properties
char name[mjMAXUINAME]; // name char name[mjMAXUINAME]; // name
int state; // 0: closed, 1: open int state; // 0: closed, 1: open
@@ -256,11 +257,12 @@ struct _mjuiSection // UI section
mjrRect rtitle; // rectangle occupied by title mjrRect rtitle; // rectangle occupied by title
mjrRect rcontent; // rectangle occupied by content mjrRect rcontent; // rectangle occupied by content
}; };
typedef struct _mjuiSection mjuiSection; typedef struct mjuiSection_ mjuiSection;
struct _mjUI // entire UI //---------------------------------- mjUI ----------------------------------------------------------
{
struct mjUI_ { // entire UI
// constants set by user // constants set by user
mjuiThemeSpacing spacing; // UI theme spacing mjuiThemeSpacing spacing; // UI theme spacing
mjuiThemeColor color; // UI theme color mjuiThemeColor color; // UI theme color
@@ -293,17 +295,18 @@ struct _mjUI // entire UI
int nsect; // number of sections in use int nsect; // number of sections in use
mjuiSection sect[mjMAXUISECT]; // preallocated array of sections mjuiSection sect[mjMAXUISECT]; // preallocated array of sections
}; };
typedef struct _mjUI mjUI; typedef struct mjUI_ mjUI;
struct _mjuiDef // table passed to mjui_add() //---------------------------------- mjuiDef -------------------------------------------------------
{
struct mjuiDef_ { // table passed to mjui_add()
int type; // type (mjtItem); -1: section int type; // type (mjtItem); -1: section
char name[mjMAXUINAME]; // name char name[mjMAXUINAME]; // name
int state; // state int state; // state
void* pdata; // pointer to data void* pdata; // pointer to data
char other[mjMAXUITEXT]; // string with type-specific properties char other[mjMAXUITEXT]; // string with type-specific properties
}; };
typedef struct _mjuiDef mjuiDef; typedef struct mjuiDef_ mjuiDef;
#endif // MUJOCO_MJUI_H_ #endif // MUJOCO_MJUI_H_
Executable → Regular
+45 -42
View File
@@ -15,6 +15,8 @@
#ifndef MUJOCO_MJVISUALIZE_H_ #ifndef MUJOCO_MJVISUALIZE_H_
#define MUJOCO_MJVISUALIZE_H_ #define MUJOCO_MJVISUALIZE_H_
#include "mjmodel.h"
#define mjNGROUP 6 // number of geom, site, joint groups with visflags #define mjNGROUP 6 // number of geom, site, joint groups with visflags
#define mjMAXOVERLAY 500 // maximum number of characters in overlay text #define mjMAXOVERLAY 500 // maximum number of characters in overlay text
#define mjMAXLINE 100 // maximum number of lines per plot #define mjMAXLINE 100 // maximum number of lines per plot
@@ -22,8 +24,9 @@
#define mjMAXPLANEGRID 200 // maximum number of grid divisions for plane #define mjMAXPLANEGRID 200 // maximum number of grid divisions for plane
typedef enum _mjtCatBit // bitflags for mjvGeom category //---------------------------------- primitive types (mjt) -----------------------------------------
{
typedef enum mjtCatBit_ { // bitflags for mjvGeom category
mjCAT_STATIC = 1, // model elements in body 0 mjCAT_STATIC = 1, // model elements in body 0
mjCAT_DYNAMIC = 2, // model elements in all other bodies mjCAT_DYNAMIC = 2, // model elements in all other bodies
mjCAT_DECOR = 4, // decorative geoms mjCAT_DECOR = 4, // decorative geoms
@@ -31,8 +34,7 @@ typedef enum _mjtCatBit // bitflags for mjvGeom category
} mjtCatBit; } mjtCatBit;
typedef enum _mjtMouse // mouse interaction mode typedef enum mjtMouse_ { // mouse interaction mode
{
mjMOUSE_NONE = 0, // no action mjMOUSE_NONE = 0, // no action
mjMOUSE_ROTATE_V, // rotate, vertical plane mjMOUSE_ROTATE_V, // rotate, vertical plane
mjMOUSE_ROTATE_H, // rotate, horizontal plane mjMOUSE_ROTATE_H, // rotate, horizontal plane
@@ -43,15 +45,13 @@ typedef enum _mjtMouse // mouse interaction mode
} mjtMouse; } mjtMouse;
typedef enum _mjtPertBit // mouse perturbations typedef enum mjtPertBit_ { // mouse perturbations
{
mjPERT_TRANSLATE = 1, // translation mjPERT_TRANSLATE = 1, // translation
mjPERT_ROTATE = 2 // rotation mjPERT_ROTATE = 2 // rotation
} mjtPertBit; } mjtPertBit;
typedef enum _mjtCamera // abstract camera type typedef enum mjtCamera_ { // abstract camera type
{
mjCAMERA_FREE = 0, // free camera mjCAMERA_FREE = 0, // free camera
mjCAMERA_TRACKING, // tracking camera; uses trackbodyid mjCAMERA_TRACKING, // tracking camera; uses trackbodyid
mjCAMERA_FIXED, // fixed camera; uses fixedcamid mjCAMERA_FIXED, // fixed camera; uses fixedcamid
@@ -59,8 +59,7 @@ typedef enum _mjtCamera // abstract camera type
} mjtCamera; } mjtCamera;
typedef enum _mjtLabel // object labeling typedef enum mjtLabel_ { // object labeling
{
mjLABEL_NONE = 0, // nothing mjLABEL_NONE = 0, // nothing
mjLABEL_BODY, // body labels mjLABEL_BODY, // body labels
mjLABEL_JOINT, // joint labels mjLABEL_JOINT, // joint labels
@@ -80,8 +79,7 @@ typedef enum _mjtLabel // object labeling
} mjtLabel; } mjtLabel;
typedef enum _mjtFrame // frame visualization typedef enum mjtFrame_ { // frame visualization
{
mjFRAME_NONE = 0, // no frames mjFRAME_NONE = 0, // no frames
mjFRAME_BODY, // body frames mjFRAME_BODY, // body frames
mjFRAME_GEOM, // geom frames mjFRAME_GEOM, // geom frames
@@ -94,8 +92,7 @@ typedef enum _mjtFrame // frame visualization
} mjtFrame; } mjtFrame;
typedef enum _mjtVisFlag // flags enabling model element visualization typedef enum mjtVisFlag_ { // flags enabling model element visualization
{
mjVIS_CONVEXHULL = 0, // mesh convex hull mjVIS_CONVEXHULL = 0, // mesh convex hull
mjVIS_TEXTURE, // textures mjVIS_TEXTURE, // textures
mjVIS_JOINT, // joints mjVIS_JOINT, // joints
@@ -123,8 +120,7 @@ typedef enum _mjtVisFlag // flags enabling model element visualizatio
} mjtVisFlag; } mjtVisFlag;
typedef enum _mjtRndFlag // flags enabling rendering effects typedef enum mjtRndFlag_ { // flags enabling rendering effects
{
mjRND_SHADOW = 0, // shadows mjRND_SHADOW = 0, // shadows
mjRND_WIREFRAME, // wireframe mjRND_WIREFRAME, // wireframe
mjRND_REFLECTION, // reflections mjRND_REFLECTION, // reflections
@@ -139,16 +135,16 @@ typedef enum _mjtRndFlag // flags enabling rendering effects
} mjtRndFlag; } mjtRndFlag;
typedef enum _mjtStereo // type of stereo rendering typedef enum mjtStereo_ { // type of stereo rendering
{
mjSTEREO_NONE = 0, // no stereo; use left eye only mjSTEREO_NONE = 0, // no stereo; use left eye only
mjSTEREO_QUADBUFFERED, // quad buffered; revert to side-by-side if no hardware support mjSTEREO_QUADBUFFERED, // quad buffered; revert to side-by-side if no hardware support
mjSTEREO_SIDEBYSIDE // side-by-side mjSTEREO_SIDEBYSIDE // side-by-side
} mjtStereo; } mjtStereo;
struct _mjvPerturb // object selection and perturbation //---------------------------------- mjvPerturb ----------------------------------------------------
{
struct mjvPerturb_ { // object selection and perturbation
int select; // selected body id; non-positive: none int select; // selected body id; non-positive: none
int skinselect; // selected skin id; negative: none int skinselect; // selected skin id; negative: none
int active; // perturbation bitmask (mjtPertBit) int active; // perturbation bitmask (mjtPertBit)
@@ -158,11 +154,12 @@ struct _mjvPerturb // object selection and perturbation
mjtNum localpos[3]; // selection point in object coordinates mjtNum localpos[3]; // selection point in object coordinates
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb) mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
}; };
typedef struct _mjvPerturb mjvPerturb; typedef struct mjvPerturb_ mjvPerturb;
struct _mjvCamera // abstract camera //---------------------------------- mjvCamera -----------------------------------------------------
{
struct mjvCamera_ { // abstract camera
// type and ids // type and ids
int type; // camera type (mjtCamera) int type; // camera type (mjtCamera)
int fixedcamid; // fixed camera id int fixedcamid; // fixed camera id
@@ -174,11 +171,12 @@ struct _mjvCamera // abstract camera
mjtNum azimuth; // camera azimuth (deg) mjtNum azimuth; // camera azimuth (deg)
mjtNum elevation; // camera elevation (deg) mjtNum elevation; // camera elevation (deg)
}; };
typedef struct _mjvCamera mjvCamera; typedef struct mjvCamera_ mjvCamera;
struct _mjvGLCamera // OpenGL camera //---------------------------------- mjvGLCamera ---------------------------------------------------
{
struct mjvGLCamera_ { // OpenGL camera
// camera frame // camera frame
float pos[3]; // position float pos[3]; // position
float forward[3]; // forward direction float forward[3]; // forward direction
@@ -191,11 +189,12 @@ struct _mjvGLCamera // OpenGL camera
float frustum_near; // near float frustum_near; // near
float frustum_far; // far float frustum_far; // far
}; };
typedef struct _mjvGLCamera mjvGLCamera; typedef struct mjvGLCamera_ mjvGLCamera;
struct _mjvGeom // abstract geom //---------------------------------- mjvGeom -------------------------------------------------------
{
struct mjvGeom_ { // abstract geom
// type info // type info
int type; // geom type (mjtGeom) int type; // geom type (mjtGeom)
int dataid; // mesh, hfield or plane id; -1: none int dataid; // mesh, hfield or plane id; -1: none
@@ -224,11 +223,12 @@ struct _mjvGeom // abstract geom
float modelrbound; // geom rbound from model, 0 if not model geom float modelrbound; // geom rbound from model, 0 if not model geom
mjtByte transparent; // treat geom as transparent mjtByte transparent; // treat geom as transparent
}; };
typedef struct _mjvGeom mjvGeom; typedef struct mjvGeom_ mjvGeom;
struct _mjvLight // OpenGL light //---------------------------------- mjvLight ------------------------------------------------------
{
struct mjvLight_ { // OpenGL light
float pos[3]; // position rel. to body frame float pos[3]; // position rel. to body frame
float dir[3]; // direction rel. to body frame float dir[3]; // direction rel. to body frame
float attenuation[3]; // OpenGL attenuation (quadratic model) float attenuation[3]; // OpenGL attenuation (quadratic model)
@@ -241,11 +241,12 @@ struct _mjvLight // OpenGL light
mjtByte directional; // directional light mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows mjtByte castshadow; // does light cast shadows
}; };
typedef struct _mjvLight mjvLight; typedef struct mjvLight_ mjvLight;
struct _mjvOption // abstract visualization options //---------------------------------- mjvOption -----------------------------------------------------
{
struct mjvOption_ { // abstract visualization options
int label; // what objects to label (mjtLabel) int label; // what objects to label (mjtLabel)
int frame; // which frame to show (mjtFrame) int frame; // which frame to show (mjtFrame)
mjtByte geomgroup[mjNGROUP]; // geom visualization by group mjtByte geomgroup[mjNGROUP]; // geom visualization by group
@@ -255,11 +256,12 @@ struct _mjvOption // abstract visualization options
mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group
mjtByte flags[mjNVISFLAG]; // visualization flags (indexed by mjtVisFlag) mjtByte flags[mjNVISFLAG]; // visualization flags (indexed by mjtVisFlag)
}; };
typedef struct _mjvOption mjvOption; typedef struct mjvOption_ mjvOption;
struct _mjvScene // abstract scene passed to OpenGL renderer //---------------------------------- mjvScene ------------------------------------------------------
{
struct mjvScene_ { // abstract scene passed to OpenGL renderer
// abstract geoms // abstract geoms
int maxgeom; // size of allocated geom buffer int maxgeom; // size of allocated geom buffer
int ngeom; // number of geoms currently in buffer int ngeom; // number of geoms currently in buffer
@@ -295,11 +297,12 @@ struct _mjvScene // abstract scene passed to OpenGL renderer
int framewidth; // frame pixel width; 0: disable framing int framewidth; // frame pixel width; 0: disable framing
float framergb[3]; // frame color float framergb[3]; // frame color
}; };
typedef struct _mjvScene mjvScene; typedef struct mjvScene_ mjvScene;
struct _mjvFigure // abstract 2D figure passed to OpenGL renderer //---------------------------------- mjvFigure -----------------------------------------------------
{
struct mjvFigure_ { // abstract 2D figure passed to OpenGL renderer
// enable flags // enable flags
int flg_legend; // show legend int flg_legend; // show legend
int flg_ticklabel[2]; // show grid tick labels (x,y) int flg_ticklabel[2]; // show grid tick labels (x,y)
@@ -345,6 +348,6 @@ struct _mjvFigure // abstract 2D figure passed to OpenGL rende
float xaxisdata[2]; // range of x-axis in data units float xaxisdata[2]; // range of x-axis in data units
float yaxisdata[2]; // range of y-axis in data units float yaxisdata[2]; // range of y-axis in data units
}; };
typedef struct _mjvFigure mjvFigure; typedef struct mjvFigure_ mjvFigure;
#endif // MUJOCO_MJVISUALIZE_H_ #endif // MUJOCO_MJVISUALIZE_H_
Executable → Regular
+32 -1
View File
@@ -18,7 +18,7 @@
//-------------------------------- mjOption --------------------------------------------- //-------------------------------- mjOption ---------------------------------------------
// scalar fields of mjOption // scalar fields of mjOption
#define MJOPTION_SCALARS \ #define MJOPTION_FLOATS \
X( mjtNum, timestep ) \ X( mjtNum, timestep ) \
X( mjtNum, apirate ) \ X( mjtNum, apirate ) \
X( mjtNum, impratio ) \ X( mjtNum, impratio ) \
@@ -28,6 +28,9 @@
X( mjtNum, density ) \ X( mjtNum, density ) \
X( mjtNum, viscosity ) \ X( mjtNum, viscosity ) \
X( mjtNum, o_margin ) \ X( mjtNum, o_margin ) \
#define MJOPTION_INTS \
X( int, integrator ) \ X( int, integrator ) \
X( int, collision ) \ X( int, collision ) \
X( int, cone ) \ X( int, cone ) \
@@ -40,6 +43,11 @@
X( int, enableflags ) X( int, enableflags )
#define MJOPTION_SCALARS \
MJOPTION_FLOATS \
MJOPTION_INTS
// vector fields of mjOption // vector fields of mjOption
#define MJOPTION_VECTORS \ #define MJOPTION_VECTORS \
X( gravity, 3 ) \ X( gravity, 3 ) \
@@ -113,6 +121,23 @@
X( nbuffer ) X( nbuffer )
// define symbols needed in MJMODEL_POINTERS (corresponding to number of columns)
#define MJMODEL_POINTERS_PREAMBLE( m ) \
int nuser_body = m->nuser_body; \
int nuser_jnt = m->nuser_jnt; \
int nuser_geom = m->nuser_geom; \
int nuser_site = m->nuser_site; \
int nuser_cam = m->nuser_cam; \
int nuser_tendon = m->nuser_tendon; \
int nuser_actuator = m->nuser_actuator; \
int nuser_sensor = m->nuser_sensor; \
int nq = m->nq; \
int nv = m->nv; \
int na = m->na; \
int nmocap3 = 3*m->nmocap; \
int nmocap4 = 4*m->nmocap;
// pointer fields of mjModel // pointer fields of mjModel
#define MJMODEL_POINTERS \ #define MJMODEL_POINTERS \
X( mjtNum, qpos0, nq, 1 ) \ X( mjtNum, qpos0, nq, 1 ) \
@@ -386,6 +411,12 @@
//-------------------------------- mjData ----------------------------------------------- //-------------------------------- mjData -----------------------------------------------
// define symbols needed in MJDATA_POINTERS (corresponding to number of columns)
#define MJDATA_POINTERS_PREAMBLE( m ) \
int nv = m->nv; \
int njmax = m->njmax;
// pointer fields of mjData // pointer fields of mjData
#define MJDATA_POINTERS \ #define MJDATA_POINTERS \
X( mjtNum, qpos, nq, 1 ) \ X( mjtNum, qpos, nq, 1 ) \
Executable → Regular
+31 -34
View File
@@ -15,27 +15,16 @@
#ifndef MUJOCO_MUJOCO_H_ #ifndef MUJOCO_MUJOCO_H_
#define MUJOCO_MUJOCO_H_ #define MUJOCO_MUJOCO_H_
// cross-platform import #include "mujoco_export.h"
#if defined(MJ_STATIC)
#define MJAPI
#else
#if defined(_WIN32)
#define MJAPI __declspec(dllimport)
#else
#define MJAPI
#endif
#endif
// this is a C-API // this is a C-API
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" extern "C" {
{
#endif #endif
// header version; should match the library version as returned by mj_version() // header version; should match the library version as returned by mj_version()
#define mjVERSION_HEADER 210 #define mjVERSION_HEADER 211
// needed to define size_t, fabs and log10 // needed to define size_t, fabs and log10
#include "stdlib.h" #include "stdlib.h"
@@ -89,7 +78,7 @@ MJAPI extern const char* mjVISSTRING[mjNVISFLAG][3];
MJAPI extern const char* mjRNDSTRING[mjNRNDFLAG][3]; MJAPI extern const char* mjRNDSTRING[mjNRNDFLAG][3];
//---------------------- Activation ----------------------------------------------------- //---------------------------------- Activation ----------------------------------------------------
// Return 1 (for backward compatibility). // Return 1 (for backward compatibility).
MJAPI int mj_activate(const char* filename); MJAPI int mj_activate(const char* filename);
@@ -98,7 +87,7 @@ MJAPI int mj_activate(const char* filename);
MJAPI void mj_deactivate(void); MJAPI void mj_deactivate(void);
//---------------------- Virtual file system -------------------------------------------- //---------------------------------- Virtual file system -------------------------------------------
// Initialize VFS to empty (no deallocation). // Initialize VFS to empty (no deallocation).
MJAPI void mj_defaultVFS(mjVFS* vfs); MJAPI void mj_defaultVFS(mjVFS* vfs);
@@ -119,7 +108,7 @@ MJAPI int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
MJAPI void mj_deleteVFS(mjVFS* vfs); MJAPI void mj_deleteVFS(mjVFS* vfs);
//---------------------- Parse and compile ---------------------------------------------- //---------------------------------- Parse and compile ---------------------------------------------
// Parse XML file in MJCF or URDF format, compile it, return low-level model. // Parse XML file in MJCF or URDF format, compile it, return low-level model.
// If vfs is not NULL, look up files in vfs before reading from disk. // If vfs is not NULL, look up files in vfs before reading from disk.
@@ -140,7 +129,7 @@ MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
int flg_html, int flg_pad); int flg_html, int flg_pad);
//---------------------- Main simulation ------------------------------------------------ //---------------------------------- Main simulation -----------------------------------------------
// Advance simulation, use control callback to obtain external force and control. // Advance simulation, use control callback to obtain external force and control.
MJAPI void mj_step(const mjModel* m, mjData* d); MJAPI void mj_step(const mjModel* m, mjData* d);
@@ -166,7 +155,7 @@ MJAPI void mj_inverseSkip(const mjModel* m, mjData* d,
int skipstage, int skipsensor); int skipstage, int skipsensor);
//---------------------- Initialization ------------------------------------------------- //---------------------------------- Initialization ------------------------------------------------
// Set default options for length range computation. // Set default options for length range computation.
MJAPI void mj_defaultLROpt(mjLROpt* opt); MJAPI void mj_defaultLROpt(mjLROpt* opt);
@@ -228,7 +217,12 @@ MJAPI int mj_setLengthRange(mjModel* m, mjData* d, int index,
const mjLROpt* opt, char* error, int error_sz); const mjLROpt* opt, char* error, int error_sz);
//---------------------- Printing ------------------------------------------------------- //---------------------------------- Printing ------------------------------------------------------
// Print mjModel to text file, specifying format.
// float_format_str must be a valid printf-style format string for a single float value.
MJAPI void mj_printFormattedModel(const mjModel* m, const char* filename,
const char* float_format_str);
// Print model to text file. // Print model to text file.
MJAPI void mj_printModel(const mjModel* m, const char* filename); MJAPI void mj_printModel(const mjModel* m, const char* filename);
@@ -245,7 +239,7 @@ MJAPI void mju_printMatSparse(const mjtNum* mat, int nr,
const int* colind); const int* colind);
//---------------------- Components ----------------------------------------------------- //---------------------------------- Components ----------------------------------------------------
// Run position-dependent computations. // Run position-dependent computations.
MJAPI void mj_fwdPosition(const mjModel* m, mjData* d); MJAPI void mj_fwdPosition(const mjModel* m, mjData* d);
@@ -281,7 +275,7 @@ MJAPI void mj_invConstraint(const mjModel* m, mjData* d);
MJAPI void mj_compareFwdInv(const mjModel* m, mjData* d); MJAPI void mj_compareFwdInv(const mjModel* m, mjData* d);
//---------------------- Sub components ------------------------------------------------- //---------------------------------- Sub components ------------------------------------------------
// Evaluate position-dependent sensors. // Evaluate position-dependent sensors.
MJAPI void mj_sensorPos(const mjModel* m, mjData* d); MJAPI void mj_sensorPos(const mjModel* m, mjData* d);
@@ -367,7 +361,7 @@ MJAPI void mj_constraintUpdate(const mjModel* m, mjData* d, const mjtNum* jar,
mjtNum* cost, int flg_coneHessian); mjtNum* cost, int flg_coneHessian);
//---------------------- Support -------------------------------------------------------- //---------------------------------- Support -------------------------------------------------------
// Add contact to d->contact list; return 0 if success; 1 if buffer full. // Add contact to d->contact list; return 0 if success; 1 if buffer full.
MJAPI int mj_addContact(const mjModel* m, mjData* d, const mjContact* con); MJAPI int mj_addContact(const mjModel* m, mjData* d, const mjContact* con);
@@ -473,8 +467,11 @@ MJAPI void mj_setTotalmass(mjModel* m, mjtNum newmass);
// Return version number: 1.0.2 is encoded as 102. // Return version number: 1.0.2 is encoded as 102.
MJAPI int mj_version(void); MJAPI int mj_version(void);
// Return the current version of MuJoCo as a null-terminated string.
MJAPI const char* mj_versionString();
//---------------------- Ray collisions -------------------------------------------------
//---------------------------------- Ray collisions ------------------------------------------------
// Intersect ray (pnt+x*vec, x>=0) with visible geoms, except geoms in bodyexclude. // Intersect ray (pnt+x*vec, x>=0) with visible geoms, except geoms in bodyexclude.
// Return geomid and distance (x) to nearest surface, or -1 if no intersection. // Return geomid and distance (x) to nearest surface, or -1 if no intersection.
@@ -500,7 +497,7 @@ MJAPI mjtNum mju_raySkin(int nface, int nvert, const int* face, const float* ver
const mjtNum* pnt, const mjtNum* vec, int* vertid); const mjtNum* pnt, const mjtNum* vec, int* vertid);
//---------------------- Interaction ---------------------------------------------------- //---------------------------------- Interaction ---------------------------------------------------
// Set default camera. // Set default camera.
MJAPI void mjv_defaultCamera(mjvCamera* cam); MJAPI void mjv_defaultCamera(mjvCamera* cam);
@@ -563,7 +560,7 @@ MJAPI int mjv_select(const mjModel* m, const mjData* d, const mjvOption* vopt,
const mjvScene* scn, mjtNum* selpnt, int* geomid, int* skinid); const mjvScene* scn, mjtNum* selpnt, int* geomid, int* skinid);
//---------------------- Visualization -------------------------------------------------- //---------------------------------- Visualization -------------------------------------------------
// Set default visualization options. // Set default visualization options.
MJAPI void mjv_defaultOption(mjvOption* opt); MJAPI void mjv_defaultOption(mjvOption* opt);
@@ -608,7 +605,7 @@ MJAPI void mjv_updateCamera(const mjModel* m, mjData* d, mjvCamera* cam, mjvScen
MJAPI void mjv_updateSkin(const mjModel* m, mjData* d, mjvScene* scn); MJAPI void mjv_updateSkin(const mjModel* m, mjData* d, mjvScene* scn);
//---------------------- OpenGL rendering ----------------------------------------------- //---------------------------------- OpenGL rendering ----------------------------------------------
// Set default mjrContext. // Set default mjrContext.
MJAPI void mjr_defaultContext(mjrContext* con); MJAPI void mjr_defaultContext(mjrContext* con);
@@ -698,7 +695,7 @@ MJAPI int mjr_getError(void);
MJAPI int mjr_findRect(int x, int y, int nrect, const mjrRect* rect); MJAPI int mjr_findRect(int x, int y, int nrect, const mjrRect* rect);
//---------------------- UI framework --------------------------------------------------- //---------------------------------- UI framework --------------------------------------------------
// Get builtin UI theme spacing (ind: 0-1). // Get builtin UI theme spacing (ind: 0-1).
MJAPI mjuiThemeSpacing mjui_themeSpacing(int ind); MJAPI mjuiThemeSpacing mjui_themeSpacing(int ind);
@@ -726,7 +723,7 @@ MJAPI mjuiItem* mjui_event(mjUI* ui, mjuiState* state, const mjrContext* con);
MJAPI void mjui_render(mjUI* ui, const mjuiState* state, const mjrContext* con); MJAPI void mjui_render(mjUI* ui, const mjuiState* state, const mjrContext* con);
//---------------------- Error and memory ----------------------------------------------- //---------------------------------- Error and memory ----------------------------------------------
// Main error function; does not return to caller. // Main error function; does not return to caller.
MJAPI void mju_error(const char* msg); MJAPI void mju_error(const char* msg);
@@ -762,7 +759,7 @@ MJAPI void mj_warning(mjData* d, int warning, int info);
MJAPI void mju_writeLog(const char* type, const char* msg); MJAPI void mju_writeLog(const char* type, const char* msg);
//---------------------- Standard math -------------------------------------------------- //---------------------------------- Standard math -------------------------------------------------
#define mjMAX(a,b) (((a) > (b)) ? (a) : (b)) #define mjMAX(a,b) (((a) > (b)) ? (a) : (b))
#define mjMIN(a,b) (((a) < (b)) ? (a) : (b)) #define mjMIN(a,b) (((a) < (b)) ? (a) : (b))
@@ -803,7 +800,7 @@ MJAPI void mju_writeLog(const char* type, const char* msg);
#endif #endif
//------------------------------ Vector math -------------------------------------------- //---------------------------------- Vector math ---------------------------------------------------
// Set res = 0. // Set res = 0.
MJAPI void mju_zero3(mjtNum res[3]); MJAPI void mju_zero3(mjtNum res[3]);
@@ -940,7 +937,7 @@ MJAPI void mju_transformSpatial(mjtNum res[6], const mjtNum vec[6], int flg_forc
const mjtNum rotnew2old[9]); const mjtNum rotnew2old[9]);
//---------------------- Quaternions ---------------------------------------------------- //---------------------------------- Quaternions ---------------------------------------------------
// Rotate vector by quaternion. // Rotate vector by quaternion.
MJAPI void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]); MJAPI void mju_rotVecQuat(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]);
@@ -979,7 +976,7 @@ MJAPI void mju_quatIntegrate(mjtNum quat[4], const mjtNum vel[3], mjtNum scale);
MJAPI void mju_quatZ2Vec(mjtNum quat[4], const mjtNum vec[3]); MJAPI void mju_quatZ2Vec(mjtNum quat[4], const mjtNum vec[3]);
//---------------------- Poses ---------------------------------------------------------- //---------------------------------- Poses ---------------------------------------------------------
// Multiply two poses. // Multiply two poses.
MJAPI void mju_mulPose(mjtNum posres[3], mjtNum quatres[4], MJAPI void mju_mulPose(mjtNum posres[3], mjtNum quatres[4],
@@ -995,7 +992,7 @@ MJAPI void mju_trnVecPose(mjtNum res[3], const mjtNum pos[3], const mjtNum quat[
const mjtNum vec[3]); const mjtNum vec[3]);
//---------------------- Decompositions -------------------------------------------------- //--------------------------------- Decompositions -------------------------------------------------
// Cholesky decomposition: mat = L*L'; return rank. // Cholesky decomposition: mat = L*L'; return rank.
MJAPI int mju_cholFactor(mjtNum* mat, int n, mjtNum mindiag); MJAPI int mju_cholFactor(mjtNum* mat, int n, mjtNum mindiag);
+47
View File
@@ -0,0 +1,47 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_MUJOCO_EXPORT_H_
#define MUJOCO_MUJOCO_EXPORT_H_
#if defined _WIN32 || defined __CYGWIN__
#define MUJOCO_HELPER_DLL_IMPORT __declspec(dllimport)
#define MUJOCO_HELPER_DLL_EXPORT __declspec(dllexport)
#define MUJOCO_HELPER_DLL_LOCAL
#else
#if __GNUC__ >= 4
#define MUJOCO_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
#define MUJOCO_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
#define MUJOCO_HELPER_DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define MUJOCO_HELPER_DLL_IMPORT
#define MUJOCO_HELPER_DLL_EXPORT
#define MUJOCO_HELPER_DLL_LOCAL
#endif
#endif
#ifdef MJ_STATIC
// static library
#define MJAPI
#define MJLOCAL
#else
#ifdef MUJOCO_DLL_EXPORTS
#define MJAPI MUJOCO_HELPER_DLL_EXPORT
#else
#define MJAPI MUJOCO_HELPER_DLL_IMPORT
#endif
#define MJLOCAL MUJOCO_HELPER_DLL_LOCAL
#endif
#endif // MUJOCO_MUJOCO_EXPORT_H_
-1
View File
@@ -14,7 +14,6 @@
--> -->
<mujoco model="Cloth"> <mujoco model="Cloth">
<include file="scene.xml"/> <include file="scene.xml"/>
<option timestep="0.002" solver="CG" tolerance="1e-6"/> <option timestep="0.002" solver="CG" tolerance="1e-6"/>
-29
View File
@@ -1,29 +0,0 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="1D grid">
<include file="scene.xml"/>
<size nconmax="50" njmax="300" nstack="50000"/>
<worldbody>
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
<joint kind="main" damping="0.001"/>
<tendon kind="main" width="0.01"/>
<geom size=".02" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco>
-31
View File
@@ -1,31 +0,0 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="1D grid with pins">
<include file="scene.xml"/>
<size nconmax="50" njmax="300" nstack="50000"/>
<worldbody>
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
<joint kind="main" damping="0.001"/>
<tendon kind="main" width="0.01"/>
<pin coord="1"/>
<pin coord="13"/>
<geom size=".02" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco>
-28
View File
@@ -1,28 +0,0 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="2D grid">
<include file="scene.xml"/>
<size nconmax="300" njmax="1000" nstack="1000000"/>
<worldbody>
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
<geom size=".02"/>
</composite>
</worldbody>
</mujoco>
-1
View File
@@ -14,7 +14,6 @@
--> -->
<mujoco model="2D grid with pins"> <mujoco model="2D grid with pins">
<include file="scene.xml"/> <include file="scene.xml"/>
<size nconmax="200" njmax="1000" nstack="1000000"/> <size nconmax="200" njmax="1000" nstack="1000000"/>
-1
View File
@@ -14,7 +14,6 @@
--> -->
<mujoco model="Loop"> <mujoco model="Loop">
<include file="scene.xml"/> <include file="scene.xml"/>
<option timestep="0.002" jacobian="dense"/> <option timestep="0.002" jacobian="dense"/>
+16 -4
View File
@@ -14,20 +14,32 @@
--> -->
<mujoco model="Particle"> <mujoco model="Particle">
<!-- Degree of Freedom: 3000
Actuators: 0
-->
<include file="scene.xml"/> <include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/> <option solver="CG" tolerance="1e-6" timestep=".01"/>
<size nconmax="3000" njmax="3000" nstack="50000000"/> <size nconmax="6000" njmax="6000" nstack="50000000"/>
<visual> <visual>
<map stiffness="100"/> <map stiffness="100"/>
</visual> </visual>
<default>
<default class="wall">
<geom type="plane" size=".5 .5 .05"/>
</default>
</default>
<worldbody> <worldbody>
<geom name="+x" class="wall" zaxis="1 0 0" pos="-.5 0 -.25"/>
<geom name="-x" class="wall" zaxis="-1 0 0" pos=".5 0 -.25"/>
<geom name="+y" class="wall" zaxis="0 1 0" pos="0 -.5 -.25"/>
<geom name="-y" class="wall" zaxis="0 -1 0" pos="0 .5 -.25"/>
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1"> <composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
<geom size=".02" rgba=".8 .2 .1 1"/> <geom size=".025" rgba=".8 .2 .1 1"/>
</composite> </composite>
</worldbody> </worldbody>
</mujoco> </mujoco>
-1
View File
@@ -14,7 +14,6 @@
--> -->
<mujoco model="Rope"> <mujoco model="Rope">
<include file="scene.xml"/> <include file="scene.xml"/>
<option timestep="0.002" jacobian="dense"/> <option timestep="0.002" jacobian="dense"/>
+4 -4
View File
@@ -14,14 +14,14 @@
--> -->
<mujoco> <mujoco>
<compiler meshdir="asset" texturedir="asset"/>
<statistic extent="1.5" meansize=".05"/>
<statistic extent="2" meansize=".05"/> <option timestep="0.005" jacobian="sparse"/>
<option timestep="0.005" solver="Newton" iterations="30" tolerance="1e-10" jacobian="sparse" cone="pyramidal"/>
<visual> <visual>
<rgba haze="0.15 0.25 0.35 1"/> <rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/> <quality shadowsize="4096"/>
<map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/> <map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/>
</visual> </visual>
+5 -1
View File
@@ -14,7 +14,10 @@
--> -->
<mujoco model="Soft box"> <mujoco model="Soft box">
<!-- Degree of Freedom: 224
Actuators: 0
Equality constraints: 651
-->
<include file="scene.xml"/> <include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/> <option solver="CG" tolerance="1e-6"/>
@@ -27,6 +30,7 @@
<composite type="box" count="7 7 7" spacing="0.04"> <composite type="box" count="7 7 7" spacing="0.04">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/> <skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/> <geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
<joint kind="main" solreffix="0.03 1" solimpfix="0 .1 .01"/>
</composite> </composite>
</body> </body>
</worldbody> </worldbody>
-33
View File
@@ -1,33 +0,0 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Soft cylinder">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="500" njmax="5000" nstack="5000000"/>
<worldbody>
<body pos="0 0 1">
<freejoint/>
<composite type="cylinder" count="5 7 9" spacing="0.05">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
-33
View File
@@ -1,33 +0,0 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Soft ellipsoid">
<include file="scene.xml"/>
<option solver="CG" tolerance="1e-6"/>
<size nconmax="500" njmax="5000" nstack="5000000"/>
<worldbody>
<body pos="0 0 1">
<freejoint/>
<composite type="ellipsoid" count="5 7 9" spacing="0.05">
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco>
+44
View File
@@ -0,0 +1,44 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Flag">
<!-- Degree of Freedom (nv): 340
Tendons (ntendon): 288
Actuators (nu): 0
Constraints (nefc): 0
This model of a flag passively flapping in the wind has no constraints and is designed to
exert smooth dynamics computations.
-->
<statistic center=".4 0 .8" extent="1.3"/>
<option wind="5 5 0" density="10">
<flag constraint="disable"/>
</option>
<worldbody>
<geom name="floor" type="plane" size="0 0 .1"/>
<light diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
<body name="B0_0" pos="0 0 1">
<composite type="cloth" count="9 19 1" spacing="0.05" flatinertia="0.01">
<joint kind="main" damping="0.001" stiffness=".1"/>
<skin texcoord="true" inflate="0.005" subgrid="4"/>
<geom type="ellipsoid" size="0.025 0.01 0.025" rgba=".8 .2 .1 1"/>
<tendon kind="main" stiffness="100" damping=".001"/>
<tendon kind="shear" stiffness="100" damping=".001"/>
</composite>
</body>
</worldbody>
</mujoco>
Executable → Regular
+18 -120
View File
@@ -14,18 +14,15 @@
--> -->
<mujoco model="Hammock"> <mujoco model="Hammock">
<!-- Degree of Freedom: 312
Actuators: 21
Equality constraints: 178
Tendons: 178
<compiler inertiafromgeom="true" angle="degree"/> Simple humanoid on a hammock, implemented as a 2D grid composite, pinned at the corners.
-->
<default> <option timestep="0.005" solver="CG" iterations="30" tolerance="1e-6"/>
<default class="humanoid">
<joint limited="true" damping="1" armature="0"/>
<geom condim="1" material="matgeom"/>
</default>
<motor ctrlrange="-.4 .4" ctrllimited="true"/>
</default>
<option timestep="0.005" solver="CG" iterations="30" tolerance="1e-6" jacobian="sparse" cone="pyramidal"/>
<size njmax="1000" nconmax="100" nstack="1000000"/> <size njmax="1000" nconmax="100" nstack="1000000"/>
@@ -38,28 +35,22 @@
<asset> <asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/> <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<texture name="plane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/> width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture name="hammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1"
<texture name="texhammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1" width="512" height="512" mark="edge" markrgb=".8 .8 .8"/> width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
<material name="plane" reflectance="0.3" texture="plane" texrepeat="1 1" texuniform="true"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278" <material name="hammock" texture="hammock"/>
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name="mathammock" texture="texhammock"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
</asset> </asset>
<include file="humanoid_body.xml"/>
<worldbody> <worldbody>
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="matplane" condim="3"/> <geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="plane" condim="3"/>
<light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/> <light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
<light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/> <light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4" dir="0 0 -1"/>
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0"> <composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
<skin texcoord="true" material="mathammock" inflate="0.01" subgrid="3"/> <skin texcoord="true" material="hammock" inflate="0.01" subgrid="3"/>
<pin coord="0 0"/> <pin coord="0 0"/>
<pin coord="10 0"/> <pin coord="10 0"/>
<pin coord="0 8"/> <pin coord="0 8"/>
@@ -67,99 +58,6 @@
<geom size=".095"/> <geom size=".095"/>
<joint kind="main" damping="10"/> <joint kind="main" damping="10"/>
</composite> </composite>
<body name="torso" childclass="humanoid" pos="0 0 1.4">
<freejoint name="root"/>
<geom name="torso1" type="capsule" fromto="0 -.07 0 0 .07 0" size="0.07"/>
<geom name="head" type="sphere" pos="0 0 .19" size=".09"/>
<geom name="uwaist" type="capsule" fromto="-.01 -.06 -.12 -.01 .06 -.12" size="0.06"/>
<body name="lwaist" pos="-.01 0 -0.260" quat="1.000 0 -0.002 0" >
<geom name="lwaist" type="capsule" fromto="0 -.06 0 0 .06 0" size="0.06" />
<joint name="abdomen_z" type="hinge" pos="0 0 0.065" axis="0 0 1" range="-45 45" damping="5" stiffness="20" armature="0.02" />
<joint name="abdomen_y" type="hinge" pos="0 0 0.065" axis="0 1 0" range="-75 30" damping="5" stiffness="10" armature="0.02" />
<body name="pelvis" pos="0 0 -0.165" quat="1.000 0 -0.002 0" >
<joint name="abdomen_x" type="hinge" pos="0 0 0.1" axis="1 0 0" range="-35 35" damping="5" stiffness="10" armature="0.02" />
<geom name="butt" type="capsule" fromto="-.02 -.07 0 -.02 .07 0" size="0.09" />
<body name="right_thigh" pos="0 -0.1 -0.04" >
<joint name="right_hip_x" type="hinge" pos="0 0 0" axis="1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_z" type="hinge" pos="0 0 0" axis="0 0 1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="right_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="right_thigh1" type="capsule" fromto="0 0 0 0 0.01 -.34" size="0.06" />
<body name="right_shin" pos="0 0.01 -0.403" >
<joint name="right_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="right_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="right_foot" pos="0 0 -.39" >
<joint name="right_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="right_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="right_foot_cap1" type="capsule" fromto="-.07 -0.02 0 0.14 -0.04 0" size="0.027" />
<geom name="right_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 0.02 0" size="0.027" />
</body>
</body>
</body>
<body name="left_thigh" pos="0 0.1 -0.04" >
<joint name="left_hip_x" type="hinge" pos="0 0 0" axis="-1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_z" type="hinge" pos="0 0 0" axis="0 0 -1" range="-60 35" damping="5" stiffness="10" armature="0.01" />
<joint name="left_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" />
<geom name="left_thigh1" type="capsule" fromto="0 0 0 0 -0.01 -.34" size="0.06" />
<body name="left_shin" pos="0 -0.01 -0.403" >
<joint name="left_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" />
<geom name="left_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" />
<body name="left_foot" pos="0 0 -.39" >
<joint name="left_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" />
<joint name="left_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" />
<geom name="left_foot_cap1" type="capsule" fromto="-.07 0.02 0 0.14 0.04 0" size="0.027" />
<geom name="left_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 -0.02 0" size="0.027" />
</body>
</body>
</body>
</body>
</body>
<body name="right_upper_arm" pos="0 -0.17 0.06" >
<joint name="right_shoulder1" type="hinge" pos="0 0 0" axis="2 1 1" range="-85 60" stiffness="1" armature="0.0068" />
<joint name="right_shoulder2" type="hinge" pos="0 0 0" axis="0 -1 1" range="-85 60" stiffness="1" armature="0.0051" />
<geom name="right_uarm1" type="capsule" fromto="0 0 0 .16 -.16 -.16" size="0.04 0.16" />
<body name="right_lower_arm" pos=".18 -.18 -.18" >
<joint name="right_elbow" type="hinge" pos="0 0 0" axis="0 -1 1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="right_larm" type="capsule" fromto="0.01 0.01 0.01 .17 .17 .17" size="0.031" />
<geom name="right_hand" type="sphere" pos=".18 .18 .18" size="0.04"/>
</body>
</body>
<body name="left_upper_arm" pos="0 0.17 0.06" >
<joint name="left_shoulder1" type="hinge" pos="0 0 0" axis="2 -1 1" range="-60 85" stiffness="1" armature="0.0068" />
<joint name="left_shoulder2" type="hinge" pos="0 0 0" axis="0 1 1" range="-60 85" stiffness="1" armature="0.0051" />
<geom name="left_uarm1" type="capsule" fromto="0 0 0 .16 .16 -.16" size="0.04 0.16" />
<body name="left_lower_arm" pos=".18 .18 -.18" >
<joint name="left_elbow" type="hinge" pos="0 0 0" axis="0 -1 -1" range="-90 50" stiffness="0" armature="0.0028" />
<geom name="left_larm" type="capsule" fromto="0.01 -0.01 0.01 .17 -.17 .17" size="0.031" />
<geom name="left_hand" type="sphere" pos=".18 -.18 .18" size="0.04"/>
</body>
</body>
</body>
</worldbody> </worldbody>
<actuator>
<motor name="abdomen_y" gear="200" joint="abdomen_y" />
<motor name="abdomen_z" gear="200" joint="abdomen_z" />
<motor name="abdomen_x" gear="200" joint="abdomen_x" />
<motor name="right_hip_x" gear="200" joint="right_hip_x" />
<motor name="right_hip_z" gear="200" joint="right_hip_z" />
<motor name="right_hip_y" gear="600" joint="right_hip_y" />
<motor name="right_knee" gear="400" joint="right_knee" />
<motor name="right_ankle_x" gear="100" joint="right_ankle_x" />
<motor name="right_ankle_y" gear="100" joint="right_ankle_y" />
<motor name="left_hip_x" gear="200" joint="left_hip_x" />
<motor name="left_hip_z" gear="200" joint="left_hip_z" />
<motor name="left_hip_y" gear="600" joint="left_hip_y" />
<motor name="left_knee" gear="400" joint="left_knee" />
<motor name="left_ankle_x" gear="100" joint="left_ankle_x" />
<motor name="left_ankle_y" gear="100" joint="left_ankle_y" />
<motor name="right_shoulder1" gear="100" joint="right_shoulder1" />
<motor name="right_shoulder2" gear="100" joint="right_shoulder2" />
<motor name="right_elbow" gear="200" joint="right_elbow" />
<motor name="left_shoulder1" gear="100" joint="left_shoulder1" />
<motor name="left_shoulder2" gear="100" joint="left_shoulder2" />
<motor name="left_elbow" gear="200" joint="left_elbow" />
</actuator>
</mujoco> </mujoco>
+157
View File
@@ -0,0 +1,157 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Humanoid body">
<!-- Degree of Freedom: 27
Actuators: 21
This simplified humanoid model, introduced in [1], is designed for bipedal locomotion
behaviours. While several variants of it exist in the wild, this version is based on the model
in the DeepMind Control Suite [2], which has fairly realistic actuator gains.
[1] Synthesis and Stabilization of Complex Behaviors through Online Trajectory Optimization.
https://doi.org/10.1109/IROS.2012.6386025
[2] DeepMind Control Suite, Tassa et al. https://arxiv.org/abs/1801.00690
-->
<asset>
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
<texture name="body" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
</asset>
<default>
<motor ctrlrange="-1 1" ctrllimited="true"/>
<default class="body">
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body"/>
<joint type="hinge" damping=".2" stiffness="1" armature=".01" limited="true" solimplimit="0 .99 .01"/>
<default class="big_joint">
<joint damping="5" stiffness="10"/>
<default class="big_stiff_joint">
<joint stiffness="20"/>
</default>
</default>
</default>
</default>
<visual>
<map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="4096"/>
<global offwidth="800" offheight="800"/>
</visual>
<worldbody>
<body name="torso" pos="0 0 1.5" childclass="body">
<camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
<camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
<freejoint name="root"/>
<geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
<geom name="upper_waist" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
<body name="head" pos="0 0 .19">
<geom name="head" type="sphere" size=".09"/>
<camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
</body>
<body name="lower_waist" pos="-.01 0 -.26">
<geom name="lower_waist" fromto="0 -.06 0 0 .06 0" size=".06"/>
<joint name="abdomen_z" pos="0 0 .065" axis="0 0 1" range="-45 45" class="big_stiff_joint"/>
<joint name="abdomen_y" pos="0 0 .065" axis="0 1 0" range="-75 30" class="big_joint"/>
<body name="pelvis" pos="0 0 -.165">
<joint name="abdomen_x" pos="0 0 .1" axis="1 0 0" range="-35 35" class="big_joint"/>
<geom name="butt" fromto="-.02 -.07 0 -.02 .07 0" size=".09"/>
<body name="right_thigh" pos="0 -.1 -.04">
<joint name="right_hip_x" axis="1 0 0" range="-25 5" class="big_joint"/>
<joint name="right_hip_z" axis="0 0 1" range="-60 35" class="big_joint"/>
<joint name="right_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="right_thigh" fromto="0 0 0 0 .01 -.34" size=".06"/>
<body name="right_shin" pos="0 .01 -.403">
<joint name="right_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="right_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="right_foot" pos="0 0 -.39">
<joint name="right_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="right_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="right_right_foot" fromto="-.07 -.02 0 .14 -.04 0" size=".027"/>
<geom name="left_right_foot" fromto="-.07 0 0 .14 .02 0" size=".027"/>
</body>
</body>
</body>
<body name="left_thigh" pos="0 .1 -.04">
<joint name="left_hip_x" axis="-1 0 0" range="-25 5" class="big_joint"/>
<joint name="left_hip_z" axis="0 0 -1" range="-60 35" class="big_joint"/>
<joint name="left_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="left_thigh" fromto="0 0 0 0 -.01 -.34" size=".06"/>
<body name="left_shin" pos="0 -.01 -.403">
<joint name="left_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="left_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="left_foot" pos="0 0 -.39">
<joint name="left_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="left_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="left_left_foot" fromto="-.07 .02 0 .14 .04 0" size=".027"/>
<geom name="right_left_foot" fromto="-.07 0 0 .14 -.02 0" size=".027"/>
</body>
</body>
</body>
</body>
</body>
<body name="right_upper_arm" pos="0 -.17 .06">
<joint name="right_shoulder1" axis="2 1 1" range="-85 60"/>
<joint name="right_shoulder2" axis="0 -1 1" range="-85 60"/>
<geom name="right_upper_arm" fromto="0 0 0 .16 -.16 -.16" size=".04 .16"/>
<body name="right_lower_arm" pos=".18 -.18 -.18">
<joint name="right_elbow" axis="0 -1 1" range="-90 50" stiffness="0"/>
<geom name="right_lower_arm" fromto=".01 .01 .01 .17 .17 .17" size=".031"/>
<body name="right_hand" pos=".18 .18 .18">
<geom name="right_hand" type="sphere" size=".04" zaxis="1 1 1"/>
</body>
</body>
</body>
<body name="left_upper_arm" pos="0 .17 .06">
<joint name="left_shoulder1" axis="2 -1 1" range="-60 85"/>
<joint name="left_shoulder2" axis="0 1 1" range="-60 85"/>
<geom name="left_upper_arm" fromto="0 0 0 .16 .16 -.16" size=".04 .16"/>
<body name="left_lower_arm" pos=".18 .18 -.18">
<joint name="left_elbow" axis="0 -1 -1" range="-90 50" stiffness="0"/>
<geom name="left_lower_arm" fromto=".01 -.01 .01 .17 -.17 .17" size=".031"/>
<body name="left_hand" pos=".18 -.18 .18">
<geom name="left_hand" type="sphere" size=".04" zaxis="1 -1 1"/>
</body>
</body>
</body>
</body>
</worldbody>
<actuator>
<motor name="abdomen_y" gear="40" joint="abdomen_y"/>
<motor name="abdomen_z" gear="40" joint="abdomen_z"/>
<motor name="abdomen_x" gear="40" joint="abdomen_x"/>
<motor name="right_hip_x" gear="40" joint="right_hip_x"/>
<motor name="right_hip_z" gear="40" joint="right_hip_z"/>
<motor name="right_hip_y" gear="120" joint="right_hip_y"/>
<motor name="right_knee" gear="80" joint="right_knee"/>
<motor name="right_ankle_x" gear="20" joint="right_ankle_x"/>
<motor name="right_ankle_y" gear="20" joint="right_ankle_y"/>
<motor name="left_hip_x" gear="40" joint="left_hip_x"/>
<motor name="left_hip_z" gear="40" joint="left_hip_z"/>
<motor name="left_hip_y" gear="120" joint="left_hip_y"/>
<motor name="left_knee" gear="80" joint="left_knee"/>
<motor name="left_ankle_x" gear="20" joint="left_ankle_x"/>
<motor name="left_ankle_y" gear="20" joint="left_ankle_y"/>
<motor name="right_shoulder1" gear="20" joint="right_shoulder1"/>
<motor name="right_shoulder2" gear="20" joint="right_shoulder2"/>
<motor name="right_elbow" gear="40" joint="right_elbow"/>
<motor name="left_shoulder1" gear="20" joint="left_shoulder1"/>
<motor name="left_shoulder2" gear="20" joint="left_shoulder2"/>
<motor name="left_elbow" gear="40" joint="left_elbow"/>
</actuator>
</mujoco>
+114 -98
View File
@@ -14,136 +14,152 @@
--> -->
<mujoco model="Humanoid"> <mujoco model="Humanoid">
<!-- Degree of Freedom: 27
Actuators: 21
<compiler inertiafromgeom="true" angle="degree"/> This simplified humanoid model, introduced in [1], is designed for bipedal locomotion
behaviours. While several variants of it exist in the wild, this version is based on the model
in the DeepMind Control Suite [2], which has fairly realistic actuator gains.
[1] Synthesis and Stabilization of Complex Behaviors through Online Trajectory Optimization.
https://doi.org/10.1109/IROS.2012.6386025
[2] DeepMind Control Suite, Tassa et al. https://arxiv.org/abs/1801.00690
-->
<option timestep="0.005"/>
<asset>
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
<texture name="body" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
</asset>
<default> <default>
<joint limited="true" damping="1" armature="0"/> <motor ctrlrange="-1 1" ctrllimited="true"/>
<geom condim="1" material="matgeom"/> <default class="body">
<motor ctrlrange="-.4 .4" ctrllimited="true"/> <geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body"/>
<joint type="hinge" damping=".2" stiffness="1" armature=".01" limited="true" solimplimit="0 .99 .01"/>
<default class="big_joint">
<joint damping="5" stiffness="10"/>
<default class="big_stiff_joint">
<joint stiffness="20"/>
</default>
</default>
</default>
</default> </default>
<option timestep="0.005" iterations="50" tolerance="1e-10" solver="Newton" jacobian="dense" cone="pyramidal"/>
<size nconmax="50" njmax="200" nstack="10000"/>
<visual> <visual>
<map force="0.1" zfar="30"/> <map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/> <rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/> <quality shadowsize="4096"/>
<global offwidth="800" offheight="800"/> <global offwidth="800" offheight="800"/>
</visual> </visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
</asset>
<worldbody> <worldbody>
<geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="matplane" condim="3"/> <geom name="floor" size="0 0 .05" type="plane" material="grid" condim="3"/>
<light name="spotlight" mode="targetbodycom" target="torso"
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/> diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 -20 4" cutoff="10"/>
<light mode="targetbodycom" target="torso" directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/> <body name="torso" pos="0 0 1.5" childclass="body">
<light name="top" pos="0 0 2" mode="trackcom"/>
<body name="torso" pos="0 0 1.4"> <camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
<camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
<freejoint name="root"/> <freejoint name="root"/>
<geom name="torso1" type="capsule" fromto="0 -.07 0 0 .07 0" size="0.07"/> <geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
<geom name="head" type="sphere" pos="0 0 .19" size=".09"/> <geom name="upper_waist" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
<geom name="uwaist" type="capsule" fromto="-.01 -.06 -.12 -.01 .06 -.12" size="0.06"/> <body name="head" pos="0 0 .19">
<body name="lwaist" pos="-.01 0 -0.260" quat="1.000 0 -0.002 0" > <geom name="head" type="sphere" size=".09"/>
<geom name="lwaist" type="capsule" fromto="0 -.06 0 0 .06 0" size="0.06" /> <camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
<joint name="abdomen_z" type="hinge" pos="0 0 0.065" axis="0 0 1" range="-45 45" damping="5" stiffness="20" armature="0.02" /> </body>
<joint name="abdomen_y" type="hinge" pos="0 0 0.065" axis="0 1 0" range="-75 30" damping="5" stiffness="10" armature="0.02" /> <body name="lower_waist" pos="-.01 0 -.26">
<body name="pelvis" pos="0 0 -0.165" quat="1.000 0 -0.002 0" > <geom name="lower_waist" fromto="0 -.06 0 0 .06 0" size=".06"/>
<joint name="abdomen_x" type="hinge" pos="0 0 0.1" axis="1 0 0" range="-35 35" damping="5" stiffness="10" armature="0.02" /> <joint name="abdomen_z" pos="0 0 .065" axis="0 0 1" range="-45 45" class="big_stiff_joint"/>
<geom name="butt" type="capsule" fromto="-.02 -.07 0 -.02 .07 0" size="0.09" /> <joint name="abdomen_y" pos="0 0 .065" axis="0 1 0" range="-75 30" class="big_joint"/>
<body name="right_thigh" pos="0 -0.1 -0.04" > <body name="pelvis" pos="0 0 -.165">
<joint name="right_hip_x" type="hinge" pos="0 0 0" axis="1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" /> <joint name="abdomen_x" pos="0 0 .1" axis="1 0 0" range="-35 35" class="big_joint"/>
<joint name="right_hip_z" type="hinge" pos="0 0 0" axis="0 0 1" range="-60 35" damping="5" stiffness="10" armature="0.01" /> <geom name="butt" fromto="-.02 -.07 0 -.02 .07 0" size=".09"/>
<joint name="right_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" /> <body name="right_thigh" pos="0 -.1 -.04">
<geom name="right_thigh1" type="capsule" fromto="0 0 0 0 0.01 -.34" size="0.06" /> <joint name="right_hip_x" axis="1 0 0" range="-25 5" class="big_joint"/>
<body name="right_shin" pos="0 0.01 -0.403" > <joint name="right_hip_z" axis="0 0 1" range="-60 35" class="big_joint"/>
<joint name="right_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" /> <joint name="right_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="right_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" /> <geom name="right_thigh" fromto="0 0 0 0 .01 -.34" size=".06"/>
<body name="right_shin" pos="0 .01 -.403">
<joint name="right_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="right_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="right_foot" pos="0 0 -.39"> <body name="right_foot" pos="0 0 -.39">
<joint name="right_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" /> <joint name="right_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="right_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" /> <joint name="right_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="right_foot_cap1" type="capsule" fromto="-.07 -0.02 0 0.14 -0.04 0" size="0.027" /> <geom name="right_right_foot" fromto="-.07 -.02 0 .14 -.04 0" size=".027"/>
<geom name="right_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 0.02 0" size="0.027" /> <geom name="left_right_foot" fromto="-.07 0 0 .14 .02 0" size=".027"/>
</body> </body>
</body> </body>
</body> </body>
<body name="left_thigh" pos="0 0.1 -0.04" > <body name="left_thigh" pos="0 .1 -.04">
<joint name="left_hip_x" type="hinge" pos="0 0 0" axis="-1 0 0" range="-25 5" damping="5" stiffness="10" armature="0.01" /> <joint name="left_hip_x" axis="-1 0 0" range="-25 5" class="big_joint"/>
<joint name="left_hip_z" type="hinge" pos="0 0 0" axis="0 0 -1" range="-60 35" damping="5" stiffness="10" armature="0.01" /> <joint name="left_hip_z" axis="0 0 -1" range="-60 35" class="big_joint"/>
<joint name="left_hip_y" type="hinge" pos="0 0 0" axis="0 1 0" range="-120 20" damping="5" stiffness="20" armature="0.01" /> <joint name="left_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="left_thigh1" type="capsule" fromto="0 0 0 0 -0.01 -.34" size="0.06" /> <geom name="left_thigh" fromto="0 0 0 0 -.01 -.34" size=".06"/>
<body name="left_shin" pos="0 -0.01 -0.403" > <body name="left_shin" pos="0 -.01 -.403">
<joint name="left_knee" type="hinge" pos="0 0 .02" axis="0 -1 0" range="-160 -2" stiffness="1" armature="0.0060" /> <joint name="left_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="left_shin1" type="capsule" fromto="0 0 0 0 0 -.3" size="0.049" /> <geom name="left_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="left_foot" pos="0 0 -.39"> <body name="left_foot" pos="0 0 -.39">
<joint name="left_ankle_y" type="hinge" pos="0 0 0.08" axis="0 1 0" range="-50 50" stiffness="4" armature="0.0008" /> <joint name="left_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="left_ankle_x" type="hinge" pos="0 0 0.04" axis="1 0 0.5" range="-50 50" stiffness="1" armature="0.0006" /> <joint name="left_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="left_foot_cap1" type="capsule" fromto="-.07 0.02 0 0.14 0.04 0" size="0.027" /> <geom name="left_left_foot" fromto="-.07 .02 0 .14 .04 0" size=".027"/>
<geom name="left_foot_cap2" type="capsule" fromto="-.07 0 0 0.14 -0.02 0" size="0.027" /> <geom name="right_left_foot" fromto="-.07 0 0 .14 -.02 0" size=".027"/>
</body> </body>
</body> </body>
</body> </body>
</body> </body>
</body> </body>
<body name="right_upper_arm" pos="0 -0.17 0.06" > <body name="right_upper_arm" pos="0 -.17 .06">
<joint name="right_shoulder1" type="hinge" pos="0 0 0" axis="2 1 1" range="-85 60" stiffness="1" armature="0.0068" /> <joint name="right_shoulder1" axis="2 1 1" range="-85 60"/>
<joint name="right_shoulder2" type="hinge" pos="0 0 0" axis="0 -1 1" range="-85 60" stiffness="1" armature="0.0051" /> <joint name="right_shoulder2" axis="0 -1 1" range="-85 60"/>
<geom name="right_uarm1" type="capsule" fromto="0 0 0 .16 -.16 -.16" size="0.04 0.16" /> <geom name="right_upper_arm" fromto="0 0 0 .16 -.16 -.16" size=".04 .16"/>
<body name="right_lower_arm" pos=".18 -.18 -.18"> <body name="right_lower_arm" pos=".18 -.18 -.18">
<joint name="right_elbow" type="hinge" pos="0 0 0" axis="0 -1 1" range="-90 50" stiffness="0" armature="0.0028" /> <joint name="right_elbow" axis="0 -1 1" range="-90 50" stiffness="0"/>
<geom name="right_larm" type="capsule" fromto="0.01 0.01 0.01 .17 .17 .17" size="0.031" /> <geom name="right_lower_arm" fromto=".01 .01 .01 .17 .17 .17" size=".031"/>
<geom name="right_hand" type="sphere" pos=".18 .18 .18" size="0.04"/> <body name="right_hand" pos=".18 .18 .18">
<geom name="right_hand" type="sphere" size=".04" zaxis="1 1 1"/>
</body> </body>
</body> </body>
<body name="left_upper_arm" pos="0 0.17 0.06" > </body>
<joint name="left_shoulder1" type="hinge" pos="0 0 0" axis="2 -1 1" range="-60 85" stiffness="1" armature="0.0068" /> <body name="left_upper_arm" pos="0 .17 .06">
<joint name="left_shoulder2" type="hinge" pos="0 0 0" axis="0 1 1" range="-60 85" stiffness="1" armature="0.0051" /> <joint name="left_shoulder1" axis="2 -1 1" range="-60 85"/>
<geom name="left_uarm1" type="capsule" fromto="0 0 0 .16 .16 -.16" size="0.04 0.16" /> <joint name="left_shoulder2" axis="0 1 1" range="-60 85"/>
<geom name="left_upper_arm" fromto="0 0 0 .16 .16 -.16" size=".04 .16"/>
<body name="left_lower_arm" pos=".18 .18 -.18"> <body name="left_lower_arm" pos=".18 .18 -.18">
<joint name="left_elbow" type="hinge" pos="0 0 0" axis="0 -1 -1" range="-90 50" stiffness="0" armature="0.0028" /> <joint name="left_elbow" axis="0 -1 -1" range="-90 50" stiffness="0"/>
<geom name="left_larm" type="capsule" fromto="0.01 -0.01 0.01 .17 -.17 .17" size="0.031" /> <geom name="left_lower_arm" fromto=".01 -.01 .01 .17 -.17 .17" size=".031"/>
<geom name="left_hand" type="sphere" pos=".18 -.18 .18" size="0.04"/> <body name="left_hand" pos=".18 -.18 .18">
<geom name="left_hand" type="sphere" size=".04" zaxis="1 -1 1"/>
</body>
</body> </body>
</body> </body>
</body> </body>
</worldbody> </worldbody>
<actuator> <actuator>
<motor name="abdomen_y" gear="200" joint="abdomen_y" /> <motor name="abdomen_y" gear="40" joint="abdomen_y"/>
<motor name="abdomen_z" gear="200" joint="abdomen_z" /> <motor name="abdomen_z" gear="40" joint="abdomen_z"/>
<motor name="abdomen_x" gear="200" joint="abdomen_x" /> <motor name="abdomen_x" gear="40" joint="abdomen_x"/>
<motor name="right_hip_x" gear="200" joint="right_hip_x" /> <motor name="right_hip_x" gear="40" joint="right_hip_x"/>
<motor name="right_hip_z" gear="200" joint="right_hip_z" /> <motor name="right_hip_z" gear="40" joint="right_hip_z"/>
<motor name="right_hip_y" gear="600" joint="right_hip_y" /> <motor name="right_hip_y" gear="120" joint="right_hip_y"/>
<motor name="right_knee" gear="400" joint="right_knee" /> <motor name="right_knee" gear="80" joint="right_knee"/>
<motor name="right_ankle_x" gear="100" joint="right_ankle_x" /> <motor name="right_ankle_x" gear="20" joint="right_ankle_x"/>
<motor name="right_ankle_y" gear="100" joint="right_ankle_y" /> <motor name="right_ankle_y" gear="20" joint="right_ankle_y"/>
<motor name="left_hip_x" gear="200" joint="left_hip_x" /> <motor name="left_hip_x" gear="40" joint="left_hip_x"/>
<motor name="left_hip_z" gear="200" joint="left_hip_z" /> <motor name="left_hip_z" gear="40" joint="left_hip_z"/>
<motor name="left_hip_y" gear="600" joint="left_hip_y" /> <motor name="left_hip_y" gear="120" joint="left_hip_y"/>
<motor name="left_knee" gear="400" joint="left_knee" /> <motor name="left_knee" gear="80" joint="left_knee"/>
<motor name="left_ankle_x" gear="100" joint="left_ankle_x" /> <motor name="left_ankle_x" gear="20" joint="left_ankle_x"/>
<motor name="left_ankle_y" gear="100" joint="left_ankle_y" /> <motor name="left_ankle_y" gear="20" joint="left_ankle_y"/>
<motor name="right_shoulder1" gear="100" joint="right_shoulder1" /> <motor name="right_shoulder1" gear="20" joint="right_shoulder1"/>
<motor name="right_shoulder2" gear="100" joint="right_shoulder2" /> <motor name="right_shoulder2" gear="20" joint="right_shoulder2"/>
<motor name="right_elbow" gear="200" joint="right_elbow" /> <motor name="right_elbow" gear="40" joint="right_elbow"/>
<motor name="left_shoulder1" gear="100" joint="left_shoulder1" /> <motor name="left_shoulder1" gear="20" joint="left_shoulder1"/>
<motor name="left_shoulder2" gear="100" joint="left_shoulder2" /> <motor name="left_shoulder2" gear="20" joint="left_shoulder2"/>
<motor name="left_elbow" gear="200" joint="left_elbow" /> <motor name="left_elbow" gear="40" joint="left_elbow"/>
</actuator> </actuator>
</mujoco> </mujoco>
+8 -88
View File
@@ -14,58 +14,49 @@
--> -->
<mujoco model="Humanoid and 100 objects"> <mujoco model="Humanoid and 100 objects">
<!-- Degree of Freedom: 627
Actuators: 21
<compiler angle="degree"/> Humanoid and 100 free primitive objects.
-->
<include file="humanoid_body.xml"/>
<option timestep="0.005" iterations="50" solver="Newton" jacobian="sparse" cone="pyramidal" tolerance="1e-10"/> <option timestep="0.005"/>
<size njmax="1500" nconmax="500" nstack="5000000"/> <size nconmax="500" njmax="1500" nstack="5000000"/>
<default> <default>
<geom solimp=".9 .9 .01"/> <geom solimp=".9 .9 .01"/>
<default class="humanoid">
<geom material="humanoid"/>
<joint damping="1" limited="true"/>
</default>
<default class="object1"> <default class="object1">
<geom type="capsule" material="object1" size="0.1 0.05"/> <geom type="capsule" material="object1" size="0.1 0.05"/>
</default> </default>
<default class="object2"> <default class="object2">
<geom type="ellipsoid" material="object2" size="0.15 0.1 0.07"/> <geom type="ellipsoid" material="object2" size="0.15 0.1 0.07"/>
</default> </default>
<default class="object3"> <default class="object3">
<geom type="box" material="object3" size="0.15 0.1 0.05"/> <geom type="box" material="object3" size="0.15 0.1 0.05"/>
</default> </default>
<default class="object4"> <default class="object4">
<geom type="cylinder" material="object4" size="0.1 0.05" condim="4" friction="1 .01 .01"/> <geom type="cylinder" material="object4" size="0.1 0.05" condim="4" friction="1 .01 .01"/>
</default> </default>
<default class="object5"> <default class="object5">
<geom type="sphere" material="object5" size="0.1"/> <geom type="sphere" material="object5" size="0.1"/>
</default> </default>
<default class="border"> <default class="border">
<geom type="capsule" size="0.4" rgba=".4 .4 .4 1"/> <geom type="capsule" size="0.4" rgba=".4 .4 .4 1"/>
</default> </default>
<default class="borderpost"> <default class="borderpost">
<geom type="box" size="0.41 0.41 0.41" rgba=".55 .55 .55 1"/> <geom type="box" size="0.41 0.41 0.41" rgba=".55 .55 .55 1"/>
</default> </default>
</default> </default>
<asset> <asset>
<texture type="skybox" builtin="gradient" width="128" height="128" rgb1=".4 .6 .8" rgb2="0 0 0"/> <texture type="skybox" builtin="gradient" width="512" height="512" rgb1=".4 .6 .8" rgb2="0 0 0"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="128" height="128" <texture name="texgeom" type="cube" builtin="flat" mark="cross" width="128" height="128"
rgb1="0.6 0.6 0.6" rgb2="0.6 0.6 0.6" markrgb="1 1 1"/> rgb1="0.6 0.6 0.6" rgb2="0.6 0.6 0.6" markrgb="1 1 1"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".4 .4 .4" rgb2=".6 .6 .6" <texture name="texplane" type="2d" builtin="checker" rgb1=".4 .4 .4" rgb2=".6 .6 .6"
width="512" height="512"/> width="512" height="512"/>
<material name='MatPlane' reflectance='0.3' texture="texplane" texrepeat="1 1" texuniform="true"/> <material name='MatPlane' reflectance='0.3' texture="texplane" texrepeat="1 1" texuniform="true"/>
<material name='humanoid' texture="texgeom" texuniform="true" rgba="1.2 1.2 0.6 1"/>
<material name='object1' texture="texgeom" texuniform="true" rgba=".4 .9 .6 1" /> <material name='object1' texture="texgeom" texuniform="true" rgba=".4 .9 .6 1" />
<material name='object2' texture="texgeom" texuniform="true" rgba=".4 .6 .9 1" /> <material name='object2' texture="texgeom" texuniform="true" rgba=".4 .6 .9 1" />
<material name='object3' texture="texgeom" texuniform="true" rgba=".4 .9 .9 1" /> <material name='object3' texture="texgeom" texuniform="true" rgba=".4 .9 .9 1" />
@@ -82,9 +73,7 @@
<worldbody> <worldbody>
<light directional="true" diffuse=".8 .8 .8" pos="0 0 10" dir="0 0 -10"/> <light directional="true" diffuse=".8 .8 .8" pos="0 0 10" dir="0 0 -10"/>
<geom pos="0 0 0" type="plane" size="3 3 .5" rgba=".7 .7 .7 1" material="MatPlane"/> <geom pos="0 0 0" type="plane" size="3 3 .5" rgba=".7 .7 .7 1" material="MatPlane"/>
<geom class="border" fromto="-3 3 0 3 3 0" /> <geom class="border" fromto="-3 3 0 3 3 0" />
<geom class="border" fromto="-3 -3 0 3 -3 0" /> <geom class="border" fromto="-3 -3 0 3 -3 0" />
<geom class="border" fromto="3 3 0 3 -3 0" /> <geom class="border" fromto="3 3 0 3 -3 0" />
@@ -94,75 +83,6 @@
<geom class="borderpost" pos="3 -3 0"/> <geom class="borderpost" pos="3 -3 0"/>
<geom class="borderpost" pos="-3 -3 0"/> <geom class="borderpost" pos="-3 -3 0"/>
<body name='torso' pos='0 0 1.4' childclass="humanoid">
<freejoint name="root"/>
<geom name='torso1' type='capsule' fromto='0 -.07 0 0 .07 0' size='0.07'/>
<geom name='head' type='sphere' pos='0 0 .19' size='.09'/>
<geom name='uwaist' type='capsule' fromto='-.01 -.06 -.12 -.01 .06 -.12' size='0.06'/>
<body name='lwaist' pos='-.01 0 -0.260' quat='1.000 0 -0.002 0' >
<geom name='lwaist' type='capsule' fromto='0 -.06 0 0 .06 0' size='0.06' />
<joint name='abdomen_z' type='hinge' pos='0 0 0.065' axis='0 0 1' range='-45 45' damping='5' stiffness='20' armature='0.02' />
<joint name='abdomen_y' type='hinge' pos='0 0 0.065' axis='0 1 0' range='-75 30' damping='5' stiffness='10' armature='0.02' />
<body name='pelvis' pos='0 0 -0.165' quat='1.000 0 -0.002 0' >
<joint name='abdomen_x' type='hinge' pos='0 0 0.1' axis='1 0 0' range='-35 35' damping='5' stiffness='10' armature='0.02' />
<geom name='butt' type='capsule' fromto='-.02 -.07 0 -.02 .07 0' size='0.09' />
<body name='right_thigh' pos='0 -0.1 -0.04' >
<joint name='right_hip_x' type='hinge' pos='0 0 0' axis='1 0 0' range='-25 5' damping='5' stiffness='10' armature='0.01' />
<joint name='right_hip_z' type='hinge' pos='0 0 0' axis='0 0 1' range='-60 35' damping='5' stiffness='10' armature='0.01' />
<joint name='right_hip_y' type='hinge' pos='0 0 0' axis='0 1 0' range='-120 20' damping='5' stiffness='20' armature='0.01' />
<geom name='right_thigh1' type='capsule' fromto='0 0 0 0 0.01 -.34' size='0.06' />
<body name='right_shin' pos='0 0.01 -0.403' >
<joint name='right_knee' type='hinge' pos='0 0 .02' axis='0 -1 0' range='-160 -2' stiffness='1' armature='0.0060' />
<geom name='right_shin1' type='capsule' fromto='0 0 0 0 0 -.3' size='0.049' />
<body name='right_foot' pos='0 0 -.39' >
<joint name='right_ankle_y' type='hinge' pos='0 0 0.08' axis='0 1 0' range='-50 50' stiffness='4' armature='0.0008' />
<joint name='right_ankle_x' type='hinge' pos='0 0 0.04' axis='1 0 0.5' range='-50 50' stiffness='1' armature='0.0006' />
<geom name='right_foot_cap1' type='capsule' fromto='-.07 -0.02 0 0.14 -0.04 0' size='0.027' />
<geom name='right_foot_cap2' type='capsule' fromto='-.07 0 0 0.14 0.02 0' size='0.027' />
</body>
</body>
</body>
<body name='left_thigh' pos='0 0.1 -0.04' >
<joint name='left_hip_x' type='hinge' pos='0 0 0' axis='-1 0 0' range='-25 5' damping='5' stiffness='10' armature='0.01' />
<joint name='left_hip_z' type='hinge' pos='0 0 0' axis='0 0 -1' range='-60 35' damping='5' stiffness='10' armature='0.01' />
<joint name='left_hip_y' type='hinge' pos='0 0 0' axis='0 1 0' range='-120 20' damping='5' stiffness='20' armature='0.01' />
<geom name='left_thigh1' type='capsule' fromto='0 0 0 0 -0.01 -.34' size='0.06' />
<body name='left_shin' pos='0 -0.01 -0.403' >
<joint name='left_knee' type='hinge' pos='0 0 .02' axis='0 -1 0' range='-160 -2' stiffness='1' armature='0.0060' />
<geom name='left_shin1' type='capsule' fromto='0 0 0 0 0 -.3' size='0.049' />
<body name='left_foot' pos='0 0 -.39' >
<joint name='left_ankle_y' type='hinge' pos='0 0 0.08' axis='0 1 0' range='-50 50' stiffness='4' armature='0.0008' />
<joint name='left_ankle_x' type='hinge' pos='0 0 0.04' axis='1 0 0.5' range='-50 50' stiffness='1' armature='0.0006' />
<geom name='left_foot_cap1' type='capsule' fromto='-.07 0.02 0 0.14 0.04 0' size='0.027' />
<geom name='left_foot_cap2' type='capsule' fromto='-.07 0 0 0.14 -0.02 0' size='0.027' />
</body>
</body>
</body>
</body>
</body>
<body name='right_upper_arm' pos='0 -0.17 0.06' >
<joint name='right_shoulder1' type='hinge' pos='0 0 0' axis='2 1 1' range='-85 60' stiffness='1' armature='0.0068' />
<joint name='right_shoulder2' type='hinge' pos='0 0 0' axis='0 -1 1' range='-85 60' stiffness='1' armature='0.0051' />
<geom name='right_uarm1' type='capsule' fromto='0 0 0 .16 -.16 -.16' size='0.04 0.16' />
<body name='right_lower_arm' pos='.18 -.18 -.18' >
<joint name='right_elbow' type='hinge' pos='0 0 0' axis='0 -1 1' range='-90 50' stiffness='0' armature='0.0028' />
<geom name='right_larm' type='capsule' fromto='0.01 0.01 0.01 .17 .17 .17' size='0.031' />
<geom name='right_hand' type='sphere' pos='.18 .18 .18' size='0.04'/>
</body>
</body>
<body name='left_upper_arm' pos='0 0.17 0.06' >
<joint name='left_shoulder1' type='hinge' pos='0 0 0' axis='2 -1 1' range='-60 85' stiffness='1' armature='0.0068' />
<joint name='left_shoulder2' type='hinge' pos='0 0 0' axis='0 1 1' range='-60 85' stiffness='1' armature='0.0051' />
<geom name='left_uarm1' type='capsule' fromto='0 0 0 .16 .16 -.16' size='0.04 0.16' />
<body name='left_lower_arm' pos='.18 .18 -.18' >
<joint name='left_elbow' type='hinge' pos='0 0 0' axis='0 -1 -1' range='-90 50' stiffness='0' armature='0.0028' />
<geom name='left_larm' type='capsule' fromto='0.01 -0.01 0.01 .17 -.17 .17' size='0.031' />
<geom name='left_hand' type='sphere' pos='.18 -.18 .18' size='0.04'/>
</body>
</body>
</body>
<body pos="-2 -2 1" quat="-0.632456 -0.632456 0.316228 0.316228"> <body pos="-2 -2 1" quat="-0.632456 -0.632456 0.316228 0.316228">
<freejoint/> <freejoint/>
<geom class="object1"/> <geom class="object1"/>
+158
View File
@@ -0,0 +1,158 @@
<!-- Copyright 2021 DeepMind Technologies Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mujoco model="Humanoid body">
<!-- Degree of Freedom: 27
Actuators: 21
This simplified humanoid model, introduced in [1], is designed for bipedal locomotion
behaviours. While several variants of it exist in the wild, this version is based on the model
in the DeepMind Control Suite [2], which has fairly realistic actuator gains.
[1] Synthesis and Stabilization of Complex Behaviors through Online Trajectory Optimization.
https://doi.org/10.1109/IROS.2012.6386025
[2] DeepMind Control Suite, Tassa et al. https://arxiv.org/abs/1801.00690
-->
<asset>
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
<texture name="body" type="cube" builtin="flat" mark="cross" width="127" height="1278"
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
</asset>
<default>
<motor ctrlrange="-1 1" ctrllimited="true"/>
<default class="body">
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body"/>
<joint type="hinge" damping=".2" stiffness="1" armature=".01" limited="true" solimplimit="0 .99 .01"/>
<default class="big_joint">
<joint damping="5" stiffness="10"/>
<default class="big_stiff_joint">
<joint stiffness="20"/>
</default>
</default>
</default>
</default>
<visual>
<map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="4096"/>
<global offwidth="800" offheight="800"/>
</visual>
<worldbody>
<body name="torso" pos="0 0 1.5" childclass="body">
<light name="top" pos="0 0 2" mode="trackcom"/>
<camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
<camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
<freejoint name="root"/>
<geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
<geom name="upper_waist" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
<body name="head" pos="0 0 .19">
<geom name="head" type="sphere" size=".09"/>
<camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
</body>
<body name="lower_waist" pos="-.01 0 -.26">
<geom name="lower_waist" fromto="0 -.06 0 0 .06 0" size=".06"/>
<joint name="abdomen_z" pos="0 0 .065" axis="0 0 1" range="-45 45" class="big_stiff_joint"/>
<joint name="abdomen_y" pos="0 0 .065" axis="0 1 0" range="-75 30" class="big_joint"/>
<body name="pelvis" pos="0 0 -.165">
<joint name="abdomen_x" pos="0 0 .1" axis="1 0 0" range="-35 35" class="big_joint"/>
<geom name="butt" fromto="-.02 -.07 0 -.02 .07 0" size=".09"/>
<body name="right_thigh" pos="0 -.1 -.04">
<joint name="right_hip_x" axis="1 0 0" range="-25 5" class="big_joint"/>
<joint name="right_hip_z" axis="0 0 1" range="-60 35" class="big_joint"/>
<joint name="right_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="right_thigh" fromto="0 0 0 0 .01 -.34" size=".06"/>
<body name="right_shin" pos="0 .01 -.403">
<joint name="right_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="right_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="right_foot" pos="0 0 -.39">
<joint name="right_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="right_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="right_right_foot" fromto="-.07 -.02 0 .14 -.04 0" size=".027"/>
<geom name="left_right_foot" fromto="-.07 0 0 .14 .02 0" size=".027"/>
</body>
</body>
</body>
<body name="left_thigh" pos="0 .1 -.04">
<joint name="left_hip_x" axis="-1 0 0" range="-25 5" class="big_joint"/>
<joint name="left_hip_z" axis="0 0 -1" range="-60 35" class="big_joint"/>
<joint name="left_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<geom name="left_thigh" fromto="0 0 0 0 -.01 -.34" size=".06"/>
<body name="left_shin" pos="0 -.01 -.403">
<joint name="left_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<geom name="left_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<body name="left_foot" pos="0 0 -.39">
<joint name="left_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<joint name="left_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<geom name="left_left_foot" fromto="-.07 .02 0 .14 .04 0" size=".027"/>
<geom name="right_left_foot" fromto="-.07 0 0 .14 -.02 0" size=".027"/>
</body>
</body>
</body>
</body>
</body>
<body name="right_upper_arm" pos="0 -.17 .06">
<joint name="right_shoulder1" axis="2 1 1" range="-85 60"/>
<joint name="right_shoulder2" axis="0 -1 1" range="-85 60"/>
<geom name="right_upper_arm" fromto="0 0 0 .16 -.16 -.16" size=".04 .16"/>
<body name="right_lower_arm" pos=".18 -.18 -.18">
<joint name="right_elbow" axis="0 -1 1" range="-90 50" stiffness="0"/>
<geom name="right_lower_arm" fromto=".01 .01 .01 .17 .17 .17" size=".031"/>
<body name="right_hand" pos=".18 .18 .18">
<geom name="right_hand" type="sphere" size=".04" zaxis="1 1 1"/>
</body>
</body>
</body>
<body name="left_upper_arm" pos="0 .17 .06">
<joint name="left_shoulder1" axis="2 -1 1" range="-60 85"/>
<joint name="left_shoulder2" axis="0 1 1" range="-60 85"/>
<geom name="left_upper_arm" fromto="0 0 0 .16 .16 -.16" size=".04 .16"/>
<body name="left_lower_arm" pos=".18 .18 -.18">
<joint name="left_elbow" axis="0 -1 -1" range="-90 50" stiffness="0"/>
<geom name="left_lower_arm" fromto=".01 -.01 .01 .17 -.17 .17" size=".031"/>
<body name="left_hand" pos=".18 -.18 .18">
<geom name="left_hand" type="sphere" size=".04" zaxis="1 -1 1"/>
</body>
</body>
</body>
</body>
</worldbody>
<actuator>
<motor name="abdomen_y" gear="40" joint="abdomen_y"/>
<motor name="abdomen_z" gear="40" joint="abdomen_z"/>
<motor name="abdomen_x" gear="40" joint="abdomen_x"/>
<motor name="right_hip_x" gear="40" joint="right_hip_x"/>
<motor name="right_hip_z" gear="40" joint="right_hip_z"/>
<motor name="right_hip_y" gear="120" joint="right_hip_y"/>
<motor name="right_knee" gear="80" joint="right_knee"/>
<motor name="right_ankle_x" gear="20" joint="right_ankle_x"/>
<motor name="right_ankle_y" gear="20" joint="right_ankle_y"/>
<motor name="left_hip_x" gear="40" joint="left_hip_x"/>
<motor name="left_hip_z" gear="40" joint="left_hip_z"/>
<motor name="left_hip_y" gear="120" joint="left_hip_y"/>
<motor name="left_knee" gear="80" joint="left_knee"/>
<motor name="left_ankle_x" gear="20" joint="left_ankle_x"/>
<motor name="left_ankle_y" gear="20" joint="left_ankle_y"/>
<motor name="right_shoulder1" gear="20" joint="right_shoulder1"/>
<motor name="right_shoulder2" gear="20" joint="right_shoulder2"/>
<motor name="right_elbow" gear="40" joint="right_elbow"/>
<motor name="left_shoulder1" gear="20" joint="left_shoulder1"/>
<motor name="left_shoulder2" gear="20" joint="left_shoulder2"/>
<motor name="left_elbow" gear="40" joint="left_elbow"/>
</actuator>
</mujoco>
-1
View File
@@ -14,7 +14,6 @@
--> -->
<mujoco model="2-link 6-muscle arm"> <mujoco model="2-link 6-muscle arm">
<option timestep="0.005" iterations="50" solver="Newton" tolerance="1e-10"/> <option timestep="0.005" iterations="50" solver="Newton" tolerance="1e-10"/>
<size njmax="50" nconmax="10" nstack="200"/> <size njmax="50" nconmax="10" nstack="200"/>
+96
View File
@@ -0,0 +1,96 @@
// Copyright 2021 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SAMPLE_ARRAY_SAFETY_H_
#define MUJOCO_SAMPLE_ARRAY_SAFETY_H_
#include <algorithm>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstring>
// Provides safe alternatives to the sizeof() operator and standard library functions for handling
// null-terminated (C-style) strings in raw char arrays.
//
// These functions make use of compile-time array sizes to limit read and write operations to within
// the array bounds. They are designed to trigger a compile error if the array size cannot be
// determined at compile time (e.g. when an array has decayed into a pointer).
//
// They do not perform runtime bound checks.
namespace mujoco {
namespace sample_util {
// returns sizeof(arr)
// use instead of sizeof() to avoid unintended array-to-pointer decay
template <typename T, int N>
static constexpr std::size_t sizeof_arr(const T(&arr)[N]) {
return sizeof(arr);
}
// like std::strcmp but it will not read beyond the bound of either lhs or rhs
template <std::size_t N1, std::size_t N2>
static inline int strcmp_arr(const char (&lhs)[N1], const char (&rhs)[N2]) {
return std::strncmp(lhs, rhs, std::min(N1, N2));
}
// like std::strlen but it will not read beyond the bound of str
// if str is not null-terminated, returns sizeof(str)
template <std::size_t N>
static inline std::size_t strlen_arr(const char (&str)[N]) {
for (std::size_t i = 0; i < N; ++i) {
if (str[i] == '\0') {
return i;
}
}
return N;
}
// like std::sprintf but will not write beyond the bound of dest
// dest is guaranteed to be null-terminated
template <std::size_t N>
static inline int sprintf_arr(char (&dest)[N], const char* format, ...) {
std::va_list vargs;
va_start(vargs, format);
int retval = std::vsnprintf(dest, N, format, vargs);
va_end(vargs);
return retval;
}
// like std::strcat but will not write beyond the bound of dest
// dest is guaranteed to be null-terminated
template <std::size_t N>
static inline char* strcat_arr(char (&dest)[N], const char* src) {
return std::strncat(dest, src, sizeof_arr(dest) - strlen_arr(dest) - 1);
}
// like std::strcpy but won't write beyond the bound of dest
// dest is guaranteed to be null-terminated
template <std::size_t N>
static inline char* strcpy_arr(char (&dest)[N], const char* src) {
{
std::size_t i = 0;
for (; src[i] && i < N - 1; ++i) {
dest[i] = src[i];
}
dest[i] = '\0';
}
return &dest[0];
}
} // namespace sample_util
} // namespace mujoco
#endif // MUJOCO_SAMPLE_ARRAY_SAFETY_H_
+28 -31
View File
@@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h" #include <cstdio>
#include "glfw3.h" #include <cstring>
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "GLFW/glfw3.h"
#include "mujoco.h"
// MuJoCo data structures // MuJoCo data structures
mjModel* m = NULL; // MuJoCo model mjModel* m = NULL; // MuJoCo model
@@ -36,11 +35,9 @@ double lasty = 0;
// keyboard callback // keyboard callback
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods) void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods) {
{
// backspace: reset simulation // backspace: reset simulation
if( act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE ) if (act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE) {
{
mj_resetData(m, d); mj_resetData(m, d);
mj_forward(m, d); mj_forward(m, d);
} }
@@ -48,8 +45,7 @@ void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods)
// mouse button callback // mouse button callback
void mouse_button(GLFWwindow* window, int button, int act, int mods) void mouse_button(GLFWwindow* window, int button, int act, int mods) {
{
// update button state // update button state
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS); button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS); button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
@@ -61,11 +57,11 @@ void mouse_button(GLFWwindow* window, int button, int act, int mods)
// mouse move callback // mouse move callback
void mouse_move(GLFWwindow* window, double xpos, double ypos) void mouse_move(GLFWwindow* window, double xpos, double ypos) {
{
// no buttons down: nothing to do // no buttons down: nothing to do
if( !button_left && !button_middle && !button_right ) if (!button_left && !button_middle && !button_right) {
return; return;
}
// compute mouse displacement, save // compute mouse displacement, save
double dx = xpos - lastx; double dx = xpos - lastx;
@@ -83,12 +79,13 @@ void mouse_move(GLFWwindow* window, double xpos, double ypos)
// determine action based on mouse button // determine action based on mouse button
mjtMouse action; mjtMouse action;
if( button_right ) if (button_right) {
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V; action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
else if( button_left ) } else if (button_left) {
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V; action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
else } else {
action = mjMOUSE_ZOOM; action = mjMOUSE_ZOOM;
}
// move camera // move camera
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam); mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
@@ -96,38 +93,38 @@ void mouse_move(GLFWwindow* window, double xpos, double ypos)
// scroll callback // scroll callback
void scroll(GLFWwindow* window, double xoffset, double yoffset) void scroll(GLFWwindow* window, double xoffset, double yoffset) {
{
// emulate vertical mouse motion = 5% of window height // emulate vertical mouse motion = 5% of window height
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam); mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
} }
// main function // main function
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
// check command-line arguments // check command-line arguments
if( argc!=2 ) if (argc!=2) {
{ std::printf(" USAGE: basic modelfile\n");
printf(" USAGE: basic modelfile\n");
return 0; return 0;
} }
// load and compile model // load and compile model
char error[1000] = "Could not load binary model"; char error[1000] = "Could not load binary model";
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") ) if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
m = mj_loadModel(argv[1], 0); m = mj_loadModel(argv[1], 0);
else } else {
m = mj_loadXML(argv[1], 0, error, 1000); m = mj_loadXML(argv[1], 0, error, 1000);
if( !m ) }
if (!m) {
mju_error_s("Load model error: %s", error); mju_error_s("Load model error: %s", error);
}
// make data // make data
d = mj_makeData(m); d = mj_makeData(m);
// init GLFW // init GLFW
if( !glfwInit() ) if (!glfwInit()) {
mju_error("Could not initialize GLFW"); mju_error("Could not initialize GLFW");
}
// create window, make OpenGL context current, request v-sync // create window, make OpenGL context current, request v-sync
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL); GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
@@ -151,15 +148,15 @@ int main(int argc, const char** argv)
glfwSetScrollCallback(window, scroll); glfwSetScrollCallback(window, scroll);
// run main loop, target real-time simulation and 60 fps rendering // run main loop, target real-time simulation and 60 fps rendering
while( !glfwWindowShouldClose(window) ) while (!glfwWindowShouldClose(window)) {
{
// advance interactive simulation for 1/60 sec // advance interactive simulation for 1/60 sec
// Assuming MuJoCo can simulate faster than real-time, which it usually can, // Assuming MuJoCo can simulate faster than real-time, which it usually can,
// this loop will finish on time for the next frame to be rendered at 60 fps. // this loop will finish on time for the next frame to be rendered at 60 fps.
// Otherwise add a cpu timer and exit this loop when it is time to render. // Otherwise add a cpu timer and exit this loop when it is time to render.
mjtNum simstart = d->time; mjtNum simstart = d->time;
while( d->time - simstart < 1.0/60.0 ) while (d->time - simstart < 1.0/60.0) {
mj_step(m, d); mj_step(m, d);
}
// get framebuffer viewport // get framebuffer viewport
mjrRect viewport = {0, 0, 0, 0}; mjrRect viewport = {0, 0, 0, 0};
+45 -43
View File
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h" #include <cctype>
#include <stdlib.h> #include <cstddef>
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#include <ctype.h>
#include "mujoco.h"
// help // help
const char helpstring[] = const char helpstring[] =
@@ -28,23 +28,23 @@ const char helpstring[] =
// deallocate and print message // deallocate and print message
int finish(const char* msg = 0, mjModel* m = 0) int finish(const char* msg = 0, mjModel* m = 0) {
{
// deallocated everything // deallocated everything
if( m ) if (m) {
mj_deleteModel(m); mj_deleteModel(m);
}
// print message // print message
if( msg ) if (msg) {
printf("%s\n", msg); std::printf("%s\n", msg);
}
return 0; return 0;
} }
// possible file types // possible file types
enum enum {
{
typeUNKNOWN = 0, typeUNKNOWN = 0,
typeXML, typeXML,
typeMJB, typeMJB,
@@ -53,50 +53,51 @@ enum
// determine file type // determine file type
int filetype(const char* filename) int filetype(const char* filename) {
{
// convert to lower case for string comparison // convert to lower case for string comparison
char lower[1000]; char lower[1000];
size_t i=0; std::size_t i=0;
while( i<strlen(filename) && i<999 ) while (i<std::strlen(filename) && i<999) {
{
lower[i] = (char)tolower(filename[i]); lower[i] = (char)tolower(filename[i]);
i++; i++;
} }
lower[i] = 0; lower[i] = 0;
// find last dot // find last dot
int dot = (int)strlen(lower); int dot = (int)std::strlen(lower);
while( dot>=0 && lower[dot]!='.' ) while (dot>=0 && lower[dot]!='.') {
dot--; dot--;
}
// no dot found // no dot found
if( dot<0 ) if (dot<0) {
return typeUNKNOWN; return typeUNKNOWN;
}
// check extension // check extension
if( !strcmp(lower+dot, ".xml") || !strcmp(lower+dot, ".urdf") ) if (!std::strcmp(lower+dot, ".xml") || !std::strcmp(lower+dot, ".urdf")) {
return typeXML; return typeXML;
else if( !strcmp(lower+dot, ".mjb") ) } else if (!std::strcmp(lower+dot, ".mjb")) {
return typeMJB; return typeMJB;
else if( !strcmp(lower+dot, ".txt") ) } else if (!std::strcmp(lower+dot, ".txt")) {
return typeTXT; return typeTXT;
else } else {
return typeUNKNOWN; return typeUNKNOWN;
} }
}
// main function // main function
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
// model and error // model and error
mjModel* m = 0; mjModel* m = 0;
char error[1000]; char error[1000];
// print help if arguments are missing // print help if arguments are missing
if( argc!=3 ) if (argc!=3) {
return finish(helpstring); return finish(helpstring);
}
// determine file types // determine file types
int type1 = filetype(argv[1]); int type1 = filetype(argv[1]);
@@ -104,42 +105,43 @@ int main(int argc, const char** argv)
// check types // check types
if (type1==typeUNKNOWN || type1==typeTXT || if (type1==typeUNKNOWN || type1==typeTXT ||
type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML) ) type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML)) {
return finish("Illegal combination of file formats"); return finish("Illegal combination of file formats");
}
// make sure output file does not exist // make sure output file does not exist
FILE* fp = fopen(argv[2], "r"); std::FILE* fp = std::fopen(argv[2], "r");
if( fp ) if (fp) {
{ std::fclose(fp);
fclose(fp);
return finish("Output file already exists"); return finish("Output file already exists");
} }
// load model // load model
if( type1==typeXML ) if (type1==typeXML) {
m = mj_loadXML(argv[1], 0, error, 1000); m = mj_loadXML(argv[1], 0, error, 1000);
else } else {
m = mj_loadModel(argv[1], 0); m = mj_loadModel(argv[1], 0);
}
// check error // check error
if( !m ) if (!m) {
{ if (type1==typeXML) {
if( type1==typeXML )
return finish(error, 0); return finish(error, 0);
else } else {
return finish("Could not load model", 0); return finish("Could not load model", 0);
} }
}
// save model // save model
if( type2==typeXML ) if (type2==typeXML) {
{ if (mj_saveLastXML(argv[2], m, error, 1000)) {
if( mj_saveLastXML(argv[2], m, error, 1000) )
return finish(error, m); return finish(error, m);
} }
else if( type2==typeMJB ) } else if (type2==typeMJB) {
mj_saveModel(m, argv[2], 0, 0); mj_saveModel(m, argv[2], 0, 0);
else } else {
mj_printModel(m, argv[2]); mj_printModel(m, argv[2]);
}
// finalize // finalize
return finish("Done", m); return finish("Done", m);
+100 -102
View File
@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include "mujoco.h"
// enable compilation with and without OpenMP support // enable compilation with and without OpenMP support
#if defined(_OPENMP) #if defined(_OPENMP)
@@ -34,7 +34,10 @@
// omp functions used below // omp functions used below
void omp_set_dynamic(int) {} void omp_set_dynamic(int) {}
void omp_set_num_threads(int) {} void omp_set_num_threads(int) {}
int omp_get_num_procs(void) {return 1;} int omp_get_num_procs(void)
{
return 1;
}
#endif #endif
@@ -56,8 +59,7 @@ double eps = 1e-6; // finite-difference epsilon
// worker function for parallel finite-difference computation of derivatives // worker function for parallel finite-difference computation of derivatives
void worker(const mjModel* m, const mjData* dmain, mjData* d, int id) void worker(const mjModel* m, const mjData* dmain, mjData* d, int id) {
{
int nv = m->nv; int nv = m->nv;
// allocate stack space for result at center // allocate stack space for result at center
@@ -81,16 +83,16 @@ void worker(const mjModel* m, const mjData* dmain, mjData* d, int id)
mju_copy(d->ctrl, dmain->ctrl, m->nu); mju_copy(d->ctrl, dmain->ctrl, m->nu);
// run full computation at center point (usually faster than copying dmain) // run full computation at center point (usually faster than copying dmain)
if( isforward ) if (isforward) {
{
mj_forward(m, d); mj_forward(m, d);
// extra solver iterations to improve warmstart (qacc) at center point // extra solver iterations to improve warmstart (qacc) at center point
for( int rep=1; rep<nwarmup; rep++ ) for (int rep=1; rep<nwarmup; rep++) {
mj_forwardSkip(m, d, mjSTAGE_VEL, 1); mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
} }
else } else {
mj_inverse(m, d); mj_inverse(m, d);
}
// select output from forward or inverse dynamics // select output from forward or inverse dynamics
mjtNum* output = (isforward ? d->qacc : d->qfrc_inverse); mjtNum* output = (isforward ? d->qacc : d->qfrc_inverse);
@@ -104,107 +106,98 @@ void worker(const mjModel* m, const mjData* dmain, mjData* d, int id)
const mjtNum* original = (isforward ? dmain->qfrc_applied : dmain->qacc); const mjtNum* original = (isforward ? dmain->qfrc_applied : dmain->qacc);
// finite-difference over force or acceleration: skip = mjSTAGE_VEL // finite-difference over force or acceleration: skip = mjSTAGE_VEL
for( int i=istart; i<iend; i++ ) for (int i=istart; i<iend; i++) {
{
// perturb selected target // perturb selected target
target[i] += eps; target[i] += eps;
// evaluate dynamics, with center warmstart // evaluate dynamics, with center warmstart
if( isforward ) if (isforward) {
{
mju_copy(d->qacc_warmstart, warmstart, m->nv); mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_VEL, 1); mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
} } else {
else
mj_inverseSkip(m, d, mjSTAGE_VEL, 1); mj_inverseSkip(m, d, mjSTAGE_VEL, 1);
}
// undo perturbation // undo perturbation
target[i] = original[i]; target[i] = original[i];
// compute column i of derivative 2 // compute column i of derivative 2
for( int j=0; j<nv; j++ ) for (int j=0; j<nv; j++) {
deriv[(3*isforward+2)*nv*nv + i + j*nv] = (output[j] - center[j])/eps; deriv[(3*isforward+2)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
} }
}
// finite-difference over velocity: skip = mjSTAGE_POS // finite-difference over velocity: skip = mjSTAGE_POS
for( int i=istart; i<iend; i++ ) for (int i=istart; i<iend; i++) {
{
// perturb velocity // perturb velocity
d->qvel[i] += eps; d->qvel[i] += eps;
// evaluate dynamics, with center warmstart // evaluate dynamics, with center warmstart
if( isforward ) if (isforward) {
{
mju_copy(d->qacc_warmstart, warmstart, m->nv); mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_POS, 1); mj_forwardSkip(m, d, mjSTAGE_POS, 1);
} } else {
else
mj_inverseSkip(m, d, mjSTAGE_POS, 1); mj_inverseSkip(m, d, mjSTAGE_POS, 1);
}
// undo perturbation // undo perturbation
d->qvel[i] = dmain->qvel[i]; d->qvel[i] = dmain->qvel[i];
// compute column i of derivative 1 // compute column i of derivative 1
for( int j=0; j<nv; j++ ) for (int j=0; j<nv; j++) {
deriv[(3*isforward+1)*nv*nv + i + j*nv] = (output[j] - center[j])/eps; deriv[(3*isforward+1)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
} }
}
// finite-difference over position: skip = mjSTAGE_NONE // finite-difference over position: skip = mjSTAGE_NONE
for( int i=istart; i<iend; i++ ) for (int i=istart; i<iend; i++) {
{
// get joint id for this dof // get joint id for this dof
int jid = m->dof_jntid[i]; int jid = m->dof_jntid[i];
// get quaternion address and dof position within quaternion (-1: not in quaternion) // get quaternion address and dof position within quaternion (-1: not in quaternion)
int quatadr = -1, dofpos = 0; int quatadr = -1, dofpos = 0;
if( m->jnt_type[jid]==mjJNT_BALL ) if (m->jnt_type[jid]==mjJNT_BALL) {
{
quatadr = m->jnt_qposadr[jid]; quatadr = m->jnt_qposadr[jid];
dofpos = i - m->jnt_dofadr[jid]; dofpos = i - m->jnt_dofadr[jid];
} } else if (m->jnt_type[jid]==mjJNT_FREE && i>=m->jnt_dofadr[jid]+3) {
else if( m->jnt_type[jid]==mjJNT_FREE && i>=m->jnt_dofadr[jid]+3 )
{
quatadr = m->jnt_qposadr[jid] + 3; quatadr = m->jnt_qposadr[jid] + 3;
dofpos = i - m->jnt_dofadr[jid] - 3; dofpos = i - m->jnt_dofadr[jid] - 3;
} }
// apply quaternion or simple perturbation // apply quaternion or simple perturbation
if( quatadr>=0 ) if (quatadr>=0) {
{
mjtNum angvel[3] = {0, 0, 0}; mjtNum angvel[3] = {0, 0, 0};
angvel[dofpos] = eps; angvel[dofpos] = eps;
mju_quatIntegrate(d->qpos+quatadr, angvel, 1); mju_quatIntegrate(d->qpos+quatadr, angvel, 1);
} } else {
else
d->qpos[m->jnt_qposadr[jid] + i - m->jnt_dofadr[jid]] += eps; d->qpos[m->jnt_qposadr[jid] + i - m->jnt_dofadr[jid]] += eps;
}
// evaluate dynamics, with center warmstart // evaluate dynamics, with center warmstart
if( isforward ) if (isforward) {
{
mju_copy(d->qacc_warmstart, warmstart, m->nv); mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_NONE, 1); mj_forwardSkip(m, d, mjSTAGE_NONE, 1);
} } else {
else
mj_inverseSkip(m, d, mjSTAGE_NONE, 1); mj_inverseSkip(m, d, mjSTAGE_NONE, 1);
}
// undo perturbation // undo perturbation
mju_copy(d->qpos, dmain->qpos, m->nq); mju_copy(d->qpos, dmain->qpos, m->nq);
// compute column i of derivative 0 // compute column i of derivative 0
for( int j=0; j<nv; j++ ) for (int j=0; j<nv; j++) {
deriv[(3*isforward+0)*nv*nv + i + j*nv] = (output[j] - center[j])/eps; deriv[(3*isforward+0)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
} }
}
mjFREESTACK mjFREESTACK
} }
// compute relative L1 norm of residual // compute relative L1 norm of residual
double relnorm(mjtNum* residual, mjtNum* base, int n) double relnorm(mjtNum* residual, mjtNum* base, int n) {
{
mjtNum L1res = 0, L1base = 0; mjtNum L1res = 0, L1base = 0;
for( int i=0; i<n; i++ ) for (int i=0; i<n; i++) {
{
L1res += mju_abs(residual[i]); L1res += mju_abs(residual[i]);
L1base += mju_abs(base[i]); L1base += mju_abs(base[i]);
} }
@@ -227,8 +220,7 @@ const char* accuracy[8] = {
// check accuracy of derivatives using known mathematical identities // check accuracy of derivatives using known mathematical identities
void checkderiv(const mjModel* m, mjData* d, mjtNum error[7]) void checkderiv(const mjModel* m, mjData* d, mjtNum error[7]) {
{
int nv = m->nv; int nv = m->nv;
// allocate space // allocate space
@@ -245,8 +237,9 @@ void checkderiv(const mjModel* m, mjData* d, mjtNum error[7])
// G2*F2 - I // G2*F2 - I
mju_mulMatMat(mat, G2, F2, nv, nv, nv); mju_mulMatMat(mat, G2, F2, nv, nv, nv);
for( int i=0; i<nv; i++ ) for (int i=0; i<nv; i++) {
mat[i*(nv+1)] -= 1; mat[i*(nv+1)] -= 1;
}
error[0] = relnorm(mat, G2, nv*nv); error[0] = relnorm(mat, G2, nv*nv);
// G2 - G2' // G2 - G2'
@@ -289,12 +282,10 @@ void checkderiv(const mjModel* m, mjData* d, mjtNum error[7])
// main function // main function
int main(int argc, char** argv) int main(int argc, char** argv) {
{
// print help if not enough arguments // print help if not enough arguments
if( argc<2 ) if (argc<2) {
{ std::printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n");
printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n");
return 1; return 1;
} }
@@ -302,62 +293,67 @@ int main(int argc, char** argv)
nthread = omp_get_num_procs(); nthread = omp_get_num_procs();
// get numeric command-line arguments // get numeric command-line arguments
if( argc>2 ) if (argc>2) {
sscanf(argv[2], "%d", &nthread); std::sscanf(argv[2], "%d", &nthread);
if( argc>3 ) }
sscanf(argv[3], "%d", &niter); if (argc>3) {
if( argc>4 ) std::sscanf(argv[3], "%d", &niter);
sscanf(argv[4], "%d", &nwarmup); }
if( argc>5 ) if (argc>4) {
sscanf(argv[5], "%d", &nepoch); std::sscanf(argv[4], "%d", &nwarmup);
if( argc>6 ) }
sscanf(argv[6], "%d", &nstep); if (argc>5) {
if( argc>7 ) std::sscanf(argv[5], "%d", &nepoch);
sscanf(argv[7], "%lf", &eps); }
if (argc>6) {
std::sscanf(argv[6], "%d", &nstep);
}
if (argc>7) {
std::sscanf(argv[7], "%lf", &eps);
}
// check number of threads // check number of threads
if( nthread<1 || nthread>MAXTHREAD ) if (nthread<1 || nthread>MAXTHREAD) {
{ std::printf("nthread must be between 1 and %d\n", MAXTHREAD);
printf("nthread must be between 1 and %d\n", MAXTHREAD);
return 1; return 1;
} }
// check number of epochs // check number of epochs
if( nepoch<1 || nepoch>MAXEPOCH ) if (nepoch<1 || nepoch>MAXEPOCH) {
{ std::printf("nepoch must be between 1 and %d\n", MAXEPOCH);
printf("nepoch must be between 1 and %d\n", MAXEPOCH);
return 1; return 1;
} }
// load model // load model
mjModel* m = 0; mjModel* m = 0;
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") ) if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
m = mj_loadModel(argv[1], NULL); m = mj_loadModel(argv[1], NULL);
else } else {
m = mj_loadXML(argv[1], NULL, NULL, 0); m = mj_loadXML(argv[1], NULL, NULL, 0);
if( !m ) }
{ if (!m) {
printf("Could not load modelfile '%s'\n", argv[1]); std::printf("Could not load modelfile '%s'\n", argv[1]);
return 1; return 1;
} }
// print arguments // print arguments
#if defined(_OPENMP) #if defined(_OPENMP)
printf("\nnthread : %d (OpenMP)\n", nthread); std::printf("\nnthread : %d (OpenMP)\n", nthread);
#else #else
printf("\nnthread : %d (serial)\n", nthread); std::printf("\nnthread : %d (serial)\n", nthread);
#endif #endif
printf("niter : %d\n", niter); std::printf("niter : %d\n", niter);
printf("nwarmup : %d\n", nwarmup); std::printf("nwarmup : %d\n", nwarmup);
printf("nepoch : %d\n", nepoch); std::printf("nepoch : %d\n", nepoch);
printf("nstep : %d\n", nstep); std::printf("nstep : %d\n", nstep);
printf("eps : %g\n\n", eps); std::printf("eps : %g\n\n", eps);
// make mjData: main, per-thread // make mjData: main, per-thread
mjData* dmain = mj_makeData(m); mjData* dmain = mj_makeData(m);
mjData* d[MAXTHREAD]; mjData* d[MAXTHREAD];
for( int n=0; n<nthread; n++ ) for (int n=0; n<nthread; n++) {
d[n] = mj_makeData(m); d[n] = mj_makeData(m);
}
// allocate derivatives // allocate derivatives
deriv = (mjtNum*) mju_malloc(6*sizeof(mjtNum)*m->nv*m->nv); deriv = (mjtNum*) mju_malloc(6*sizeof(mjtNum)*m->nv*m->nv);
@@ -376,15 +372,15 @@ int main(int argc, char** argv)
mjtNum error[MAXEPOCH][8]; mjtNum error[MAXEPOCH][8];
// run epochs, collect statistics // run epochs, collect statistics
for( int epoch=0; epoch<nepoch; epoch++ ) for (int epoch=0; epoch<nepoch; epoch++) {
{
// set solver options for main simulation // set solver options for main simulation
m->opt.iterations = save_iterations; m->opt.iterations = save_iterations;
m->opt.tolerance = save_tolerance; m->opt.tolerance = save_tolerance;
// advance main simulation for nstep // advance main simulation for nstep
for( int i=0; i<nstep; i++ ) for (int i=0; i<nstep; i++) {
mj_step(m, dmain); mj_step(m, dmain);
}
// count number of active constraints // count number of active constraints
nefc += dmain->nefc; nefc += dmain->nefc;
@@ -394,15 +390,15 @@ int main(int argc, char** argv)
m->opt.tolerance = 0; m->opt.tolerance = 0;
// test forward and inverse // test forward and inverse
for( isforward=0; isforward<2; isforward++ ) for (isforward=0; isforward<2; isforward++) {
{
// start timer // start timer
double starttm = omp_get_wtime(); double starttm = omp_get_wtime();
// run worker threads in parallel if OpenMP is enabled // run worker threads in parallel if OpenMP is enabled
#pragma omp parallel for schedule(static) #pragma omp parallel for schedule(static)
for( int n=0; n<nthread; n++ ) for (int n=0; n<nthread; n++) {
worker(m, dmain, d[n], n); worker(m, dmain, d[n], n);
}
// record duration in ms // record duration in ms
cputm[epoch][isforward] = 1000*(omp_get_wtime() - starttm); cputm[epoch][isforward] = 1000*(omp_get_wtime() - starttm);
@@ -414,30 +410,32 @@ int main(int argc, char** argv)
// compute statistics // compute statistics
double mcputm[2] = {0, 0}, merror[8] = {0, 0, 0, 0, 0, 0, 0, 0}; double mcputm[2] = {0, 0}, merror[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for( int epoch=0; epoch<nepoch; epoch++ ) for (int epoch=0; epoch<nepoch; epoch++) {
{
mcputm[0] += cputm[epoch][0]; mcputm[0] += cputm[epoch][0];
mcputm[1] += cputm[epoch][1]; mcputm[1] += cputm[epoch][1];
for( int ie=0; ie<8; ie++ ) for (int ie=0; ie<8; ie++) {
merror[ie] += error[epoch][ie]; merror[ie] += error[epoch][ie];
} }
}
// print sizes, timing, accuracy // print sizes, timing, accuracy
printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch); std::printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch);
printf("inverse : %.2f ms\n", mcputm[0]/nepoch); std::printf("inverse : %.2f ms\n", mcputm[0]/nepoch);
printf("forward : %.2f ms\n\n", mcputm[1]/nepoch); std::printf("forward : %.2f ms\n\n", mcputm[1]/nepoch);
printf("accuracy: log10(residual L1 relnorm)\n"); std::printf("accuracy: log10(residual L1 relnorm)\n");
printf("------------------------------------\n"); std::printf("------------------------------------\n");
for( int ie=0; ie<8; ie++ ) for (int ie=0; ie<8; ie++) {
printf(" %s : %.2g\n", accuracy[ie], merror[ie]/nepoch); std::printf(" %s : %.2g\n", accuracy[ie], merror[ie]/nepoch);
printf("\n"); }
std::printf("\n");
// shut down // shut down
mju_free(deriv); mju_free(deriv);
mj_deleteData(dmain); mj_deleteData(dmain);
for( int n=0; n<nthread; n++ ) for (int n=0; n<nthread; n++) {
mj_deleteData(d[n]); mj_deleteData(d[n]);
}
mj_deleteModel(m); mj_deleteModel(m);
return 0; return 0;
} }
+71 -62
View File
@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h" #include <cstdio>
#include "stdio.h" #include <cstdlib>
#include "stdlib.h" #include <cstring>
#include "string.h"
#include "mujoco.h"
// select EGL, OSMESA or GLFW // select EGL, OSMESA or GLFW
#if defined(MJ_EGL) #if defined(MJ_EGL)
@@ -26,9 +26,11 @@
OSMesaContext ctx; OSMesaContext ctx;
unsigned char buffer[10000000]; unsigned char buffer[10000000];
#else #else
#include "glfw3.h" #include <GLFW/glfw3.h>
#endif #endif
#include "array_safety.h"
namespace mju = ::mujoco::sample_util;
//-------------------------------- global data ------------------------------------------ //-------------------------------- global data ------------------------------------------
@@ -46,16 +48,17 @@ mjrContext con;
//-------------------------------- utility functions ------------------------------------ //-------------------------------- utility functions ------------------------------------
// load model, init simulation and rendering // load model, init simulation and rendering
void initMuJoCo(const char* filename) void initMuJoCo(const char* filename) {
{
// load and compile // load and compile
char error[1000] = "Could not load binary model"; char error[1000] = "Could not load binary model";
if( strlen(filename)>4 && !strcmp(filename+strlen(filename)-4, ".mjb") ) if (std::strlen(filename)>4 && !std::strcmp(filename+std::strlen(filename)-4, ".mjb")) {
m = mj_loadModel(filename, 0); m = mj_loadModel(filename, 0);
else } else {
m = mj_loadXML(filename, 0, error, 1000); m = mj_loadXML(filename, 0, error, 1000);
if( !m ) }
if (!m) {
mju_error_s("Load model error: %s", error); mju_error_s("Load model error: %s", error);
}
// make data, run one computation to initialize all fields // make data, run one computation to initialize all fields
d = mj_makeData(m); d = mj_makeData(m);
@@ -80,8 +83,7 @@ void initMuJoCo(const char* filename)
// deallocate everything // deallocate everything
void closeMuJoCo(void) void closeMuJoCo(void) {
{
mj_deleteData(d); mj_deleteData(d);
mj_deleteModel(m); mj_deleteModel(m);
mjr_freeContext(&con); mjr_freeContext(&con);
@@ -90,8 +92,7 @@ void closeMuJoCo(void)
// create OpenGL context/window // create OpenGL context/window
void initOpenGL(void) void initOpenGL(void) {
{
//------------------------ EGL //------------------------ EGL
#if defined(MJ_EGL) #if defined(MJ_EGL)
// desired config // desired config
@@ -110,56 +111,66 @@ void initOpenGL(void)
// get default display // get default display
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if( eglDpy==EGL_NO_DISPLAY ) if (eglDpy==EGL_NO_DISPLAY) {
mju_error_i("Could not get EGL display, error 0x%x\n", eglGetError()); mju_error_i("Could not get EGL display, error 0x%x\n", eglGetError());
}
// initialize // initialize
EGLint major, minor; EGLint major, minor;
if( eglInitialize(eglDpy, &major, &minor)!=EGL_TRUE ) if (eglInitialize(eglDpy, &major, &minor)!=EGL_TRUE) {
mju_error_i("Could not initialize EGL, error 0x%x\n", eglGetError()); mju_error_i("Could not initialize EGL, error 0x%x\n", eglGetError());
}
// choose config // choose config
EGLint numConfigs; EGLint numConfigs;
EGLConfig eglCfg; EGLConfig eglCfg;
if( eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE ) if (eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE) {
mju_error_i("Could not choose EGL config, error 0x%x\n", eglGetError()); mju_error_i("Could not choose EGL config, error 0x%x\n", eglGetError());
}
// bind OpenGL API // bind OpenGL API
if( eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE ) if (eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE) {
mju_error_i("Could not bind EGL OpenGL API, error 0x%x\n", eglGetError()); mju_error_i("Could not bind EGL OpenGL API, error 0x%x\n", eglGetError());
}
// create context // create context
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL); EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);
if( eglCtx==EGL_NO_CONTEXT ) if (eglCtx==EGL_NO_CONTEXT) {
mju_error_i("Could not create EGL context, error 0x%x\n", eglGetError()); mju_error_i("Could not create EGL context, error 0x%x\n", eglGetError());
}
// make context current, no surface (let OpenGL handle FBO) // make context current, no surface (let OpenGL handle FBO)
if( eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx)!=EGL_TRUE ) if (eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx)!=EGL_TRUE) {
mju_error_i("Could not make EGL context current, error 0x%x\n", eglGetError()); mju_error_i("Could not make EGL context current, error 0x%x\n", eglGetError());
}
//------------------------ OSMESA //------------------------ OSMESA
#elif defined(MJ_OSMESA) #elif defined(MJ_OSMESA)
// create context // create context
ctx = OSMesaCreateContextExt(GL_RGBA, 24, 8, 8, 0); ctx = OSMesaCreateContextExt(GL_RGBA, 24, 8, 8, 0);
if( !ctx ) if (!ctx) {
mju_error("OSMesa context creation failed"); mju_error("OSMesa context creation failed");
}
// make current // make current
if( !OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, 800, 800) ) if (!OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, 800, 800)) {
mju_error("OSMesa make current failed"); mju_error("OSMesa make current failed");
}
//------------------------ GLFW //------------------------ GLFW
#else #else
// init GLFW // init GLFW
if( !glfwInit() ) if (!glfwInit()) {
mju_error("Could not initialize GLFW"); mju_error("Could not initialize GLFW");
}
// create invisible window, single-buffered // create invisible window, single-buffered
glfwWindowHint(GLFW_VISIBLE, 0); glfwWindowHint(GLFW_VISIBLE, 0);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE); glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 800, "Invisible window", NULL, NULL); GLFWwindow* window = glfwCreateWindow(800, 800, "Invisible window", NULL, NULL);
if( !window ) if (!window) {
mju_error("Could not create GLFW window"); mju_error("Could not create GLFW window");
}
// make context current // make context current
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
@@ -168,14 +179,14 @@ void initOpenGL(void)
// close OpenGL context/window // close OpenGL context/window
void closeOpenGL(void) void closeOpenGL(void) {
{
//------------------------ EGL //------------------------ EGL
#if defined(MJ_EGL) #if defined(MJ_EGL)
// get current display // get current display
EGLDisplay eglDpy = eglGetCurrentDisplay(); EGLDisplay eglDpy = eglGetCurrentDisplay();
if( eglDpy==EGL_NO_DISPLAY ) if (eglDpy==EGL_NO_DISPLAY) {
return; return;
}
// get current context // get current context
EGLContext eglCtx = eglGetCurrentContext(); EGLContext eglCtx = eglGetCurrentContext();
@@ -184,8 +195,9 @@ void closeOpenGL(void)
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
// destroy context if valid // destroy context if valid
if( eglCtx!=EGL_NO_CONTEXT ) if (eglCtx!=EGL_NO_CONTEXT) {
eglDestroyContext(eglDpy, eglCtx); eglDestroyContext(eglDpy, eglCtx);
}
// terminate display // terminate display
eglTerminate(eglDpy); eglTerminate(eglDpy);
@@ -206,19 +218,17 @@ void closeOpenGL(void)
//-------------------------------- main function ---------------------------------------- //-------------------------------- main function ----------------------------------------
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
// check command-line arguments // check command-line arguments
if( argc!=5 ) if (argc!=5) {
{ std::printf(" USAGE: record modelfile duration fps rgbfile\n");
printf(" USAGE: record modelfile duration fps rgbfile\n");
return 0; return 0;
} }
// parse numeric arguments // parse numeric arguments
double duration = 10, fps = 30; double duration = 10, fps = 30;
sscanf(argv[2], "%lf", &duration); std::sscanf(argv[2], "%lf", &duration);
sscanf(argv[3], "%lf", &fps); std::sscanf(argv[3], "%lf", &fps);
// initialize OpenGL and MuJoCo // initialize OpenGL and MuJoCo
initOpenGL(); initOpenGL();
@@ -226,8 +236,9 @@ int main(int argc, const char** argv)
// set rendering to offscreen buffer // set rendering to offscreen buffer
mjr_setBuffer(mjFB_OFFSCREEN, &con); mjr_setBuffer(mjFB_OFFSCREEN, &con);
if( con.currentBuffer!=mjFB_OFFSCREEN ) if (con.currentBuffer!=mjFB_OFFSCREEN) {
printf("Warning: offscreen rendering not supported, using default/window framebuffer\n"); std::printf("Warning: offscreen rendering not supported, using default/window framebuffer\n");
}
// get size of active renderbuffer // get size of active renderbuffer
mjrRect viewport = mjr_maxViewport(&con); mjrRect viewport = mjr_maxViewport(&con);
@@ -235,24 +246,24 @@ int main(int argc, const char** argv)
int H = viewport.height; int H = viewport.height;
// allocate rgb and depth buffers // allocate rgb and depth buffers
unsigned char* rgb = (unsigned char*)malloc(3*W*H); unsigned char* rgb = (unsigned char*)std::malloc(3*W*H);
float* depth = (float*)malloc(sizeof(float)*W*H); float* depth = (float*)std::malloc(sizeof(float)*W*H);
if( !rgb || !depth ) if (!rgb || !depth) {
mju_error("Could not allocate buffers"); mju_error("Could not allocate buffers");
}
// create output rgb file // create output rgb file
FILE* fp = fopen(argv[4], "wb"); std::FILE* fp = std::fopen(argv[4], "wb");
if( !fp ) if (!fp) {
mju_error("Could not open rgbfile for writing"); mju_error("Could not open rgbfile for writing");
}
// main loop // main loop
double frametime = 0; double frametime = 0;
int framecount = 0; int framecount = 0;
while( d->time<duration ) while (d->time<duration) {
{
// render new frame if it is time (or first frame) // render new frame if it is time (or first frame)
if( (d->time-frametime)>1/fps || frametime==0 ) if ((d->time-frametime)>1/fps || frametime==0) {
{
// update abstract scene // update abstract scene
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn); mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
@@ -261,7 +272,7 @@ int main(int argc, const char** argv)
// add time stamp in upper-left corner // add time stamp in upper-left corner
char stamp[50]; char stamp[50];
sprintf(stamp, "Time = %.3f", d->time); mju::sprintf_arr(stamp, "Time = %.3f", d->time);
mjr_overlay(mjFONT_NORMAL, mjGRID_TOPLEFT, viewport, stamp, NULL, &con); mjr_overlay(mjFONT_NORMAL, mjGRID_TOPLEFT, viewport, stamp, NULL, &con);
// read rgb and depth buffers // read rgb and depth buffers
@@ -270,23 +281,21 @@ int main(int argc, const char** argv)
// insert subsampled depth image in lower-left corner of rgb image // insert subsampled depth image in lower-left corner of rgb image
const int NS = 3; // depth image sub-sampling const int NS = 3; // depth image sub-sampling
for (int r=0; r<H; r+=NS) for (int r=0; r<H; r+=NS)
for( int c=0; c<W; c+=NS ) for (int c=0; c<W; c+=NS) {
{
int adr = (r/NS)*W + c/NS; int adr = (r/NS)*W + c/NS;
rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] = rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] = (unsigned char)((1.0f-depth[r*W+c])*255.0f);
(unsigned char)((1.0f-depth[r*W+c])*255.0f);
} }
// write rgb image to file // write rgb image to file
fwrite(rgb, 3, W*H, fp); std::fwrite(rgb, 3, W*H, fp);
// print every 10 frames: '.' if ok, 'x' if OpenGL error // print every 10 frames: '.' if ok, 'x' if OpenGL error
if( ((framecount++)%10)==0 ) if (((framecount++)%10)==0) {
{ if (mjr_getError()) {
if( mjr_getError() ) std::printf("x");
printf("x"); } else {
else std::printf(".");
printf("."); }
} }
// save simulation time // save simulation time
@@ -296,12 +305,12 @@ int main(int argc, const char** argv)
// advance simulation // advance simulation
mj_step(m, d); mj_step(m, d);
} }
printf("\n"); std::printf("\n");
// close file, free buffers // close file, free buffers
fclose(fp); std::fclose(fp);
free(rgb); std::free(rgb);
free(depth); std::free(depth);
// close MuJoCo and OpenGL // close MuJoCo and OpenGL
closeMuJoCo(); closeMuJoCo();
+504 -455
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+92 -66
View File
@@ -12,15 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h" #include <chrono>
#include <stdlib.h> #include <cstdio>
#include <stdio.h>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <chrono>
#include <thread> #include <thread>
using namespace std; #include "mujoco.h"
// model and per-thread data // model and per-thread data
@@ -35,40 +33,52 @@ double simtime[64];
// timer // timer
chrono::system_clock::time_point tm_start; std::chrono::system_clock::time_point tm_start;
mjtNum gettm(void) mjtNum gettm(void) {
{ std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - tm_start;
chrono::duration<double> elapsed = chrono::system_clock::now() - tm_start;
return elapsed.count(); return elapsed.count();
} }
// deallocate and print message // deallocate and print message
int finish(const char* msg = NULL, mjModel* m = NULL) int finish(const char* msg = NULL, mjModel* m = NULL) {
{
// deallocate model // deallocate model
if( m ) if (m) {
mj_deleteModel(m); mj_deleteModel(m);
}
// print message // print message
if( msg ) if (msg) {
printf("%s\n", msg); std::printf("%s\n", msg);
}
return 0; return 0;
} }
// thread function // thread function
void simulate(int id, int nstep) void simulate(int id, int nstep, mjtNum ctrlnoise) {
{
// clear statistics // clear statistics
contacts[id] = 0; contacts[id] = 0;
constraints[id] = 0; constraints[id] = 0;
// run and time // run and time
double start = gettm(); double start = gettm();
for( int i=0; i<nstep; i++ ) for (int i=0; i<nstep; i++) {
{ // inject pseuso-random control noise
if (ctrlnoise)
for (int j=0; j<m->nu; j++) {
mjtNum center = 0.0;
mjtNum radius = 1.0;
mjtNum* range = m->actuator_ctrlrange + 2*j;
if (m->actuator_ctrllimited[j]) {
center = (range[1] + range[0]) / 2;
radius = (range[1] - range[0]) / 2;
}
radius *= ctrlnoise;
d[id]->ctrl[j] = center + radius * (2*mju_Halton(i, j+2) - 1);
}
// advance simulation // advance simulation
mj_step(m, d[id]); mj_step(m, d[id]);
@@ -81,22 +91,35 @@ void simulate(int id, int nstep)
// main function // main function
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
// print help if arguments are missing // print help if arguments are missing
if( argc<3 || argc>5 ) if (argc<2 || argc>6) {
return finish("\n Usage: testspeed modelfile nstep [nthread [profile]]\n"); return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
}
// read nstep and nthread // read arguments
int nstep = 0, nthread = 0, profile = 0; int nstep = 10000, nthread = 0, profile = 0;
if( sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0 ) // inject small noise by default, to avoid fixed contact state
mjtNum ctrlnoise = 0.01;
if (argc>2)
if (std::sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0) {
return finish("Invalid nstep argument"); return finish("Invalid nstep argument");
}
if (argc>3) if (argc>3)
if( sscanf(argv[3], "%d", &nthread)!=1 ) if (std::sscanf(argv[3], "%d", &nthread)!=1) {
return finish("Invalid nthread argument"); return finish("Invalid nthread argument");
}
if (argc>4) if (argc>4)
if( sscanf(argv[4], "%d", &profile)!=1 ) if (std::sscanf(argv[4], "%lf", &ctrlnoise)!=1) {
return finish("Invalid ctrlnoise argument");
}
if (argc>5)
if (std::sscanf(argv[5], "%d", &profile)!=1) {
return finish("Invalid profile argument"); return finish("Invalid profile argument");
}
// clamp ctrlnoise to [0.0, 1.0]
ctrlnoise = mjMAX(0.0, mjMIN(ctrlnoise, 1.0));
// clamp nthread to [1, 64] // clamp nthread to [1, 64]
nthread = mjMAX(1, mjMIN(64, nthread)); nthread = mjMAX(1, mjMIN(64, nthread));
@@ -107,24 +130,25 @@ int main(int argc, const char** argv)
// load model // load model
char error[1000] = "Could not load binary model"; char error[1000] = "Could not load binary model";
if( binary ) if (binary) {
m = mj_loadModel(argv[1], 0); m = mj_loadModel(argv[1], 0);
else } else {
m = mj_loadXML(argv[1], 0, error, 1000); m = mj_loadXML(argv[1], 0, error, 1000);
if( !m ) }
if (!m) {
return finish(error); return finish(error);
}
// make per-thread data // make per-thread data
int testkey = mj_name2id(m, mjOBJ_KEY, "test"); int testkey = mj_name2id(m, mjOBJ_KEY, "test");
for( int id=0; id<nthread; id++ ) for (int id=0; id<nthread; id++) {
{
d[id] = mj_makeData(m); d[id] = mj_makeData(m);
if( !d[id] ) if (!d[id]) {
return finish("Could not allocate mjData", m); return finish("Could not allocate mjData", m);
}
// init to keyframe "test" if present // init to keyframe "test" if present
if( testkey>=0 ) if (testkey>=0) {
{
mju_copy(d[id]->qpos, m->key_qpos + testkey*m->nq, m->nq); mju_copy(d[id]->qpos, m->key_qpos + testkey*m->nq, m->nq);
mju_copy(d[id]->qvel, m->key_qvel + testkey*m->nv, m->nv); mju_copy(d[id]->qvel, m->key_qvel + testkey*m->nv, m->nv);
mju_copy(d[id]->act, m->key_act + testkey*m->na, m->na); mju_copy(d[id]->act, m->key_act + testkey*m->na, m->na);
@@ -132,63 +156,65 @@ int main(int argc, const char** argv)
} }
// install timer callback for profiling if requested // install timer callback for profiling if requested
tm_start = chrono::system_clock::now(); tm_start = std::chrono::system_clock::now();
if( profile ) if (profile) {
mjcb_time = gettm; mjcb_time = gettm;
}
// print start // print start
if( nthread>1 ) if (nthread>1) {
printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep); std::printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep);
else } else {
printf("\nRunning %d steps at dt = %g ...\n\n", nstep, m->opt.timestep); std::printf("\nRunning %d steps at dt = %g ...\n\n", nstep, m->opt.timestep);
}
// run simulation, record total time // run simulation, record total time
thread th[64]; std::thread th[64];
double starttime = gettm(); double starttime = gettm();
for( int id=0; id<nthread; id++ ) for (int id=0; id<nthread; id++) {
th[id] = thread(simulate, id, nstep); th[id] = std::thread(simulate, id, nstep, ctrlnoise);
for( int id=0; id<nthread; id++ ) }
for (int id=0; id<nthread; id++) {
th[id].join(); th[id].join();
}
double tottime = gettm() - starttime; double tottime = gettm() - starttime;
// all-thread summary // all-thread summary
if( nthread>1 ) if (nthread>1) {
{ std::printf("Summary for all %d threads\n\n", nthread);
printf("Summary for all %d threads\n\n", nthread); std::printf(" Total simulation time : %.2f s\n", tottime);
printf(" Total simulation time : %.2f s\n", tottime); std::printf(" Total steps per second : %.0f\n", nthread*nstep/tottime);
printf(" Total steps per second : %.0f\n", nthread*nstep/tottime); std::printf(" Total realtime factor : %.2f x\n", nthread*nstep*m->opt.timestep/tottime);
printf(" Total realtime factor : %.2f x\n", nthread*nstep*m->opt.timestep/tottime); std::printf(" Total time per step : %.4f ms\n\n", 1000*tottime/(nthread*nstep));
printf(" Total time per step : %.4f ms\n\n", 1000*tottime/(nthread*nstep));
printf("Details for thread 0\n\n"); std::printf("Details for thread 0\n\n");
} }
// details for thread 0 // details for thread 0
printf(" Simulation time : %.2f s\n", simtime[0]); std::printf(" Simulation time : %.2f s\n", simtime[0]);
printf(" Steps per second : %.0f\n", nstep/simtime[0]); std::printf(" Steps per second : %.0f\n", nstep/simtime[0]);
printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]); std::printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]);
printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep); std::printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep);
printf(" Contacts per step : %d\n", contacts[0]/nstep); std::printf(" Contacts per step : %.2f\n", static_cast<float>(contacts[0])/nstep);
printf(" Constraints per step : %d\n", constraints[0]/nstep); std::printf(" Constraints per step : %.2f\n", static_cast<float>(constraints[0])/nstep);
printf(" Degrees of freedom : %d\n\n", m->nv); std::printf(" Degrees of freedom : %d\n\n", m->nv);
// profiler results for thread 0 // profiler results for thread 0
if( profile ) if (profile) {
{
printf(" Profiler phase (ms per step)\n"); printf(" Profiler phase (ms per step)\n");
mjtNum tstep = d[0]->timer[mjTIMER_STEP].duration/d[0]->timer[mjTIMER_STEP].number; mjtNum tstep = d[0]->timer[mjTIMER_STEP].duration/d[0]->timer[mjTIMER_STEP].number;
for (int i=0; i<mjNTIMER; i++) for (int i=0; i<mjNTIMER; i++)
if( d[0]->timer[i].number>0 ) if (d[0]->timer[i].number>0) {
{
mjtNum istep = d[0]->timer[i].duration/d[0]->timer[i].number; mjtNum istep = d[0]->timer[i].duration/d[0]->timer[i].number;
printf(" %16s : %.5f (%6.2f %%)\n", mjTIMERSTRING[i], std::printf(" %16s : %.5f (%6.2f %%)\n", mjTIMERSTRING[i],
1000*istep, 100*istep/tstep); 1000*istep, 100*istep/tstep);
} }
} }
// free per-thread data // free per-thread data
for( int id=0; id<nthread; id++ ) for (int id=0; id<nthread; id++) {
mj_deleteData(d[id]); mj_deleteData(d[id]);
}
// finalize // finalize
return finish(); return finish();
Regular → Executable
+46 -50
View File
@@ -12,74 +12,64 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "mujoco.h" #include <cstddef>
#include "mjxmacro.h" #include <cstdio>
#include <stdlib.h>
#include <stdio.h>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <chrono>
#include "mjxmacro.h"
#include "mujoco.h"
using namespace std; #include "array_safety.h"
namespace mju = ::mujoco::sample_util;
static constexpr int kFieldSize = 500;
// help // help
const char helpstring[] = "\n Usage: testxml modelfile.xml\n"; const char helpstring[] = "\n Usage: testxml modelfile.xml\n";
// deallocate and print message // deallocate and print message
int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0) int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0) {
{
// deallocated everything // deallocated everything
if( d ) if (d) {
mj_deleteData(d); mj_deleteData(d);
if( m ) }
if (m) {
mj_deleteModel(m); mj_deleteModel(m);
}
// print message // print message
if( msg ) if (msg) {
printf("%s\n", msg); std::printf("%s\n", msg);
}
return 0; return 0;
} }
// return absolute difference if it is below 1, relative difference otherwise // return absolute difference if it is below 1, relative difference otherwise
static mjtNum _compare(mjtNum val1, mjtNum val2) static mjtNum _compare(mjtNum val1, mjtNum val2) {
{
mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2)); mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2));
if( magnitude>1.0 ) if (magnitude>1.0) {
return mju_abs(val1-val2) / magnitude; return mju_abs(val1-val2) / magnitude;
else } else {
return mju_abs(val1-val2); return mju_abs(val1-val2);
} }
}
// compare two models, return largest difference and field name // compare two models, return largest difference and field name
mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field) mjtNum compareModel(const mjModel* m1, const mjModel* m2, char (&field)[kFieldSize]) {
{
int r, c; int r, c;
mjtNum dif, maxdif = 0.0; mjtNum dif, maxdif = 0.0;
// define symbols corresponding to number of columns (needed in MJMODEL_POINTERS) // define symbols corresponding to number of columns (needed in MJMODEL_POINTERS)
int nq = m1->nq; MJMODEL_POINTERS_PREAMBLE(m1);
int nv = m1->nv;
int na = m1->na;
int nmocap3 = 3*m1->nmocap;
int nmocap4 = 4*m1->nmocap;
int nuser_body = m1->nuser_body;
int nuser_jnt = m1->nuser_jnt;
int nuser_geom = m1->nuser_geom;
int nuser_site = m1->nuser_site;
int nuser_cam = m1->nuser_cam;
int nuser_tendon = m1->nuser_tendon;
int nuser_actuator = m1->nuser_actuator;
int nuser_sensor = m1->nuser_sensor;
// compare ints // compare ints
#define X(name) if(m1->name!=m2->name) {strcpy(field, #name); return 1.0;} #define X(name) if(m1->name!=m2->name) {mju::strcpy_arr(field, #name); return 1.0;}
MJMODEL_INTS MJMODEL_INTS
#undef X #undef X
@@ -89,7 +79,7 @@ mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
for( r=0; r<m1->nr; r++ ) \ for( r=0; r<m1->nr; r++ ) \
for( c=0; c<nc; c++ ) { \ for( c=0; c<nc; c++ ) { \
dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \ dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} } if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
MJMODEL_POINTERS MJMODEL_POINTERS
#undef X #undef X
@@ -97,7 +87,7 @@ mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
// compare scalars in mjOption // compare scalars in mjOption
#define X(type, name) \ #define X(type, name) \
dif = _compare(m1->opt.name, m2->opt.name); \ dif = _compare(m1->opt.name, m2->opt.name); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);}
MJOPTION_SCALARS MJOPTION_SCALARS
#undef X #undef X
@@ -106,7 +96,7 @@ mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
#define X(name, n) \ #define X(name, n) \
for( c=0; c<n; c++ ) { \ for( c=0; c<n; c++ ) { \
dif = _compare(m1->opt.name[c], m2->opt.name[c]); \ dif = _compare(m1->opt.name[c], m2->opt.name[c]); \
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} } if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
MJOPTION_VECTORS MJOPTION_VECTORS
#undef X #undef X
@@ -119,51 +109,57 @@ mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
// main function // main function
int main(int argc, const char** argv) int main(int argc, const char** argv) {
{
// print help if arguments are missing // print help if arguments are missing
if( argc<2 ) if (argc<2) {
return finish(helpstring); return finish(helpstring);
}
// get filename, check file type // get filename, check file type
std::string filename(argv[1]); std::string filename(argv[1]);
if( filename.find(".xml")==std::string::npos ) if (filename.find(".xml")==std::string::npos) {
return finish("xml model file is required"); return finish("xml model file is required");
}
// load model // load model
char error[1000]; char error[1000];
mjModel* m = mj_loadXML(argv[1], 0, error, 1000); mjModel* m = mj_loadXML(argv[1], 0, error, 1000);
if( !m ) if (!m) {
return finish(error); return finish(error);
}
// make data // make data
mjData* d = mj_makeData(m); mjData* d = mj_makeData(m);
if( !d ) if (!d) {
return finish("Could not allocate mjData", m); return finish("Could not allocate mjData", m);
}
// prepare temp filename in the same directory as original (for asset loading) // prepare temp filename in the same directory as original (for asset loading)
std::string tempfile; std::string tempfile;
size_t lastpath = filename.find_last_of("/\\"); std::size_t lastpath = filename.find_last_of("/\\");
if( lastpath==std::string::npos ) if (lastpath==std::string::npos) {
tempfile = "_tempfile_.xml"; tempfile = "_tempfile_.xml";
else } else {
tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml"; tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml";
}
// save // save
if( !mj_saveLastXML(tempfile.c_str(), m, error, 1000) ) if (!mj_saveLastXML(tempfile.c_str(), m, error, 1000)) {
return finish(error, m, d); return finish(error, m, d);
}
// load back // load back
mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100); mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100);
if( !mtemp ) if (!mtemp) {
return finish(error, m, d); return finish(error, m, d);
}
// compare // compare
char field[500] = ""; char field[kFieldSize] = "";
mjtNum result = compareModel(m, mtemp, field); mjtNum result = compareModel(m, mtemp, field);
printf("\nComparison of original and saved model\n"); std::printf("\nComparison of original and saved model\n");
printf(" Max difference : %.3g\n", result); std::printf(" Max difference : %.3g\n", result);
printf(" Field name : %s\n", field); std::printf(" Field name : %s\n", field);
// delete temp model and file // delete temp model and file
mj_deleteModel(mtemp); mj_deleteModel(mtemp);
Executable → Regular
+41 -50
View File
@@ -13,15 +13,14 @@
// limitations under the License. // limitations under the License.
#include "uitools.h" #include "uitools.h"
#include "stdio.h" #include <stdio.h>
#include "string.h" #include <string.h>
//-------------------------------- Internal GLFW callbacks ------------------------------ //-------------------------------- Internal GLFW callbacks ------------------------------
// update state // update state
static void uiUpdateState(GLFWwindow* wnd) static void uiUpdateState(GLFWwindow* wnd) {
{
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
@@ -40,8 +39,7 @@ static void uiUpdateState(GLFWwindow* wnd)
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS); glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS);
// swap left and right if Alt // swap left and right if Alt
if( state->alt ) if (state->alt) {
{
int tmp = state->left; int tmp = state->left;
state->left = state->right; state->left = state->right;
state->right = tmp; state->right = tmp;
@@ -63,18 +61,17 @@ static void uiUpdateState(GLFWwindow* wnd)
state->y = y; state->y = y;
// find mouse rectangle // find mouse rectangle
state->mouserect = mjr_findRect(mju_round(x), mju_round(y), state->mouserect = mjr_findRect(mju_round(x), mju_round(y), state->nrect-1, state->rect+1) + 1;
state->nrect-1, state->rect+1) + 1;
} }
// keyboard // keyboard
static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods) static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods) {
{
// release: nothing to do // release: nothing to do
if( act==GLFW_RELEASE ) if (act==GLFW_RELEASE) {
return; return;
}
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
@@ -95,8 +92,7 @@ static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods
// mouse button // mouse button
static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods) static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods) {
{
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
@@ -105,31 +101,32 @@ static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods)
uiUpdateState(wnd); uiUpdateState(wnd);
// translate button // translate button
if( button==GLFW_MOUSE_BUTTON_LEFT ) if (button==GLFW_MOUSE_BUTTON_LEFT) {
button = mjBUTTON_LEFT; button = mjBUTTON_LEFT;
else if( button==GLFW_MOUSE_BUTTON_RIGHT ) } else if (button==GLFW_MOUSE_BUTTON_RIGHT) {
button = mjBUTTON_RIGHT; button = mjBUTTON_RIGHT;
else } else {
button = mjBUTTON_MIDDLE; button = mjBUTTON_MIDDLE;
}
// swap left and right if Alt // swap left and right if Alt
if (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS || if (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS ) glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS) {
{ if (button==mjBUTTON_LEFT) {
if( button==mjBUTTON_LEFT )
button = mjBUTTON_RIGHT; button = mjBUTTON_RIGHT;
else if( button==mjBUTTON_RIGHT ) } else if (button==mjBUTTON_RIGHT) {
button = mjBUTTON_LEFT; button = mjBUTTON_LEFT;
} }
}
// press // press
if( act==GLFW_PRESS ) if (act==GLFW_PRESS) {
{
// detect doubleclick: 250 ms // detect doubleclick: 250 ms
if( button==state->button && glfwGetTime()-state->buttontime<0.25 ) if (button==state->button && glfwGetTime()-state->buttontime<0.25) {
state->doubleclick = 1; state->doubleclick = 1;
else } else {
state->doubleclick = 0; state->doubleclick = 0;
}
// set info // set info
state->type = mjEVENT_PRESS; state->type = mjEVENT_PRESS;
@@ -137,23 +134,22 @@ static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods)
state->buttontime = glfwGetTime(); state->buttontime = glfwGetTime();
// start dragging // start dragging
if( state->mouserect ) if (state->mouserect) {
{
state->dragbutton = state->button; state->dragbutton = state->button;
state->dragrect = state->mouserect; state->dragrect = state->mouserect;
} }
} }
// release // release
else else {
state->type = mjEVENT_RELEASE; state->type = mjEVENT_RELEASE;
}
// application-specific processing // application-specific processing
ptr->uiEvent(state); ptr->uiEvent(state);
// stop dragging after application processing // stop dragging after application processing
if( state->type==mjEVENT_RELEASE ) if (state->type==mjEVENT_RELEASE) {
{
state->dragrect = 0; state->dragrect = 0;
state->dragbutton = 0; state->dragbutton = 0;
} }
@@ -162,15 +158,15 @@ static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods)
// mouse move // mouse move
static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos) static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos) {
{
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
// no buttons down: nothing to do // no buttons down: nothing to do
if( !state->left && !state->right && !state->middle ) if (!state->left && !state->right && !state->middle) {
return; return;
}
// update state // update state
uiUpdateState(wnd); uiUpdateState(wnd);
@@ -185,8 +181,7 @@ static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos)
// scroll // scroll
static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset) static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset) {
{
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
@@ -206,8 +201,7 @@ static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset)
// resize // resize
static void uiResize(GLFWwindow* wnd, int width, int height) static void uiResize(GLFWwindow* wnd, int width, int height) {
{
// extract data from user pointer // extract data from user pointer
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd); uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
@@ -226,17 +220,17 @@ static void uiResize(GLFWwindow* wnd, int width, int height)
state->dragrect = 0; state->dragrect = 0;
// application-specific processing (unless called with 0,0 from uiModify) // application-specific processing (unless called with 0,0 from uiModify)
if( width && height ) if (width && height) {
ptr->uiEvent(state); ptr->uiEvent(state);
} }
}
//----------------------------------- Public API ---------------------------------------- //----------------------------------- Public API ----------------------------------------
// Compute suitable font scale. // Compute suitable font scale.
int uiFontScale(GLFWwindow* wnd) int uiFontScale(GLFWwindow* wnd) {
{
// compute framebuffer-to-window ratio // compute framebuffer-to-window ratio
int width_win, width_buf, height; int width_win, width_buf, height;
glfwGetWindowSize(wnd, &width_win, &height); glfwGetWindowSize(wnd, &width_win, &height);
@@ -251,12 +245,13 @@ int uiFontScale(GLFWwindow* wnd)
// estimate font scaling, guard against unrealistic PPI // estimate font scaling, guard against unrealistic PPI
int fs; int fs;
if( width_buf>width_win ) if (width_buf>width_win) {
fs = mju_round(b2w * 100); fs = mju_round(b2w * 100);
else if( PPI>50 && PPI<350 ) } else if (PPI>50 && PPI<350) {
fs = mju_round(PPI); fs = mju_round(PPI);
else } else {
fs = 150; fs = 150;
}
fs = mju_round(fs * 0.02) * 50; fs = mju_round(fs * 0.02) * 50;
fs = mjMIN(300, mjMAX(100, fs)); fs = mjMIN(300, mjMAX(100, fs));
@@ -267,8 +262,7 @@ int uiFontScale(GLFWwindow* wnd)
// Set internal and user-supplied UI callbacks in GLFW window. // Set internal and user-supplied UI callbacks in GLFW window.
void uiSetCallback(GLFWwindow* wnd, mjuiState* state, void uiSetCallback(GLFWwindow* wnd, mjuiState* state,
uiEventFn uiEvent, uiLayoutFn uiLayout) uiEventFn uiEvent, uiLayoutFn uiLayout) {
{
// make container with user-supplied objects and set window pointer // make container with user-supplied objects and set window pointer
uiUserPointer* ptr = (uiUserPointer*) mju_malloc(sizeof(uiUserPointer)); uiUserPointer* ptr = (uiUserPointer*) mju_malloc(sizeof(uiUserPointer));
ptr->state = state; ptr->state = state;
@@ -293,11 +287,9 @@ void uiSetCallback(GLFWwindow* wnd, mjuiState* state,
// Clear UI callbacks in GLFW window. // Clear UI callbacks in GLFW window.
void uiClearCallback(GLFWwindow* wnd) void uiClearCallback(GLFWwindow* wnd) {
{
// clear container // clear container
if( glfwGetWindowUserPointer(wnd) ) if (glfwGetWindowUserPointer(wnd)) {
{
mju_free(glfwGetWindowUserPointer(wnd)); mju_free(glfwGetWindowUserPointer(wnd));
glfwSetWindowUserPointer(wnd, NULL); glfwSetWindowUserPointer(wnd, NULL);
} }
@@ -313,8 +305,7 @@ void uiClearCallback(GLFWwindow* wnd)
// Modify UI structure. // Modify UI structure.
void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con) void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con) {
{
mjui_resize(ui, con); mjui_resize(ui, con);
mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con); mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con);
uiResize(wnd, 0, 0); uiResize(wnd, 0, 0);
Executable → Regular
+3 -6
View File
@@ -16,14 +16,12 @@
#define MUJOCO_UITOOLS_H_ #define MUJOCO_UITOOLS_H_
#include "GLFW/glfw3.h"
#include "mujoco.h" #include "mujoco.h"
#include "glfw3.h"
// this is a C-API // this is a C-API
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" extern "C" {
{
#endif #endif
@@ -32,8 +30,7 @@ typedef void (*uiEventFn)(mjuiState* state);
typedef void (*uiLayoutFn)(mjuiState* state); typedef void (*uiLayoutFn)(mjuiState* state);
// Container for GLFW window pointer. // Container for GLFW window pointer.
struct _uiUserPointer struct _uiUserPointer {
{
mjuiState* state; mjuiState* state;
uiEventFn uiEvent; uiEventFn uiEvent;
uiLayoutFn uiLayout; uiLayoutFn uiLayout;