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
+228 -233
View File
@@ -15,310 +15,305 @@
#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) -----------------------------------------
{
mjWARN_INERTIA = 0, // (near) singular inertia matrix
mjWARN_CONTACTFULL, // too many contacts in contact list
mjWARN_CNSTRFULL, // too many constraints
mjWARN_VGEOMFULL, // too many visual geoms
mjWARN_BADQPOS, // bad number in qpos
mjWARN_BADQVEL, // bad number in qvel
mjWARN_BADQACC, // bad number in qacc
mjWARN_BADCTRL, // bad number in ctrl
mjNWARNING // number of warnings typedef enum mjtWarning_ { // warning types
mjWARN_INERTIA = 0, // (near) singular inertia matrix
mjWARN_CONTACTFULL, // too many contacts in contact list
mjWARN_CNSTRFULL, // too many constraints
mjWARN_VGEOMFULL, // too many visual geoms
mjWARN_BADQPOS, // bad number in qpos
mjWARN_BADQVEL, // bad number in qvel
mjWARN_BADQACC, // bad number in qacc
mjWARN_BADCTRL, // bad number in ctrl
mjNWARNING // number of warnings
} 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 mjTIMER_INVERSE, // inverse
mjTIMER_INVERSE, // inverse
// breakdown of step/forward // breakdown of step/forward
mjTIMER_POSITION, // fwdPosition mjTIMER_POSITION, // fwdPosition
mjTIMER_VELOCITY, // fwdVelocity mjTIMER_VELOCITY, // fwdVelocity
mjTIMER_ACTUATION, // fwdActuation mjTIMER_ACTUATION, // fwdActuation
mjTIMER_ACCELERATION, // fwdAcceleration mjTIMER_ACCELERATION, // fwdAcceleration
mjTIMER_CONSTRAINT, // fwdConstraint mjTIMER_CONSTRAINT, // fwdConstraint
// breakdown of fwdPosition // breakdown of fwdPosition
mjTIMER_POS_KINEMATICS, // kinematics, com, tendon, transmission mjTIMER_POS_KINEMATICS, // kinematics, com, tendon, transmission
mjTIMER_POS_INERTIA, // inertia computations mjTIMER_POS_INERTIA, // inertia computations
mjTIMER_POS_COLLISION, // collision detection mjTIMER_POS_COLLISION, // collision detection
mjTIMER_POS_MAKE, // make constraints mjTIMER_POS_MAKE, // make constraints
mjTIMER_POS_PROJECT, // project constraints mjTIMER_POS_PROJECT, // project constraints
mjNTIMER // number of timers mjNTIMER // number of timers
} 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 mjtNum frame[9]; // normal is in [0-2]
mjtNum frame[9]; // normal is in [0-2]
// contact parameters set by mj_collideGeoms // contact parameters set by mj_collideGeoms
mjtNum includemargin; // include if dist<includemargin=margin-gap mjtNum includemargin; // include if dist<includemargin=margin-gap
mjtNum friction[5]; // tangent1, 2, spin, roll1, 2 mjtNum friction[5]; // tangent1, 2, spin, roll1, 2
mjtNum solref[mjNREF]; // constraint solver reference mjtNum solref[mjNREF]; // constraint solver reference
mjtNum solimp[mjNIMP]; // constraint solver impedance mjtNum solimp[mjNIMP]; // constraint solver impedance
// internal storage used by solver // internal storage used by solver
mjtNum mu; // friction of regularized cone, set by mj_makeConstraint mjtNum mu; // friction of regularized cone, set by mj_makeConstraint
mjtNum H[36]; // cone Hessian, set by mj_updateConstraint mjtNum H[36]; // cone Hessian, set by mj_updateConstraint
// contact descriptors set by mj_collideGeoms // contact descriptors set by mj_collideGeoms
int dim; // contact space dimensionality: 1, 3, 4 or 6 int dim; // contact space dimensionality: 1, 3, 4 or 6
int geom1; // id of geom 1 int geom1; // id of geom 1
int geom2; // id of geom 2 int geom2; // id of geom 2
// flag set by mj_fuseContact or mj_instantianteEquality // flag set by mj_fuseContact or mj_instantianteEquality
int exclude; // 0: include, 1: in gap, 2: fused, 3: equality, 4: no dofs int exclude; // 0: include, 1: in gap, 2: fused, 3: equality, 4: no dofs
// 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 int nactive; // number of active constraints
int nactive; // number of active constraints int nchange; // number of constraint state changes
int nchange; // number of constraint state changes 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
// stack pointer // stack pointer
int pstack; // first available mjtNum address in stack int pstack; // first available mjtNum address in stack
// memory utilization stats // memory utilization stats
int maxuse_stack; // maximum stack allocation int maxuse_stack; // maximum stack allocation
int maxuse_con; // maximum number of contacts int maxuse_con; // maximum number of contacts
int maxuse_efc; // maximum number of scalar constraints int maxuse_efc; // maximum number of scalar constraints
// diagnostics // diagnostics
mjWarningStat warning[mjNWARNING]; // warning statistics mjWarningStat warning[mjNWARNING]; // warning statistics
mjTimerStat timer[mjNTIMER]; // timer statistics mjTimerStat timer[mjNTIMER]; // timer statistics
mjSolverStat solver[mjNSOLVER]; // solver statistics per iteration mjSolverStat solver[mjNSOLVER]; // solver statistics per iteration
int solver_iter; // number of solver iterations int solver_iter; // number of solver iterations
int solver_nnz; // number of non-zeros in Hessian or efc_AR int solver_nnz; // number of non-zeros in Hessian or efc_AR
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
// variable sizes // variable sizes
int ne; // number of equality constraints int ne; // number of equality constraints
int nf; // number of friction constraints int nf; // number of friction constraints
int nefc; // number of constraints int nefc; // number of constraints
int ncon; // number of detected contacts int ncon; // number of detected contacts
// global properties // global properties
mjtNum time; // simulation time mjtNum time; // simulation time
mjtNum energy[2]; // potential, kinetic energy mjtNum energy[2]; // potential, kinetic energy
//-------------------------------- end of info header //-------------------------------- end of info header
// buffers // buffers
void* buffer; // main buffer; all pointers point in it (nbuffer bytes) void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
mjtNum* stack; // stack buffer (nstack mjtNums) mjtNum* stack; // stack buffer (nstack mjtNums)
//-------------------------------- main inputs and outputs of the computation //-------------------------------- main inputs and outputs of the computation
// state // state
mjtNum* qpos; // position (nq x 1) mjtNum* qpos; // position (nq x 1)
mjtNum* qvel; // velocity (nv x 1) mjtNum* qvel; // velocity (nv x 1)
mjtNum* act; // actuator activation (na x 1) mjtNum* act; // actuator activation (na x 1)
mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1) mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1)
// control // control
mjtNum* ctrl; // control (nu x 1) mjtNum* ctrl; // control (nu x 1)
mjtNum* qfrc_applied; // applied generalized force (nv x 1) mjtNum* qfrc_applied; // applied generalized force (nv x 1)
mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6) mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6)
// dynamics // dynamics
mjtNum* qacc; // acceleration (nv x 1) mjtNum* qacc; // acceleration (nv x 1)
mjtNum* act_dot; // time-derivative of actuator activation (na x 1) mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
// mocap data // mocap data
mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3) mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3)
mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4) mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4)
// user data // user data
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1) mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
// sensors // sensors
mjtNum* sensordata; // sensor data array (nsensordata x 1) mjtNum* sensordata; // sensor data array (nsensordata x 1)
//-------------------------------- POSITION dependent //-------------------------------- POSITION dependent
// computed by mj_fwdPosition/mj_kinematics // computed by mj_fwdPosition/mj_kinematics
mjtNum* xpos; // Cartesian position of body frame (nbody x 3) mjtNum* xpos; // Cartesian position of body frame (nbody x 3)
mjtNum* xquat; // Cartesian orientation of body frame (nbody x 4) mjtNum* xquat; // Cartesian orientation of body frame (nbody x 4)
mjtNum* xmat; // Cartesian orientation of body frame (nbody x 9) mjtNum* xmat; // Cartesian orientation of body frame (nbody x 9)
mjtNum* xipos; // Cartesian position of body com (nbody x 3) mjtNum* xipos; // Cartesian position of body com (nbody x 3)
mjtNum* ximat; // Cartesian orientation of body inertia (nbody x 9) mjtNum* ximat; // Cartesian orientation of body inertia (nbody x 9)
mjtNum* xanchor; // Cartesian position of joint anchor (njnt x 3) mjtNum* xanchor; // Cartesian position of joint anchor (njnt x 3)
mjtNum* xaxis; // Cartesian joint axis (njnt x 3) mjtNum* xaxis; // Cartesian joint axis (njnt x 3)
mjtNum* geom_xpos; // Cartesian geom position (ngeom x 3) mjtNum* geom_xpos; // Cartesian geom position (ngeom x 3)
mjtNum* geom_xmat; // Cartesian geom orientation (ngeom x 9) mjtNum* geom_xmat; // Cartesian geom orientation (ngeom x 9)
mjtNum* site_xpos; // Cartesian site position (nsite x 3) mjtNum* site_xpos; // Cartesian site position (nsite x 3)
mjtNum* site_xmat; // Cartesian site orientation (nsite x 9) mjtNum* site_xmat; // Cartesian site orientation (nsite x 9)
mjtNum* cam_xpos; // Cartesian camera position (ncam x 3) mjtNum* cam_xpos; // Cartesian camera position (ncam x 3)
mjtNum* cam_xmat; // Cartesian camera orientation (ncam x 9) mjtNum* cam_xmat; // Cartesian camera orientation (ncam x 9)
mjtNum* light_xpos; // Cartesian light position (nlight x 3) mjtNum* light_xpos; // Cartesian light position (nlight x 3)
mjtNum* light_xdir; // Cartesian light direction (nlight x 3) mjtNum* light_xdir; // Cartesian light direction (nlight x 3)
// computed by mj_fwdPosition/mj_comPos // computed by mj_fwdPosition/mj_comPos
mjtNum* subtree_com; // center of mass of each subtree (nbody x 3) mjtNum* subtree_com; // center of mass of each subtree (nbody x 3)
mjtNum* cdof; // com-based motion axis of each dof (nv x 6) mjtNum* cdof; // com-based motion axis of each dof (nv x 6)
mjtNum* cinert; // com-based body inertia and mass (nbody x 10) mjtNum* cinert; // com-based body inertia and mass (nbody x 10)
// computed by mj_fwdPosition/mj_tendon // computed by mj_fwdPosition/mj_tendon
int* ten_wrapadr; // start address of tendon's path (ntendon x 1) int* ten_wrapadr; // start address of tendon's path (ntendon x 1)
int* ten_wrapnum; // number of wrap points in path (ntendon x 1) int* ten_wrapnum; // number of wrap points in path (ntendon x 1)
int* ten_J_rownnz; // number of non-zeros in Jacobian row (ntendon x 1) int* ten_J_rownnz; // number of non-zeros in Jacobian row (ntendon x 1)
int* ten_J_rowadr; // row start address in colind array (ntendon x 1) int* ten_J_rowadr; // row start address in colind array (ntendon x 1)
int* ten_J_colind; // column indices in sparse Jacobian (ntendon x nv) int* ten_J_colind; // column indices in sparse Jacobian (ntendon x nv)
mjtNum* ten_length; // tendon lengths (ntendon x 1) mjtNum* ten_length; // tendon lengths (ntendon x 1)
mjtNum* ten_J; // tendon Jacobian (ntendon x nv) mjtNum* ten_J; // tendon Jacobian (ntendon x nv)
int* wrap_obj; // geom id; -1: site; -2: pulley (nwrap*2 x 1) int* wrap_obj; // geom id; -1: site; -2: pulley (nwrap*2 x 1)
mjtNum* wrap_xpos; // Cartesian 3D points in all path (nwrap*2 x 3) mjtNum* wrap_xpos; // Cartesian 3D points in all path (nwrap*2 x 3)
// computed by mj_fwdPosition/mj_transmission // computed by mj_fwdPosition/mj_transmission
mjtNum* actuator_length; // actuator lengths (nu x 1) mjtNum* actuator_length; // actuator lengths (nu x 1)
mjtNum* actuator_moment; // actuator moments (nu x nv) mjtNum* actuator_moment; // actuator moments (nu x nv)
// computed by mj_fwdPosition/mj_crb // computed by mj_fwdPosition/mj_crb
mjtNum* crb; // com-based composite inertia and mass (nbody x 10) mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
mjtNum* qM; // total inertia (nM x 1) mjtNum* qM; // total inertia (nM x 1)
// computed by mj_fwdPosition/mj_factorM // computed by mj_fwdPosition/mj_factorM
mjtNum* qLD; // L'*D*L factorization of M (nM x 1) mjtNum* qLD; // L'*D*L factorization of M (nM x 1)
mjtNum* qLDiagInv; // 1/diag(D) (nv x 1) mjtNum* qLDiagInv; // 1/diag(D) (nv x 1)
mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1) mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1)
// computed by mj_fwdPosition/mj_collision // computed by mj_fwdPosition/mj_collision
mjContact* contact; // list of all detected contacts (nconmax x 1) mjContact* contact; // list of all detected contacts (nconmax x 1)
// computed by mj_fwdPosition/mj_makeConstraint // computed by mj_fwdPosition/mj_makeConstraint
int* efc_type; // constraint type (mjtConstraint) (njmax x 1) int* efc_type; // constraint type (mjtConstraint) (njmax x 1)
int* efc_id; // id of object of specified type (njmax x 1) int* efc_id; // id of object of specified type (njmax x 1)
int* efc_J_rownnz; // number of non-zeros in Jacobian row (njmax x 1) int* efc_J_rownnz; // number of non-zeros in Jacobian row (njmax x 1)
int* efc_J_rowadr; // row start address in colind array (njmax x 1) int* efc_J_rowadr; // row start address in colind array (njmax x 1)
int* efc_J_rowsuper; // number of subsequent rows in supernode (njmax x 1) int* efc_J_rowsuper; // number of subsequent rows in supernode (njmax x 1)
int* efc_J_colind; // column indices in Jacobian (njmax x nv) int* efc_J_colind; // column indices in Jacobian (njmax x nv)
int* efc_JT_rownnz; // number of non-zeros in Jacobian row T (nv x 1) int* efc_JT_rownnz; // number of non-zeros in Jacobian row T (nv x 1)
int* efc_JT_rowadr; // row start address in colind array T (nv x 1) int* efc_JT_rowadr; // row start address in colind array T (nv x 1)
int* efc_JT_rowsuper; // number of subsequent rows in supernode T (nv x 1) int* efc_JT_rowsuper; // number of subsequent rows in supernode T (nv x 1)
int* efc_JT_colind; // column indices in Jacobian T (nv x njmax) int* efc_JT_colind; // column indices in Jacobian T (nv x njmax)
mjtNum* efc_J; // constraint Jacobian (njmax x nv) mjtNum* efc_J; // constraint Jacobian (njmax x nv)
mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax) mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax)
mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1) mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1)
mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1) mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1)
mjtNum* efc_frictionloss; // frictionloss (friction) (njmax x 1) mjtNum* efc_frictionloss; // frictionloss (friction) (njmax x 1)
mjtNum* efc_diagApprox; // approximation to diagonal of A (njmax x 1) mjtNum* efc_diagApprox; // approximation to diagonal of A (njmax x 1)
mjtNum* efc_KBIP; // stiffness, damping, impedance, imp' (njmax x 4) mjtNum* efc_KBIP; // stiffness, damping, impedance, imp' (njmax x 4)
mjtNum* efc_D; // constraint mass (njmax x 1) mjtNum* efc_D; // constraint mass (njmax x 1)
mjtNum* efc_R; // inverse constraint mass (njmax x 1) mjtNum* efc_R; // inverse constraint mass (njmax x 1)
// computed by mj_fwdPosition/mj_projectConstraint // computed by mj_fwdPosition/mj_projectConstraint
int* efc_AR_rownnz; // number of non-zeros in AR (njmax x 1) int* efc_AR_rownnz; // number of non-zeros in AR (njmax x 1)
int* efc_AR_rowadr; // row start address in colind array (njmax x 1) int* efc_AR_rowadr; // row start address in colind array (njmax x 1)
int* efc_AR_colind; // column indices in sparse AR (njmax x njmax) int* efc_AR_colind; // column indices in sparse AR (njmax x njmax)
mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax) mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax)
//-------------------------------- POSITION, VELOCITY dependent //-------------------------------- POSITION, VELOCITY dependent
// computed by mj_fwdVelocity // computed by mj_fwdVelocity
mjtNum* ten_velocity; // tendon velocities (ntendon x 1) mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
mjtNum* actuator_velocity; // actuator velocities (nu x 1) mjtNum* actuator_velocity; // actuator velocities (nu x 1)
// computed by mj_fwdVelocity/mj_comVel // computed by mj_fwdVelocity/mj_comVel
mjtNum* cvel; // com-based velocity [3D rot; 3D tran] (nbody x 6) mjtNum* cvel; // com-based velocity [3D rot; 3D tran] (nbody x 6)
mjtNum* cdof_dot; // time-derivative of cdof (nv x 6) mjtNum* cdof_dot; // time-derivative of cdof (nv x 6)
// computed by mj_fwdVelocity/mj_rne (without acceleration) // computed by mj_fwdVelocity/mj_rne (without acceleration)
mjtNum* qfrc_bias; // C(qpos,qvel) (nv x 1) mjtNum* qfrc_bias; // C(qpos,qvel) (nv x 1)
// computed by mj_fwdVelocity/mj_passive // computed by mj_fwdVelocity/mj_passive
mjtNum* qfrc_passive; // passive force (nv x 1) mjtNum* qfrc_passive; // passive force (nv x 1)
// computed by mj_fwdVelocity/mj_referenceConstraint // computed by mj_fwdVelocity/mj_referenceConstraint
mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1) mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1)
mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1) mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1)
// computed by mj_sensorVel/mj_subtreeVel if needed // computed by mj_sensorVel/mj_subtreeVel if needed
mjtNum* subtree_linvel; // linear velocity of subtree com (nbody x 3) mjtNum* subtree_linvel; // linear velocity of subtree com (nbody x 3)
mjtNum* subtree_angmom; // angular momentum about subtree com (nbody x 3) mjtNum* subtree_angmom; // angular momentum about subtree com (nbody x 3)
//-------------------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent //-------------------------------- POSITION, VELOCITY, CONTROL/ACCELERATION dependent
// computed by mj_fwdActuation // computed by mj_fwdActuation
mjtNum* actuator_force; // actuator force in actuation space (nu x 1) mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
mjtNum* qfrc_actuator; // actuator force (nv x 1) mjtNum* qfrc_actuator; // actuator force (nv x 1)
// computed by mj_fwdAcceleration // computed by mj_fwdAcceleration
mjtNum* qfrc_unc; // net unconstrained force (nv x 1) mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1) mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
// computed by mj_fwdConstraint/mj_inverse // computed by mj_fwdConstraint/mj_inverse
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1) mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
mjtNum* efc_force; // constraint force in constraint space (njmax x 1) mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1) int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
mjtNum* qfrc_constraint; // constraint force (nv x 1) mjtNum* qfrc_constraint; // constraint force (nv x 1)
// computed by mj_inverse // computed by mj_inverse
mjtNum* qfrc_inverse; // net external force; should equal: (nv x 1) mjtNum* qfrc_inverse; // net external force; should equal: (nv x 1)
// qfrc_applied + J'*xfrc_applied + qfrc_actuator // qfrc_applied + J'*xfrc_applied + qfrc_actuator
// computed by mj_sensorAcc/mj_rnePostConstraint if needed; rotation:translation format // computed by mj_sensorAcc/mj_rnePostConstraint if needed; rotation:translation format
mjtNum* cacc; // com-based acceleration (nbody x 6) mjtNum* cacc; // com-based acceleration (nbody x 6)
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
+733 -770
View File
File diff suppressed because it is too large Load Diff
Executable → Regular
+103 -103
View File
@@ -15,137 +15,137 @@
#ifndef MUJOCO_MJRENDER_H_ #ifndef MUJOCO_MJRENDER_H_
#define MUJOCO_MJRENDER_H_ #define MUJOCO_MJRENDER_H_
#define mjNAUX 10 // number of auxiliary buffers #include "mjmodel.h"
#define mjMAXTEXTURE 1000 // maximum number of textures
#define mjNAUX 10 // number of auxiliary buffers
#define mjMAXTEXTURE 1000 // maximum number of textures
typedef enum _mjtGridPos // grid position for overlay //---------------------------------- primitive types (mjt) -----------------------------------------
{
mjGRID_TOPLEFT = 0, // top left typedef enum mjtGridPos_ { // grid position for overlay
mjGRID_TOPRIGHT, // top right mjGRID_TOPLEFT = 0, // top left
mjGRID_BOTTOMLEFT, // bottom left mjGRID_TOPRIGHT, // top right
mjGRID_BOTTOMRIGHT // bottom right mjGRID_BOTTOMLEFT, // bottom left
mjGRID_BOTTOMRIGHT // bottom right
} 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 mjFONTSCALE_200 = 200, // 200% scale
mjFONTSCALE_200 = 200, // 200% scale mjFONTSCALE_250 = 250, // 250% scale
mjFONTSCALE_250 = 250, // 250% scale mjFONTSCALE_300 = 300 // 300% scale
mjFONTSCALE_300 = 300 // 300% scale
} 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 ----------------------------------------------------
{
// parameters copied from mjVisual
float lineWidth; // line width for wireframe rendering
float shadowClip; // clipping radius for directional lights
float shadowScale; // fraction of light cutoff for spot lights
float fogStart; // fog start = stat.extent * vis.map.fogstart
float fogEnd; // fog end = stat.extent * vis.map.fogend
float fogRGBA[4]; // fog rgba
int shadowSize; // size of shadow map texture
int offWidth; // width of offscreen buffer
int offHeight; // height of offscreen buffer
int offSamples; // number of offscreen buffer multisamples
// parameters specified at creation struct mjrContext_ { // custom OpenGL context
int fontScale; // font scale // parameters copied from mjVisual
int auxWidth[mjNAUX]; // auxiliary buffer width float lineWidth; // line width for wireframe rendering
int auxHeight[mjNAUX]; // auxiliary buffer height float shadowClip; // clipping radius for directional lights
int auxSamples[mjNAUX]; // auxiliary buffer multisamples float shadowScale; // fraction of light cutoff for spot lights
float fogStart; // fog start = stat.extent * vis.map.fogstart
float fogEnd; // fog end = stat.extent * vis.map.fogend
float fogRGBA[4]; // fog rgba
int shadowSize; // size of shadow map texture
int offWidth; // width of offscreen buffer
int offHeight; // height of offscreen buffer
int offSamples; // number of offscreen buffer multisamples
// offscreen rendering objects // parameters specified at creation
unsigned int offFBO; // offscreen framebuffer object int fontScale; // font scale
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples int auxWidth[mjNAUX]; // auxiliary buffer width
unsigned int offColor; // offscreen color buffer int auxHeight[mjNAUX]; // auxiliary buffer height
unsigned int offColor_r; // offscreen color buffer for resolving multisamples int auxSamples[mjNAUX]; // auxiliary buffer multisamples
unsigned int offDepthStencil; // offscreen depth and stencil buffer
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for resolving multisamples
// shadow rendering objects // offscreen rendering objects
unsigned int shadowFBO; // shadow map framebuffer object unsigned int offFBO; // offscreen framebuffer object
unsigned int shadowTex; // shadow map texture unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
unsigned int offColor; // offscreen color buffer
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
unsigned int offDepthStencil; // offscreen depth and stencil buffer
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for resolving multisamples
// auxiliary buffers // shadow rendering objects
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object unsigned int shadowFBO; // shadow map framebuffer object
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving unsigned int shadowTex; // shadow map texture
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
// texture objects and info // auxiliary buffers
int ntexture; // number of allocated textures unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
int textureType[100]; // type of texture (mjtTexture) unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
unsigned int texture[100]; // texture names unsigned int auxColor[mjNAUX]; // auxiliary color buffer
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
// displaylist starting positions // texture objects and info
unsigned int basePlane; // all planes from model int ntexture; // number of allocated textures
unsigned int baseMesh; // all meshes from model int textureType[100]; // type of texture (mjtTexture)
unsigned int baseHField; // all hfields from model unsigned int texture[100]; // texture names
unsigned int baseBuiltin; // all buildin geoms, with quality from model
unsigned int baseFontNormal; // normal font
unsigned int baseFontShadow; // shadow font
unsigned int baseFontBig; // big font
// displaylist ranges // displaylist starting positions
int rangePlane; // all planes from model unsigned int basePlane; // all planes from model
int rangeMesh; // all meshes from model unsigned int baseMesh; // all meshes from model
int rangeHField; // all hfields from model unsigned int baseHField; // all hfields from model
int rangeBuiltin; // all builtin geoms, with quality from model unsigned int baseBuiltin; // all buildin geoms, with quality from model
int rangeFont; // all characters in font unsigned int baseFontNormal; // normal font
unsigned int baseFontShadow; // shadow font
unsigned int baseFontBig; // big font
// skin VBOs // displaylist ranges
int nskin; // number of skins int rangePlane; // all planes from model
unsigned int* skinvertVBO; // skin vertex position VBOs int rangeMesh; // all meshes from model
unsigned int* skinnormalVBO; // skin vertex normal VBOs int rangeHField; // all hfields from model
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs int rangeBuiltin; // all builtin geoms, with quality from model
unsigned int* skinfaceVBO; // skin face index VBOs int rangeFont; // all characters in font
// character info // skin VBOs
int charWidth[127]; // character widths: normal and shadow int nskin; // number of skins
int charWidthBig[127]; // chacarter widths: big unsigned int* skinvertVBO; // skin vertex position VBOs
int charHeight; // character heights: normal and shadow unsigned int* skinnormalVBO; // skin vertex normal VBOs
int charHeightBig; // character heights: big unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs
unsigned int* skinfaceVBO; // skin face index VBOs
// capabilities // character info
int glewInitialized; // is glew initialized int charWidth[127]; // character widths: normal and shadow
int windowAvailable; // is default/window framebuffer available int charWidthBig[127]; // chacarter widths: big
int windowSamples; // number of samples for default/window framebuffer int charHeight; // character heights: normal and shadow
int windowStereo; // is stereo available for default/window framebuffer int charHeightBig; // character heights: big
int windowDoublebuffer; // is default/window framebuffer double buffered
// framebuffer // capabilities
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN int glewInitialized; // is glew initialized
int windowAvailable; // is default/window framebuffer available
int windowSamples; // number of samples for default/window framebuffer
int windowStereo; // is stereo available for default/window framebuffer
int windowDoublebuffer; // is default/window framebuffer double buffered
// framebuffer
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
+195 -192
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,48 +57,47 @@
#define mjKEY_F12 301 #define mjKEY_F12 301
typedef enum _mjtButton // mouse button //---------------------------------- primitive types (mjt) -----------------------------------------
{
mjBUTTON_NONE = 0, // no button typedef enum mjtButton_ { // mouse button
mjBUTTON_LEFT, // left button mjBUTTON_NONE = 0, // no button
mjBUTTON_RIGHT, // right button mjBUTTON_LEFT, // left button
mjBUTTON_MIDDLE // middle button mjBUTTON_RIGHT, // right button
mjBUTTON_MIDDLE // middle 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 mjEVENT_RELEASE, // mouse button release
mjEVENT_RELEASE, // mouse button release mjEVENT_SCROLL, // scroll
mjEVENT_SCROLL, // scroll mjEVENT_KEY, // key press
mjEVENT_KEY, // key press mjEVENT_RESIZE // resize
mjEVENT_RESIZE // resize
} 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 mjITEM_STATIC, // static text
mjITEM_STATIC, // static text mjITEM_BUTTON, // button
mjITEM_BUTTON, // button
// the rest have data pointer // the rest have data pointer
mjITEM_CHECKINT, // check box, int value mjITEM_CHECKINT, // check box, int value
mjITEM_CHECKBYTE, // check box, mjtByte value mjITEM_CHECKBYTE, // check box, mjtByte value
mjITEM_RADIO, // radio group mjITEM_RADIO, // radio group
mjITEM_RADIOLINE, // radio group, single line mjITEM_RADIOLINE, // radio group, single line
mjITEM_SELECT, // selection box mjITEM_SELECT, // selection box
mjITEM_SLIDERINT, // slider, int value mjITEM_SLIDERINT, // slider, int value
mjITEM_SLIDERNUM, // slider, mjtNum value mjITEM_SLIDERNUM, // slider, mjtNum value
mjITEM_EDITINT, // editable array, int values mjITEM_EDITINT, // editable array, int values
mjITEM_EDITNUM, // editable array, mjtNum values mjITEM_EDITNUM, // editable array, mjtNum values
mjITEM_EDITTXT, // editable text mjITEM_EDITTXT, // editable text
mjNITEM // number of item types mjNITEM // number of item types
} mjtItem; } mjtItem;
@@ -104,206 +105,208 @@ 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 -----------------------------------------------------
{
// constants set by user
int nrect; // number of rectangles used
mjrRect rect[mjMAXUIRECT]; // rectangles (index 0: entire window)
void* userdata; // pointer to user data (for callbacks)
// event type struct mjuiState_ { // mouse and keyboard state
int type; // (type mjtEvent) // constants set by user
int nrect; // number of rectangles used
mjrRect rect[mjMAXUIRECT]; // rectangles (index 0: entire window)
void* userdata; // pointer to user data (for callbacks)
// mouse buttons // event type
int left; // is left button down int type; // (type mjtEvent)
int right; // is right button down
int middle; // is middle button down
int doubleclick; // is last press a double click
int button; // which button was pressed (mjtButton)
double buttontime; // time of last button press
// mouse position // mouse buttons
double x; // x position int left; // is left button down
double y; // y position int right; // is right button down
double dx; // x displacement int middle; // is middle button down
double dy; // y displacement int doubleclick; // is last press a double click
double sx; // x scroll int button; // which button was pressed (mjtButton)
double sy; // y scroll double buttontime; // time of last button press
// keyboard // mouse position
int control; // is control down double x; // x position
int shift; // is shift down double y; // y position
int alt; // is alt down double dx; // x displacement
int key; // which key was pressed double dy; // y displacement
double keytime; // time of last key press double sx; // x scroll
double sy; // y scroll
// rectangle ownership and dragging // keyboard
int mouserect; // which rectangle contains mouse int control; // is control down
int dragrect; // which rectangle is dragged with mouse int shift; // is shift down
int dragbutton; // which button started drag (mjtButton) int alt; // is alt down
int key; // which key was pressed
double keytime; // time of last key press
// rectangle ownership and dragging
int mouserect; // which rectangle contains mouse
int dragrect; // which rectangle is dragged with mouse
int dragbutton; // which button started drag (mjtButton)
}; };
typedef struct _mjuiState mjuiState; typedef struct mjuiState_ mjuiState;
struct _mjuiThemeSpacing // UI visualization theme spacing //---------------------------------- mjuiThemeSpacing ----------------------------------------------
{
int total; // total width struct mjuiThemeSpacing_ { // UI visualization theme spacing
int scroll; // scrollbar width int total; // total width
int label; // label width int scroll; // scrollbar width
int section; // section gap int label; // label width
int itemside; // item side gap int section; // section gap
int itemmid; // item middle gap int itemside; // item side gap
int itemver; // item vertical gap int itemmid; // item middle gap
int texthor; // text horizontal gap int itemver; // item vertical gap
int textver; // text vertical gap int texthor; // text horizontal gap
int linescroll; // number of pixels to scroll int textver; // text vertical gap
int samples; // number of multisamples int linescroll; // number of pixels to scroll
int samples; // number of multisamples
}; };
typedef struct _mjuiThemeSpacing mjuiThemeSpacing; typedef struct mjuiThemeSpacing_ mjuiThemeSpacing;
struct _mjuiThemeColor // UI visualization theme color //---------------------------------- mjuiThemeColor ------------------------------------------------
{
float master[3]; // master background struct mjuiThemeColor_ { // UI visualization theme color
float thumb[3]; // scrollbar thumb float master[3]; // master background
float secttitle[3]; // section title float thumb[3]; // scrollbar thumb
float sectfont[3]; // section font float secttitle[3]; // section title
float sectsymbol[3]; // section symbol float sectfont[3]; // section font
float sectpane[3]; // section pane float sectsymbol[3]; // section symbol
float shortcut[3]; // shortcut background float sectpane[3]; // section pane
float fontactive[3]; // font active float shortcut[3]; // shortcut background
float fontinactive[3]; // font inactive float fontactive[3]; // font active
float decorinactive[3]; // decor inactive float fontinactive[3]; // font inactive
float decorinactive2[3]; // inactive slider color 2 float decorinactive[3]; // decor inactive
float button[3]; // button float decorinactive2[3]; // inactive slider color 2
float check[3]; // check float button[3]; // button
float radio[3]; // radio float check[3]; // check
float select[3]; // select float radio[3]; // radio
float select2[3]; // select pane float select[3]; // select
float slider[3]; // slider float select2[3]; // select pane
float slider2[3]; // slider color 2 float slider[3]; // slider
float edit[3]; // edit float slider2[3]; // slider color 2
float edit2[3]; // edit invalid float edit[3]; // edit
float cursor[3]; // edit cursor float edit2[3]; // edit invalid
float cursor[3]; // edit cursor
}; };
typedef struct _mjuiThemeColor mjuiThemeColor; typedef struct mjuiThemeColor_ mjuiThemeColor;
struct _mjuiItemSingle // check and button-related //---------------------------------- mjuiItem ------------------------------------------------------
{
int modifier; // 0: none, 1: control, 2: shift; 4: alt struct mjuiItemSingle_ { // check and button-related
int shortcut; // shortcut key; 0: undefined int modifier; // 0: none, 1: control, 2: shift; 4: alt
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 int state; // 0: disable, 1: enable, 2+: use predicate
int state; // 0: disable, 1: enable, 2+: use predicate void *pdata; // data pointer (type-specific)
void *pdata; // data pointer (type-specific) int sectionid; // id of section containing item
int sectionid; // id of section containing 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 ---------------------------------------------------
{
// properties
char name[mjMAXUINAME]; // name
int state; // 0: closed, 1: open
int modifier; // 0: none, 1: control, 2: shift; 4: alt
int shortcut; // shortcut key; 0: undefined
int nitem; // number of items in use
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
// internal struct mjuiSection_ { // UI section
mjrRect rtitle; // rectangle occupied by title // properties
mjrRect rcontent; // rectangle occupied by content char name[mjMAXUINAME]; // name
int state; // 0: closed, 1: open
int modifier; // 0: none, 1: control, 2: shift; 4: alt
int shortcut; // shortcut key; 0: undefined
int nitem; // number of items in use
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
// internal
mjrRect rtitle; // rectangle occupied by title
mjrRect rcontent; // rectangle occupied by content
}; };
typedef struct _mjuiSection mjuiSection; typedef struct mjuiSection_ mjuiSection;
struct _mjUI // entire UI //---------------------------------- mjUI ----------------------------------------------------------
{
// constants set by user
mjuiThemeSpacing spacing; // UI theme spacing
mjuiThemeColor color; // UI theme color
mjfItemEnable predicate; // callback to set item state programmatically
void* userdata; // pointer to user data (passed to predicate)
int rectid; // index of this ui rectangle in mjuiState
int auxid; // aux buffer index of this ui
int radiocol; // number of radio columns (0 defaults to 2)
// UI sizes (framebuffer units) struct mjUI_ { // entire UI
int width; // width // constants set by user
int height; // current heigth mjuiThemeSpacing spacing; // UI theme spacing
int maxheight; // height when all sections open mjuiThemeColor color; // UI theme color
int scroll; // scroll from top of UI mjfItemEnable predicate; // callback to set item state programmatically
void* userdata; // pointer to user data (passed to predicate)
int rectid; // index of this ui rectangle in mjuiState
int auxid; // aux buffer index of this ui
int radiocol; // number of radio columns (0 defaults to 2)
// mouse focus // UI sizes (framebuffer units)
int mousesect; // 0: none, -1: scroll, otherwise 1+section int width; // width
int mouseitem; // item within section int height; // current heigth
int mousehelp; // help button down: print shortcuts int maxheight; // height when all sections open
int scroll; // scroll from top of UI
// keyboard focus and edit // mouse focus
int editsect; // 0: none, otherwise 1+section int mousesect; // 0: none, -1: scroll, otherwise 1+section
int edititem; // item within section int mouseitem; // item within section
int editcursor; // cursor position int mousehelp; // help button down: print shortcuts
int editscroll; // horizontal scroll
char edittext[mjMAXUITEXT]; // current text
mjuiItem* editchanged; // pointer to changed edit in last mjui_event
// sections // keyboard focus and edit
int nsect; // number of sections in use int editsect; // 0: none, otherwise 1+section
mjuiSection sect[mjMAXUISECT]; // preallocated array of sections int edititem; // item within section
int editcursor; // cursor position
int editscroll; // horizontal scroll
char edittext[mjMAXUITEXT]; // current text
mjuiItem* editchanged; // pointer to changed edit in last mjui_event
// sections
int nsect; // number of sections in use
mjuiSection sect[mjMAXUISECT]; // preallocated array of sections
}; };
typedef struct _mjUI mjUI; typedef struct mjUI_ mjUI;
struct _mjuiDef // table passed to mjui_add() //---------------------------------- mjuiDef -------------------------------------------------------
{
int type; // type (mjtItem); -1: section struct mjuiDef_ { // table passed to mjui_add()
char name[mjMAXUINAME]; // name int type; // type (mjtItem); -1: section
int state; // state char name[mjMAXUINAME]; // name
void* pdata; // pointer to data int state; // state
char other[mjMAXUITEXT]; // string with type-specific properties void* pdata; // pointer to data
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
+264 -261
View File
@@ -15,336 +15,339 @@
#ifndef MUJOCO_MJVISUALIZE_H_ #ifndef MUJOCO_MJVISUALIZE_H_
#define MUJOCO_MJVISUALIZE_H_ #define MUJOCO_MJVISUALIZE_H_
#define mjNGROUP 6 // number of geom, site, joint groups with visflags #include "mjmodel.h"
#define mjMAXOVERLAY 500 // maximum number of characters in overlay text
#define mjMAXLINE 100 // maximum number of lines per plot #define mjNGROUP 6 // number of geom, site, joint groups with visflags
#define mjMAXLINEPNT 1000 // maximum number points per line #define mjMAXOVERLAY 500 // maximum number of characters in overlay text
#define mjMAXPLANEGRID 200 // maximum number of grid divisions for plane #define mjMAXLINE 100 // maximum number of lines per plot
#define mjMAXLINEPNT 1000 // maximum number points per line
#define mjMAXPLANEGRID 200 // maximum number of grid divisions for plane
typedef enum _mjtCatBit // bitflags for mjvGeom category //---------------------------------- primitive types (mjt) -----------------------------------------
{
mjCAT_STATIC = 1, // model elements in body 0 typedef enum mjtCatBit_ { // bitflags for mjvGeom category
mjCAT_DYNAMIC = 2, // model elements in all other bodies mjCAT_STATIC = 1, // model elements in body 0
mjCAT_DECOR = 4, // decorative geoms mjCAT_DYNAMIC = 2, // model elements in all other bodies
mjCAT_ALL = 7 // select all categories mjCAT_DECOR = 4, // decorative geoms
mjCAT_ALL = 7 // select all categories
} 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 mjMOUSE_MOVE_V, // move, vertical plane
mjMOUSE_MOVE_V, // move, vertical plane mjMOUSE_MOVE_H, // move, horizontal plane
mjMOUSE_MOVE_H, // move, horizontal plane mjMOUSE_ZOOM, // zoom
mjMOUSE_ZOOM, // zoom mjMOUSE_SELECT // selection
mjMOUSE_SELECT // selection
} 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 mjCAMERA_USER // user is responsible for setting OpenGL camera
mjCAMERA_USER // user is responsible for setting OpenGL camera
} 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 mjLABEL_GEOM, // geom labels
mjLABEL_GEOM, // geom labels mjLABEL_SITE, // site labels
mjLABEL_SITE, // site labels mjLABEL_CAMERA, // camera labels
mjLABEL_CAMERA, // camera labels mjLABEL_LIGHT, // light labels
mjLABEL_LIGHT, // light labels mjLABEL_TENDON, // tendon labels
mjLABEL_TENDON, // tendon labels mjLABEL_ACTUATOR, // actuator labels
mjLABEL_ACTUATOR, // actuator labels mjLABEL_CONSTRAINT, // constraint labels
mjLABEL_CONSTRAINT, // constraint labels mjLABEL_SKIN, // skin labels
mjLABEL_SKIN, // skin labels mjLABEL_SELECTION, // selected object
mjLABEL_SELECTION, // selected object mjLABEL_SELPNT, // coordinates of selection point
mjLABEL_SELPNT, // coordinates of selection point mjLABEL_CONTACTFORCE, // magnitude of contact force
mjLABEL_CONTACTFORCE, // magnitude of contact force
mjNLABEL // number of label types mjNLABEL // number of label types
} 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 mjFRAME_SITE, // site frames
mjFRAME_SITE, // site frames mjFRAME_CAMERA, // camera frames
mjFRAME_CAMERA, // camera frames mjFRAME_LIGHT, // light frames
mjFRAME_LIGHT, // light frames mjFRAME_WORLD, // world frame
mjFRAME_WORLD, // world frame
mjNFRAME // number of visualization frames mjNFRAME // number of visualization frames
} 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 mjVIS_ACTUATOR, // actuators
mjVIS_ACTUATOR, // actuators mjVIS_CAMERA, // cameras
mjVIS_CAMERA, // cameras mjVIS_LIGHT, // lights
mjVIS_LIGHT, // lights mjVIS_TENDON, // tendons
mjVIS_TENDON, // tendons mjVIS_RANGEFINDER, // rangefinder sensors
mjVIS_RANGEFINDER, // rangefinder sensors mjVIS_CONSTRAINT, // point constraints
mjVIS_CONSTRAINT, // point constraints mjVIS_INERTIA, // equivalent inertia boxes
mjVIS_INERTIA, // equivalent inertia boxes mjVIS_SCLINERTIA, // scale equivalent inertia boxes with mass
mjVIS_SCLINERTIA, // scale equivalent inertia boxes with mass mjVIS_PERTFORCE, // perturbation force
mjVIS_PERTFORCE, // perturbation force mjVIS_PERTOBJ, // perturbation object
mjVIS_PERTOBJ, // perturbation object mjVIS_CONTACTPOINT, // contact points
mjVIS_CONTACTPOINT, // contact points mjVIS_CONTACTFORCE, // contact force
mjVIS_CONTACTFORCE, // contact force mjVIS_CONTACTSPLIT, // split contact force into normal and tanget
mjVIS_CONTACTSPLIT, // split contact force into normal and tanget mjVIS_TRANSPARENT, // make dynamic geoms more transparent
mjVIS_TRANSPARENT, // make dynamic geoms more transparent mjVIS_AUTOCONNECT, // auto connect joints and body coms
mjVIS_AUTOCONNECT, // auto connect joints and body coms mjVIS_COM, // center of mass
mjVIS_COM, // center of mass mjVIS_SELECT, // selection point
mjVIS_SELECT, // selection point mjVIS_STATIC, // static bodies
mjVIS_STATIC, // static bodies mjVIS_SKIN, // skin
mjVIS_SKIN, // skin
mjNVISFLAG // number of visualization flags mjNVISFLAG // number of visualization flags
} 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 mjRND_ADDITIVE, // additive transparency
mjRND_ADDITIVE, // additive transparency mjRND_SKYBOX, // skybox
mjRND_SKYBOX, // skybox mjRND_FOG, // fog
mjRND_FOG, // fog mjRND_HAZE, // haze
mjRND_HAZE, // haze mjRND_SEGMENT, // segmentation with random color
mjRND_SEGMENT, // segmentation with random color mjRND_IDCOLOR, // segmentation with segid color
mjRND_IDCOLOR, // segmentation with segid color
mjNRNDFLAG // number of rendering flags mjNRNDFLAG // number of rendering flags
} 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 ----------------------------------------------------
{
int select; // selected body id; non-positive: none struct mjvPerturb_ { // object selection and perturbation
int skinselect; // selected skin id; negative: none int select; // selected body id; non-positive: none
int active; // perturbation bitmask (mjtPertBit) int skinselect; // selected skin id; negative: none
int active2; // secondary perturbation bitmask (mjtPertBit) int active; // perturbation bitmask (mjtPertBit)
mjtNum refpos[3]; // desired position for selected object int active2; // secondary perturbation bitmask (mjtPertBit)
mjtNum refquat[4]; // desired orientation for selected object mjtNum refpos[3]; // desired position for selected object
mjtNum localpos[3]; // selection point in object coordinates mjtNum refquat[4]; // desired orientation for selected object
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb) mjtNum localpos[3]; // selection point in object coordinates
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
}; };
typedef struct _mjvPerturb mjvPerturb; typedef struct mjvPerturb_ mjvPerturb;
struct _mjvCamera // abstract camera //---------------------------------- mjvCamera -----------------------------------------------------
{
// type and ids
int type; // camera type (mjtCamera)
int fixedcamid; // fixed camera id
int trackbodyid; // body id to track
// abstract camera pose specification struct mjvCamera_ { // abstract camera
mjtNum lookat[3]; // lookat point // type and ids
mjtNum distance; // distance to lookat point or tracked body int type; // camera type (mjtCamera)
mjtNum azimuth; // camera azimuth (deg) int fixedcamid; // fixed camera id
mjtNum elevation; // camera elevation (deg) int trackbodyid; // body id to track
// abstract camera pose specification
mjtNum lookat[3]; // lookat point
mjtNum distance; // distance to lookat point or tracked body
mjtNum azimuth; // camera azimuth (deg)
mjtNum elevation; // camera elevation (deg)
}; };
typedef struct _mjvCamera mjvCamera; typedef struct mjvCamera_ mjvCamera;
struct _mjvGLCamera // OpenGL camera //---------------------------------- mjvGLCamera ---------------------------------------------------
{
// camera frame
float pos[3]; // position
float forward[3]; // forward direction
float up[3]; // up direction
// camera projection struct mjvGLCamera_ { // OpenGL camera
float frustum_center; // hor. center (left,right set to match aspect) // camera frame
float frustum_bottom; // bottom float pos[3]; // position
float frustum_top; // top float forward[3]; // forward direction
float frustum_near; // near float up[3]; // up direction
float frustum_far; // far
// camera projection
float frustum_center; // hor. center (left,right set to match aspect)
float frustum_bottom; // bottom
float frustum_top; // top
float frustum_near; // near
float frustum_far; // far
}; };
typedef struct _mjvGLCamera mjvGLCamera; typedef struct mjvGLCamera_ mjvGLCamera;
struct _mjvGeom // abstract geom //---------------------------------- mjvGeom -------------------------------------------------------
{
// type info
int type; // geom type (mjtGeom)
int dataid; // mesh, hfield or plane id; -1: none
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
int objid; // mujoco object id; -1 for decor
int category; // visual category
int texid; // texture id; -1: no texture
int texuniform; // uniform cube mapping
int texcoord; // mesh geom has texture coordinates
int segid; // segmentation id; -1: not shown
// OpenGL info struct mjvGeom_ { // abstract geom
float texrepeat[2]; // texture repetition for 2D mapping // type info
float size[3]; // size parameters int type; // geom type (mjtGeom)
float pos[3]; // Cartesian position int dataid; // mesh, hfield or plane id; -1: none
float mat[9]; // Cartesian orientation int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
float rgba[4]; // color and transparency int objid; // mujoco object id; -1 for decor
float emission; // emission coef int category; // visual category
float specular; // specular coef int texid; // texture id; -1: no texture
float shininess; // shininess coef int texuniform; // uniform cube mapping
float reflectance; // reflectance coef int texcoord; // mesh geom has texture coordinates
char label[100]; // text label int segid; // segmentation id; -1: not shown
// transparency rendering (set internally) // OpenGL info
float camdist; // distance to camera (used by sorter) float texrepeat[2]; // texture repetition for 2D mapping
float modelrbound; // geom rbound from model, 0 if not model geom float size[3]; // size parameters
mjtByte transparent; // treat geom as transparent float pos[3]; // Cartesian position
float mat[9]; // Cartesian orientation
float rgba[4]; // color and transparency
float emission; // emission coef
float specular; // specular coef
float shininess; // shininess coef
float reflectance; // reflectance coef
char label[100]; // text label
// transparency rendering (set internally)
float camdist; // distance to camera (used by sorter)
float modelrbound; // geom rbound from model, 0 if not model geom
mjtByte transparent; // treat geom as transparent
}; };
typedef struct _mjvGeom mjvGeom; typedef struct mjvGeom_ mjvGeom;
struct _mjvLight // OpenGL light //---------------------------------- mjvLight ------------------------------------------------------
{
float pos[3]; // position rel. to body frame struct mjvLight_ { // OpenGL light
float dir[3]; // direction rel. to body frame float pos[3]; // position rel. to body frame
float attenuation[3]; // OpenGL attenuation (quadratic model) float dir[3]; // direction rel. to body frame
float cutoff; // OpenGL cutoff float attenuation[3]; // OpenGL attenuation (quadratic model)
float exponent; // OpenGL exponent float cutoff; // OpenGL cutoff
float ambient[3]; // ambient rgb (alpha=1) float exponent; // OpenGL exponent
float diffuse[3]; // diffuse rgb (alpha=1) float ambient[3]; // ambient rgb (alpha=1)
float specular[3]; // specular rgb (alpha=1) float diffuse[3]; // diffuse rgb (alpha=1)
mjtByte headlight; // headlight float specular[3]; // specular rgb (alpha=1)
mjtByte directional; // directional light mjtByte headlight; // headlight
mjtByte castshadow; // does light cast shadows mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows
}; };
typedef struct _mjvLight mjvLight; typedef struct mjvLight_ mjvLight;
struct _mjvOption // abstract visualization options //---------------------------------- mjvOption -----------------------------------------------------
{
int label; // what objects to label (mjtLabel) struct mjvOption_ { // abstract visualization options
int frame; // which frame to show (mjtFrame) int label; // what objects to label (mjtLabel)
mjtByte geomgroup[mjNGROUP]; // geom visualization by group int frame; // which frame to show (mjtFrame)
mjtByte sitegroup[mjNGROUP]; // site visualization by group mjtByte geomgroup[mjNGROUP]; // geom visualization by group
mjtByte jointgroup[mjNGROUP]; // joint visualization by group mjtByte sitegroup[mjNGROUP]; // site visualization by group
mjtByte tendongroup[mjNGROUP]; // tendon visualization by group mjtByte jointgroup[mjNGROUP]; // joint visualization by group
mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group mjtByte tendongroup[mjNGROUP]; // tendon visualization by group
mjtByte flags[mjNVISFLAG]; // visualization flags (indexed by mjtVisFlag) mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group
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 ------------------------------------------------------
{
// abstract geoms
int maxgeom; // size of allocated geom buffer
int ngeom; // number of geoms currently in buffer
mjvGeom* geoms; // buffer for geoms
int* geomorder; // buffer for ordering geoms by distance to camera
// skin data struct mjvScene_ { // abstract scene passed to OpenGL renderer
int nskin; // number of skins // abstract geoms
int* skinfacenum; // number of faces in skin int maxgeom; // size of allocated geom buffer
int* skinvertadr; // address of skin vertices int ngeom; // number of geoms currently in buffer
int* skinvertnum; // number of vertices in skin mjvGeom* geoms; // buffer for geoms
float* skinvert; // skin vertex data int* geomorder; // buffer for ordering geoms by distance to camera
float* skinnormal; // skin normal data
// OpenGL lights // skin data
int nlight; // number of lights currently in buffer int nskin; // number of skins
mjvLight lights[8]; // buffer for lights int* skinfacenum; // number of faces in skin
int* skinvertadr; // address of skin vertices
int* skinvertnum; // number of vertices in skin
float* skinvert; // skin vertex data
float* skinnormal; // skin normal data
// OpenGL cameras // OpenGL lights
mjvGLCamera camera[2]; // left and right camera int nlight; // number of lights currently in buffer
mjvLight lights[8]; // buffer for lights
// OpenGL model transformation // OpenGL cameras
mjtByte enabletransform; // enable model transformation mjvGLCamera camera[2]; // left and right camera
float translate[3]; // model translation
float rotate[4]; // model quaternion rotation
float scale; // model scaling
// OpenGL rendering effects // OpenGL model transformation
int stereo; // stereoscopic rendering (mjtStereo) mjtByte enabletransform; // enable model transformation
mjtByte flags[mjNRNDFLAG]; // rendering flags (indexed by mjtRndFlag) float translate[3]; // model translation
float rotate[4]; // model quaternion rotation
float scale; // model scaling
// framing // OpenGL rendering effects
int framewidth; // frame pixel width; 0: disable framing int stereo; // stereoscopic rendering (mjtStereo)
float framergb[3]; // frame color mjtByte flags[mjNRNDFLAG]; // rendering flags (indexed by mjtRndFlag)
// framing
int framewidth; // frame pixel width; 0: disable framing
float framergb[3]; // frame color
}; };
typedef struct _mjvScene mjvScene; typedef struct mjvScene_ mjvScene;
struct _mjvFigure // abstract 2D figure passed to OpenGL renderer //---------------------------------- mjvFigure -----------------------------------------------------
{
// enable flags
int flg_legend; // show legend
int flg_ticklabel[2]; // show grid tick labels (x,y)
int flg_extend; // automatically extend axis ranges to fit data
int flg_barplot; // isolated line segments (i.e. GL_LINES)
int flg_selection; // vertical selection line
int flg_symmetric; // symmetric y-axis
// style settings struct mjvFigure_ { // abstract 2D figure passed to OpenGL renderer
float linewidth; // line width // enable flags
float gridwidth; // grid line width int flg_legend; // show legend
int gridsize[2]; // number of grid points in (x,y) int flg_ticklabel[2]; // show grid tick labels (x,y)
float gridrgb[3]; // grid line rgb int flg_extend; // automatically extend axis ranges to fit data
float figurergba[4]; // figure color and alpha int flg_barplot; // isolated line segments (i.e. GL_LINES)
float panergba[4]; // pane color and alpha int flg_selection; // vertical selection line
float legendrgba[4]; // legend color and alpha int flg_symmetric; // symmetric y-axis
float textrgb[3]; // text color
float linergb[mjMAXLINE][3]; // line colors
float range[2][2]; // axis ranges; (min>=max) automatic
char xformat[20]; // x-tick label format for sprintf
char yformat[20]; // y-tick label format for sprintf
char minwidth[20]; // string used to determine min y-tick width
// text labels // style settings
char title[1000]; // figure title; subplots separated with 2+ spaces float linewidth; // line width
char xlabel[100]; // x-axis label float gridwidth; // grid line width
char linename[mjMAXLINE][100]; // line names for legend int gridsize[2]; // number of grid points in (x,y)
float gridrgb[3]; // grid line rgb
float figurergba[4]; // figure color and alpha
float panergba[4]; // pane color and alpha
float legendrgba[4]; // legend color and alpha
float textrgb[3]; // text color
float linergb[mjMAXLINE][3]; // line colors
float range[2][2]; // axis ranges; (min>=max) automatic
char xformat[20]; // x-tick label format for sprintf
char yformat[20]; // y-tick label format for sprintf
char minwidth[20]; // string used to determine min y-tick width
// dynamic settings // text labels
int legendoffset; // number of lines to offset legend char title[1000]; // figure title; subplots separated with 2+ spaces
int subplot; // selected subplot (for title rendering) char xlabel[100]; // x-axis label
int highlight[2]; // if point is in legend rect, highlight line char linename[mjMAXLINE][100]; // line names for legend
int highlightid; // if id>=0 and no point, highlight id
float selection; // selection line x-value
// line data // dynamic settings
int linepnt[mjMAXLINE]; // number of points in line; (0) disable int legendoffset; // number of lines to offset legend
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y) int subplot; // selected subplot (for title rendering)
int highlight[2]; // if point is in legend rect, highlight line
int highlightid; // if id>=0 and no point, highlight id
float selection; // selection line x-value
// output from renderer // line data
int xaxispixel[2]; // range of x-axis in pixels int linepnt[mjMAXLINE]; // number of points in line; (0) disable
int yaxispixel[2]; // range of y-axis in pixels float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
float xaxisdata[2]; // range of x-axis in data units
float yaxisdata[2]; // range of y-axis in data units // output from renderer
int xaxispixel[2]; // range of x-axis in pixels
int yaxispixel[2]; // range of y-axis in pixels
float xaxisdata[2]; // range of x-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
+62 -65
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);
@@ -680,7 +677,7 @@ MJAPI void mjr_rectangle(mjrRect viewport, float r, float g, float b, float a);
// Draw rectangle with centered text. // Draw rectangle with centered text.
MJAPI void mjr_label(mjrRect viewport, int font, const char* txt, MJAPI void mjr_label(mjrRect viewport, int font, const char* txt,
float r, float g, float b, float a, float rt, float gt, float bt, float r, float g, float b, float a, float rt, float gt, float bt,
const mjrContext* con); const mjrContext* con);
// Draw 2D figure. // Draw 2D figure.
MJAPI void mjr_figure(mjrRect viewport, mjvFigure* fig, const mjrContext* con); MJAPI void mjr_figure(mjrRect viewport, mjvFigure* fig, const 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,48 +759,48 @@ 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))
#ifdef mjUSEDOUBLE #ifdef mjUSEDOUBLE
#define mju_sqrt sqrt #define mju_sqrt sqrt
#define mju_exp exp #define mju_exp exp
#define mju_sin sin #define mju_sin sin
#define mju_cos cos #define mju_cos cos
#define mju_tan tan #define mju_tan tan
#define mju_asin asin #define mju_asin asin
#define mju_acos acos #define mju_acos acos
#define mju_atan2 atan2 #define mju_atan2 atan2
#define mju_tanh tanh #define mju_tanh tanh
#define mju_pow pow #define mju_pow pow
#define mju_abs fabs #define mju_abs fabs
#define mju_log log #define mju_log log
#define mju_log10 log10 #define mju_log10 log10
#define mju_floor floor #define mju_floor floor
#define mju_ceil ceil #define mju_ceil ceil
#else #else
#define mju_sqrt sqrtf #define mju_sqrt sqrtf
#define mju_exp expf #define mju_exp expf
#define mju_sin sinf #define mju_sin sinf
#define mju_cos cosf #define mju_cos cosf
#define mju_tan tanf #define mju_tan tanf
#define mju_asin asinf #define mju_asin asinf
#define mju_acos acosf #define mju_acos acosf
#define mju_atan2 atan2f #define mju_atan2 atan2f
#define mju_tanh tanhf #define mju_tanh tanhf
#define mju_pow powf #define mju_pow powf
#define mju_abs fabsf #define mju_abs fabsf
#define mju_log logf #define mju_log logf
#define mju_log10 log10f #define mju_log10 log10f
#define mju_floor floorf #define mju_floor floorf
#define mju_ceil ceilf #define mju_ceil ceilf
#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_
+13 -14
View File
@@ -14,23 +14,22 @@
--> -->
<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"/> <size nconmax="300" njmax="1000" nstack="1000000"/>
<size nconmax="300" njmax="1000" nstack="1000000"/> <worldbody>
<worldbody> <body name="B3_5" pos="0 0 1">
<freejoint/>
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
<joint kind="main" damping="0.001"/>
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
</composite>
</body>
<body name="B3_5" pos="0 0 1"> </worldbody>
<freejoint/>
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
<joint kind="main" damping="0.001"/>
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
</composite>
</body>
</worldbody>
</mujoco> </mujoco>
-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>
+10 -11
View File
@@ -14,17 +14,16 @@
--> -->
<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"/> <worldbody>
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
<worldbody> <skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/>
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1"> <pin coord="0 0"/>
<skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/> <pin coord="8 0"/>
<pin coord="0 0"/> <geom size=".02"/>
<pin coord="8 0"/> </composite>
<geom size=".02"/> </worldbody>
</composite>
</worldbody>
</mujoco> </mujoco>
+12 -13
View File
@@ -14,20 +14,19 @@
--> -->
<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"/> <size nconmax="100" njmax="300" nstack="50000"/>
<size nconmax="100" njmax="300" nstack="50000"/> <worldbody>
<body name="B0" pos="0 0 1">
<worldbody> <freejoint/>
<body name="B0" pos="0 0 1"> <composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2">
<freejoint/> <joint kind="main" damping="0.005"/>
<composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2"> <geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
<joint kind="main" damping="0.005"/> </composite>
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/> </body>
</composite> </worldbody>
</body>
</worldbody>
</mujoco> </mujoco>
+23 -11
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" timestep=".01"/>
<option solver="CG" tolerance="1e-6"/> <size nconmax="6000" njmax="6000" nstack="50000000"/>
<size nconmax="3000" njmax="3000" nstack="50000000"/> <visual>
<map stiffness="100"/>
</visual>
<visual> <default>
<map stiffness="100"/> <default class="wall">
</visual> <geom type="plane" size=".5 .5 .05"/>
</default>
</default>
<worldbody> <worldbody>
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1"> <geom name="+x" class="wall" zaxis="1 0 0" pos="-.5 0 -.25"/>
<geom size=".02" rgba=".8 .2 .1 1"/> <geom name="-x" class="wall" zaxis="-1 0 0" pos=".5 0 -.25"/>
</composite> <geom name="+y" class="wall" zaxis="0 1 0" pos="0 -.5 -.25"/>
</worldbody> <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">
<geom size=".025" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
</mujoco> </mujoco>
+12 -13
View File
@@ -14,20 +14,19 @@
--> -->
<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"/> <size nconmax="100" njmax="300" nstack="50000"/>
<size nconmax="100" njmax="300" nstack="50000"/> <worldbody>
<body name="B10" pos="0 0 1">
<worldbody> <freejoint/>
<body name="B10" pos="0 0 1"> <composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
<freejoint/> <joint kind="main" damping="0.005"/>
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2"> <geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
<joint kind="main" damping="0.005"/> </composite>
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/> </body>
</composite> </worldbody>
</body>
</worldbody>
</mujoco> </mujoco>
+28 -28
View File
@@ -14,39 +14,39 @@
--> -->
<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>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="4096"/>
<map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/>
</visual>
<visual> <asset>
<rgba haze="0.15 0.25 0.35 1"/> <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<quality shadowsize="2048"/> <texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
<map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/> width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
</visual> <texture name="texcarpet" type="2d" file="carpet.png"/>
<texture name="texsponge" type="2d" file="sponge.png"/>
<texture name="texmarble" type="cube" file="marble.png"/>
<asset> <material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/> <material name="matcarpet" texture="texcarpet"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" <material name="matsponge" texture="texsponge" specular="0.3"/>
width="512" height="512" mark="cross" markrgb=".8 .8 .8"/> <material name="matmarble" texture="texmarble" rgba=".7 .7 .7 1"/>
<texture name="texcarpet" type="2d" file="carpet.png"/> </asset>
<texture name="texsponge" type="2d" file="sponge.png"/>
<texture name="texmarble" type="cube" file="marble.png"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/> <worldbody>
<material name="matcarpet" texture="texcarpet"/> <light directional="true" diffuse=".4 .4 .4" specular="0.1 0.1 0.1" pos="0 0 5.0" dir="0 0 -1" castshadow="false"/>
<material name="matsponge" texture="texsponge" specular="0.3"/> <light directional="true" diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
<material name="matmarble" texture="texmarble" rgba=".7 .7 .7 1"/>
</asset>
<worldbody> <geom name="ground" type="plane" size="0 0 1" pos="0 0 0" quat="1 0 0 0" material="matplane" condim="1"/>
<light directional="true" diffuse=".4 .4 .4" specular="0.1 0.1 0.1" pos="0 0 5.0" dir="0 0 -1" castshadow="false"/>
<light directional="true" diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
<geom name="ground" type="plane" size="0 0 1" pos="0 0 0" quat="1 0 0 0" material="matplane" condim="1"/> <body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1">
<geom type="capsule" size=".1 .1" material="matmarble" group="1" condim="1"/>
<body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1"> </body>
<geom type="capsule" size=".1 .1" material="matmarble" group="1" condim="1"/> </worldbody>
</body>
</worldbody>
</mujoco> </mujoco>
+17 -13
View File
@@ -14,20 +14,24 @@
--> -->
<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"/> <size nconmax="500" njmax="5000" nstack="5000000"/>
<size nconmax="500" njmax="5000" nstack="5000000"/> <worldbody>
<body pos="0 0 1">
<worldbody> <freejoint/>
<body pos="0 0 1"> <composite type="box" count="7 7 7" spacing="0.04">
<freejoint/> <skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
<composite type="box" count="7 7 7" spacing="0.04"> <geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/> <joint kind="main" solreffix="0.03 1" solimpfix="0 .1 .01"/>
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/> </composite>
</composite> </body>
</body> </worldbody>
</worldbody>
</mujoco> </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 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
+38 -140
View File
@@ -14,152 +14,50 @@
--> -->
<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"/> <visual>
<map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="2048"/>
<global offwidth="800" offheight="800"/>
</visual>
<visual> <asset>
<map force="0.1" zfar="30"/> <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
<rgba haze="0.15 0.25 0.35 1"/> <texture name="plane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
<quality shadowsize="2048"/> width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<global offwidth="800" offheight="800"/> <texture name="hammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1"
</visual> width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
<material name="plane" reflectance="0.3" texture="plane" texrepeat="1 1" texuniform="true"/>
<material name="hammock" texture="hammock"/>
</asset>
<asset> <include file="humanoid_body.xml"/>
<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"/> <worldbody>
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="plane" condim="3"/>
<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"/> <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" dir="0 0 -1"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278" <composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/> <skin texcoord="true" material="hammock" inflate="0.01" subgrid="3"/>
<pin coord="0 0"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/> <pin coord="10 0"/>
<material name="mathammock" texture="texhammock"/> <pin coord="0 8"/>
<pin coord="10 8"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/> <geom size=".095"/>
</asset> <joint kind="main" damping="10"/>
</composite>
<worldbody> </worldbody>
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="matplane" 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="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/>
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
<skin texcoord="true" material="mathammock" inflate="0.01" subgrid="3"/>
<pin coord="0 0"/>
<pin coord="10 0"/>
<pin coord="0 8"/>
<pin coord="10 8"/>
<geom size=".095"/>
<joint kind="main" damping="10"/>
</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>
<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>
+139 -123
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"/>
<default> <asset>
<joint limited="true" damping="1" armature="0"/> <texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
<geom condim="1" material="matgeom"/> <texture name="body" type="cube" builtin="flat" mark="cross" width="127" height="1278"
<motor ctrlrange="-.4 .4" ctrllimited="true"/> 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>
</default>
<option timestep="0.005" iterations="50" tolerance="1e-10" solver="Newton" jacobian="dense" cone="pyramidal"/> <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>
<size nconmax="50" njmax="200" nstack="10000"/> <worldbody>
<geom name="floor" size="0 0 .05" type="plane" material="grid" condim="3"/>
<visual> <light name="spotlight" mode="targetbodycom" target="torso"
<map force="0.1" zfar="30"/> diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 -20 4" cutoff="10"/>
<rgba haze="0.15 0.25 0.35 1"/> <body name="torso" pos="0 0 1.5" childclass="body">
<quality shadowsize="2048"/> <light name="top" pos="0 0 2" mode="trackcom"/>
<global offwidth="800" offheight="800"/> <camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
</visual> <camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
<freejoint name="root"/>
<asset> <geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/> <geom name="upper_waist" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
<body name="head" pos="0 0 .19">
<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"/> <geom name="head" type="sphere" size=".09"/>
<camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278" </body>
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/> <body name="lower_waist" pos="-.01 0 -.26">
<geom name="lower_waist" fromto="0 -.06 0 0 .06 0" size=".06"/>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/> <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"/>
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/> <body name="pelvis" pos="0 0 -.165">
</asset> <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"/>
<worldbody> <body name="right_thigh" pos="0 -.1 -.04">
<geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="matplane" condim="3"/> <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"/>
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/> <joint name="right_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<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"/> <geom name="right_thigh" fromto="0 0 0 0 .01 -.34" size=".06"/>
<body name="right_shin" pos="0 .01 -.403">
<body name="torso" pos="0 0 1.4"> <joint name="right_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
<freejoint name="root"/> <geom name="right_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
<geom name="torso1" type="capsule" fromto="0 -.07 0 0 .07 0" size="0.07"/> <body name="right_foot" pos="0 0 -.39">
<geom name="head" type="sphere" pos="0 0 .19" size=".09"/> <joint name="right_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<geom name="uwaist" type="capsule" fromto="-.01 -.06 -.12 -.01 .06 -.12" size="0.06"/> <joint name="right_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<body name="lwaist" pos="-.01 0 -0.260" quat="1.000 0 -0.002 0" > <geom name="right_right_foot" fromto="-.07 -.02 0 .14 -.04 0" size=".027"/>
<geom name="lwaist" type="capsule" fromto="0 -.06 0 0 .06 0" size="0.06" /> <geom name="left_right_foot" fromto="-.07 0 0 .14 .02 0" size=".027"/>
<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="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>
<body name="right_upper_arm" pos="0 -0.17 0.06" > </body>
<joint name="right_shoulder1" type="hinge" pos="0 0 0" axis="2 1 1" range="-85 60" stiffness="1" armature="0.0068" /> <body name="left_thigh" pos="0 .1 -.04">
<joint name="right_shoulder2" type="hinge" pos="0 0 0" axis="0 -1 1" range="-85 60" stiffness="1" armature="0.0051" /> <joint name="left_hip_x" axis="-1 0 0" range="-25 5" class="big_joint"/>
<geom name="right_uarm1" type="capsule" fromto="0 0 0 .16 -.16 -.16" size="0.04 0.16" /> <joint name="left_hip_z" axis="0 0 -1" range="-60 35" class="big_joint"/>
<body name="right_lower_arm" pos=".18 -.18 -.18" > <joint name="left_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
<joint name="right_elbow" type="hinge" pos="0 0 0" axis="0 -1 1" range="-90 50" stiffness="0" armature="0.0028" /> <geom name="left_thigh" fromto="0 0 0 0 -.01 -.34" size=".06"/>
<geom name="right_larm" type="capsule" fromto="0.01 0.01 0.01 .17 .17 .17" size="0.031" /> <body name="left_shin" pos="0 -.01 -.403">
<geom name="right_hand" type="sphere" pos=".18 .18 .18" size="0.04"/> <joint name="left_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
</body> <geom name="left_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
</body> <body name="left_foot" pos="0 0 -.39">
<body name="left_upper_arm" pos="0 0.17 0.06" > <joint name="left_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
<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_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
<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_left_foot" fromto="-.07 .02 0 .14 .04 0" size=".027"/>
<geom name="left_uarm1" type="capsule" fromto="0 0 0 .16 .16 -.16" size="0.04 0.16" /> <geom name="right_left_foot" fromto="-.07 0 0 .14 -.02 0" size=".027"/>
<body name="left_lower_arm" pos=".18 .18 -.18" > </body>
<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>
</body> </body>
</worldbody> </body>
<body name="right_upper_arm" pos="0 -.17 .06">
<actuator> <joint name="right_shoulder1" axis="2 1 1" range="-85 60"/>
<motor name="abdomen_y" gear="200" joint="abdomen_y" /> <joint name="right_shoulder2" axis="0 -1 1" range="-85 60"/>
<motor name="abdomen_z" gear="200" joint="abdomen_z" /> <geom name="right_upper_arm" fromto="0 0 0 .16 -.16 -.16" size=".04 .16"/>
<motor name="abdomen_x" gear="200" joint="abdomen_x" /> <body name="right_lower_arm" pos=".18 -.18 -.18">
<motor name="right_hip_x" gear="200" joint="right_hip_x" /> <joint name="right_elbow" axis="0 -1 1" range="-90 50" stiffness="0"/>
<motor name="right_hip_z" gear="200" joint="right_hip_z" /> <geom name="right_lower_arm" fromto=".01 .01 .01 .17 .17 .17" size=".031"/>
<motor name="right_hip_y" gear="600" joint="right_hip_y" /> <body name="right_hand" pos=".18 .18 .18">
<motor name="right_knee" gear="400" joint="right_knee" /> <geom name="right_hand" type="sphere" size=".04" zaxis="1 1 1"/>
<motor name="right_ankle_x" gear="100" joint="right_ankle_x" /> </body>
<motor name="right_ankle_y" gear="100" joint="right_ankle_y" /> </body>
<motor name="left_hip_x" gear="200" joint="left_hip_x" /> </body>
<motor name="left_hip_z" gear="200" joint="left_hip_z" /> <body name="left_upper_arm" pos="0 .17 .06">
<motor name="left_hip_y" gear="600" joint="left_hip_y" /> <joint name="left_shoulder1" axis="2 -1 1" range="-60 85"/>
<motor name="left_knee" gear="400" joint="left_knee" /> <joint name="left_shoulder2" axis="0 1 1" range="-60 85"/>
<motor name="left_ankle_x" gear="100" joint="left_ankle_x" /> <geom name="left_upper_arm" fromto="0 0 0 .16 .16 -.16" size=".04 .16"/>
<motor name="left_ankle_y" gear="100" joint="left_ankle_y" /> <body name="left_lower_arm" pos=".18 .18 -.18">
<motor name="right_shoulder1" gear="100" joint="right_shoulder1" /> <joint name="left_elbow" axis="0 -1 -1" range="-90 50" stiffness="0"/>
<motor name="right_shoulder2" gear="100" joint="right_shoulder2" /> <geom name="left_lower_arm" fromto=".01 -.01 .01 .17 -.17 .17" size=".031"/>
<motor name="right_elbow" gear="200" joint="right_elbow" /> <body name="left_hand" pos=".18 -.18 .18">
<motor name="left_shoulder1" gear="100" joint="left_shoulder1" /> <geom name="left_hand" type="sphere" size=".04" zaxis="1 -1 1"/>
<motor name="left_shoulder2" gear="100" joint="left_shoulder2" /> </body>
<motor name="left_elbow" gear="200" joint="left_elbow" /> </body>
</actuator> </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> </mujoco>
File diff suppressed because it is too large Load Diff
+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>
+83 -84
View File
@@ -14,108 +14,107 @@
--> -->
<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"/> <visual>
<rgba haze=".3 .3 .3 1"/>
</visual>
<visual> <default>
<rgba haze=".3 .3 .3 1"/> <joint type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="0 120" damping="0.1"/>
</visual> <muscle ctrllimited="true" ctrlrange="0 1"/>
</default>
<default> <asset>
<joint type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="0 120" damping="0.1"/> <texture type="skybox" builtin="gradient" rgb1="0.6 0.6 0.6" rgb2="0 0 0" width="512" height="512"/>
<muscle ctrllimited="true" ctrlrange="0 1"/>
</default>
<asset> <texture name="texplane" type="2d" builtin="checker" rgb1=".25 .25 .25" rgb2=".3 .3 .3" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
<texture type="skybox" builtin="gradient" rgb1="0.6 0.6 0.6" rgb2="0 0 0" width="512" height="512"/>
<texture name="texplane" type="2d" builtin="checker" rgb1=".25 .25 .25" rgb2=".3 .3 .3" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/> <material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
</asset>
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/> <worldbody>
</asset> <geom name="floor" pos="0 0 -0.5" size="0 0 1" type="plane" material="matplane"/>
<worldbody> <light directional="true" diffuse=".8 .8 .8" specular=".2 .2 .2" pos="0 0 5" dir="0 0 -1"/>
<geom name="floor" pos="0 0 -0.5" size="0 0 1" type="plane" material="matplane"/>
<light directional="true" diffuse=".8 .8 .8" specular=".2 .2 .2" pos="0 0 5" dir="0 0 -1"/> <site name="s0" pos="-0.15 0 0" size="0.02"/>
<site name="x0" pos="0 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
<site name="s0" pos="-0.15 0 0" size="0.02"/> <body pos="0 0 0">
<site name="x0" pos="0 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/> <geom name="upper arm" type="capsule" size="0.045" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
<joint name="shoulder"/>
<geom name="shoulder" type="cylinder" pos="0 0 0" size=".1 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
<body pos="0 0 0"> <site name="s1" pos="0.15 0.06 0" size="0.02"/>
<geom name="upper arm" type="capsule" size="0.045" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/> <site name="s2" pos="0.15 -0.06 0" size="0.02"/>
<joint name="shoulder"/> <site name="s3" pos="0.4 0.06 0" size="0.02"/>
<geom name="shoulder" type="cylinder" pos="0 0 0" size=".1 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/> <site name="s4" pos="0.4 -0.06 0" size="0.02"/>
<site name="s5" pos="0.25 0.1 0" size="0.02"/>
<site name="s6" pos="0.25 -0.1 0" size="0.02"/>
<site name="x1" pos="0.5 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
<site name="s1" pos="0.15 0.06 0" size="0.02"/> <body pos="0.5 0 0">
<site name="s2" pos="0.15 -0.06 0" size="0.02"/> <geom name="forearm" type="capsule" size="0.035" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
<site name="s3" pos="0.4 0.06 0" size="0.02"/> <joint name="elbow"/>
<site name="s4" pos="0.4 -0.06 0" size="0.02"/> <geom name="elbow" type="cylinder" pos="0 0 0" size=".08 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
<site name="s5" pos="0.25 0.1 0" size="0.02"/>
<site name="s6" pos="0.25 -0.1 0" size="0.02"/>
<site name="x1" pos="0.5 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
<body pos="0.5 0 0"> <site name="s7" pos="0.11 0.05 0" size="0.02"/>
<geom name="forearm" type="capsule" size="0.035" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/> <site name="s8" pos="0.11 -0.05 0" size="0.02"/>
<joint name="elbow"/> </body>
<geom name="elbow" type="cylinder" pos="0 0 0" size=".08 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/> </body>
</worldbody>
<site name="s7" pos="0.11 0.05 0" size="0.02"/> <tendon>
<site name="s8" pos="0.11 -0.05 0" size="0.02"/> <spatial name="SF" width="0.01">
</body> <site site="s0"/>
</body> <geom geom="shoulder"/>
</worldbody> <site site="s1"/>
</spatial>
<tendon> <spatial name="SE" width="0.01">
<spatial name="SF" width="0.01"> <site site="s0"/>
<site site="s0"/> <geom geom="shoulder" sidesite="x0"/>
<geom geom="shoulder"/> <site site="s2"/>
<site site="s1"/> </spatial>
</spatial>
<spatial name="SE" width="0.01"> <spatial name="EF" width="0.01">
<site site="s0"/> <site site="s3"/>
<geom geom="shoulder" sidesite="x0"/> <geom geom="elbow"/>
<site site="s2"/> <site site="s7"/>
</spatial> </spatial>
<spatial name="EF" width="0.01"> <spatial name="EE" width="0.01">
<site site="s3"/> <site site="s4"/>
<geom geom="elbow"/> <geom geom="elbow" sidesite="x1"/>
<site site="s7"/> <site site="s8"/>
</spatial> </spatial>
<spatial name="EE" width="0.01"> <spatial name="BF" width="0.009" rgba=".4 .6 .4 1">
<site site="s4"/> <site site="s0"/>
<geom geom="elbow" sidesite="x1"/> <geom geom="shoulder"/>
<site site="s8"/> <site site="s5"/>
</spatial> <geom geom="elbow"/>
<site site="s7"/>
</spatial>
<spatial name="BF" width="0.009" rgba=".4 .6 .4 1"> <spatial name="BE" width="0.009" rgba=".4 .6 .4 1">
<site site="s0"/> <site site="s0"/>
<geom geom="shoulder"/> <geom geom="shoulder" sidesite="x0"/>
<site site="s5"/> <site site="s6"/>
<geom geom="elbow"/> <geom geom="elbow" sidesite="x1"/>
<site site="s7"/> <site site="s8"/>
</spatial> </spatial>
</tendon>
<spatial name="BE" width="0.009" rgba=".4 .6 .4 1"> <actuator>
<site site="s0"/> <muscle name="SF" tendon="SF"/>
<geom geom="shoulder" sidesite="x0"/> <muscle name="SE" tendon="SE"/>
<site site="s6"/> <muscle name="EF" tendon="EF"/>
<geom geom="elbow" sidesite="x1"/> <muscle name="EE" tendon="EE"/>
<site site="s8"/> <muscle name="BF" tendon="BF"/>
</spatial> <muscle name="BE" tendon="BE"/>
</tendon> </actuator>
<actuator>
<muscle name="SF" tendon="SF"/>
<muscle name="SE" tendon="SE"/>
<muscle name="EF" tendon="EF"/>
<muscle name="EE" tendon="EE"/>
<muscle name="BF" tendon="BF"/>
<muscle name="BE" tendon="BE"/>
</actuator>
</mujoco> </mujoco>
+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_
+125 -128
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,158 +35,156 @@ 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_forward(m, d);
mj_resetData(m, d); }
mj_forward(m, d);
}
} }
// 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); button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
// update mouse position // update mouse position
glfwGetCursorPos(window, &lastx, &lasty); glfwGetCursorPos(window, &lastx, &lasty);
} }
// 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;
double dy = ypos - lasty; double dy = ypos - lasty;
lastx = xpos; lastx = xpos;
lasty = ypos; lasty = ypos;
// get current window size // get current window size
int width, height; int width, height;
glfwGetWindowSize(window, &width, &height); glfwGetWindowSize(window, &width, &height);
// get shift key state // get shift key state
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS || bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS); glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
// 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);
} }
// 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");
{ return 0;
printf(" USAGE: basic modelfile\n"); }
return 0;
// load and compile model
char error[1000] = "Could not load binary model";
if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
m = mj_loadModel(argv[1], 0);
} else {
m = mj_loadXML(argv[1], 0, error, 1000);
}
if (!m) {
mju_error_s("Load model error: %s", error);
}
// make data
d = mj_makeData(m);
// init GLFW
if (!glfwInit()) {
mju_error("Could not initialize GLFW");
}
// create window, make OpenGL context current, request v-sync
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// initialize visualization data structures
mjv_defaultCamera(&cam);
mjv_defaultOption(&opt);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);
// create scene and context
mjv_makeScene(m, &scn, 2000);
mjr_makeContext(m, &con, mjFONTSCALE_150);
// install GLFW mouse and keyboard callbacks
glfwSetKeyCallback(window, keyboard);
glfwSetCursorPosCallback(window, mouse_move);
glfwSetMouseButtonCallback(window, mouse_button);
glfwSetScrollCallback(window, scroll);
// run main loop, target real-time simulation and 60 fps rendering
while (!glfwWindowShouldClose(window)) {
// advance interactive simulation for 1/60 sec
// 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.
// Otherwise add a cpu timer and exit this loop when it is time to render.
mjtNum simstart = d->time;
while (d->time - simstart < 1.0/60.0) {
mj_step(m, d);
} }
// load and compile model // get framebuffer viewport
char error[1000] = "Could not load binary model"; mjrRect viewport = {0, 0, 0, 0};
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") ) glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
m = mj_loadModel(argv[1], 0);
else
m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
mju_error_s("Load model error: %s", error);
// make data // update scene and render
d = mj_makeData(m); mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
mjr_render(viewport, &scn, &con);
// init GLFW // swap OpenGL buffers (blocking call due to v-sync)
if( !glfwInit() ) glfwSwapBuffers(window);
mju_error("Could not initialize GLFW");
// create window, make OpenGL context current, request v-sync // process pending GUI events, call GLFW callbacks
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL); glfwPollEvents();
glfwMakeContextCurrent(window); }
glfwSwapInterval(1);
// initialize visualization data structures //free visualization storage
mjv_defaultCamera(&cam); mjv_freeScene(&scn);
mjv_defaultOption(&opt); mjr_freeContext(&con);
mjv_defaultScene(&scn);
mjr_defaultContext(&con);
// create scene and context // free MuJoCo model and data
mjv_makeScene(m, &scn, 2000); mj_deleteData(d);
mjr_makeContext(m, &con, mjFONTSCALE_150); mj_deleteModel(m);
// install GLFW mouse and keyboard callbacks // terminate GLFW (crashes with Linux NVidia drivers)
glfwSetKeyCallback(window, keyboard); #if defined(__APPLE__) || defined(_WIN32)
glfwSetCursorPosCallback(window, mouse_move); glfwTerminate();
glfwSetMouseButtonCallback(window, mouse_button); #endif
glfwSetScrollCallback(window, scroll);
// run main loop, target real-time simulation and 60 fps rendering return 1;
while( !glfwWindowShouldClose(window) )
{
// advance interactive simulation for 1/60 sec
// 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.
// Otherwise add a cpu timer and exit this loop when it is time to render.
mjtNum simstart = d->time;
while( d->time - simstart < 1.0/60.0 )
mj_step(m, d);
// get framebuffer viewport
mjrRect viewport = {0, 0, 0, 0};
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
// update scene and render
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
mjr_render(viewport, &scn, &con);
// swap OpenGL buffers (blocking call due to v-sync)
glfwSwapBuffers(window);
// process pending GUI events, call GLFW callbacks
glfwPollEvents();
}
//free visualization storage
mjv_freeScene(&scn);
mjr_freeContext(&con);
// free MuJoCo model and data
mj_deleteData(d);
mj_deleteModel(m);
// terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32)
glfwTerminate();
#endif
return 1;
} }
+100 -98
View File
@@ -12,135 +12,137 @@
// 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[] =
"\n Usage: compile infile outfile\n" "\n Usage: compile infile outfile\n"
" infile can be in mjcf, urdf, mjb format\n" " infile can be in mjcf, urdf, mjb format\n"
" outfile can be in mjcf, mjb, txt format\n\n" " outfile can be in mjcf, mjb, txt format\n\n"
" Example: compile model.xml model.mjb\n"; " Example: compile model.xml model.mjb\n";
// 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, typeTXT
typeTXT
}; };
// 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]; std::size_t i=0;
size_t i=0; while (i<std::strlen(filename) && i<999) {
while( i<strlen(filename) && i<999 ) lower[i] = (char)tolower(filename[i]);
{ i++;
lower[i] = (char)tolower(filename[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]);
int type2 = filetype(argv[2]); int type2 = filetype(argv[2]);
// 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
if (type1==typeXML) {
m = mj_loadXML(argv[1], 0, error, 1000);
} else {
m = mj_loadModel(argv[1], 0);
}
// check error
if (!m) {
if (type1==typeXML) {
return finish(error, 0);
} else {
return finish("Could not load model", 0);
} }
}
// load model // save model
if( type1==typeXML ) if (type2==typeXML) {
m = mj_loadXML(argv[1], 0, error, 1000); if (mj_saveLastXML(argv[2], m, error, 1000)) {
else return finish(error, m);
m = mj_loadModel(argv[1], 0);
// check error
if( !m )
{
if( type1==typeXML )
return finish(error, 0);
else
return finish("Could not load model", 0);
} }
} else if (type2==typeMJB) {
mj_saveModel(m, argv[2], 0, 0);
} else {
mj_printModel(m, argv[2]);
}
// save model // finalize
if( type2==typeXML ) return finish("Done", m);
{
if( mj_saveLastXML(argv[2], m, error, 1000) )
return finish(error, m);
}
else if( type2==typeMJB )
mj_saveModel(m, argv[2], 0, 0);
else
mj_printModel(m, argv[2]);
// finalize
return finish("Done", m);
} }
+341 -343
View File
@@ -12,29 +12,32 @@
// 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)
#include <omp.h> #include <omp.h>
#else #else
// omp timer replacement // omp timer replacement
#include <chrono> #include <chrono>
double omp_get_wtime(void) double omp_get_wtime(void)
{ {
static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now(); static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start; std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start;
return elapsed.count(); return elapsed.count();
} }
// 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,388 +59,383 @@ 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
mjMARKSTACK mjMARKSTACK
mjtNum* center = mj_stackAlloc(d, nv); mjtNum* center = mj_stackAlloc(d, nv);
mjtNum* warmstart = mj_stackAlloc(d, nv); mjtNum* warmstart = mj_stackAlloc(d, nv);
// prepare static schedule: range of derivative columns to be computed by this thread // prepare static schedule: range of derivative columns to be computed by this thread
int chunk = (m->nv + nthread-1) / nthread; int chunk = (m->nv + nthread-1) / nthread;
int istart = id * chunk; int istart = id * chunk;
int iend = mjMIN(istart + chunk, m->nv); int iend = mjMIN(istart + chunk, m->nv);
// copy state and control from dmain to thread-specific d // copy state and control from dmain to thread-specific d
d->time = dmain->time; d->time = dmain->time;
mju_copy(d->qpos, dmain->qpos, m->nq);
mju_copy(d->qvel, dmain->qvel, m->nv);
mju_copy(d->qacc, dmain->qacc, m->nv);
mju_copy(d->qacc_warmstart, dmain->qacc_warmstart, m->nv);
mju_copy(d->qfrc_applied, dmain->qfrc_applied, m->nv);
mju_copy(d->xfrc_applied, dmain->xfrc_applied, 6*m->nbody);
mju_copy(d->ctrl, dmain->ctrl, m->nu);
// run full computation at center point (usually faster than copying dmain)
if (isforward) {
mj_forward(m, d);
// extra solver iterations to improve warmstart (qacc) at center point
for (int rep=1; rep<nwarmup; rep++) {
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
}
} else {
mj_inverse(m, d);
}
// select output from forward or inverse dynamics
mjtNum* output = (isforward ? d->qacc : d->qfrc_inverse);
// save output for center point and warmstart (needed in forward only)
mju_copy(center, output, nv);
mju_copy(warmstart, d->qacc_warmstart, nv);
// select target vector and original vector for force or acceleration derivative
mjtNum* target = (isforward ? d->qfrc_applied : d->qacc);
const mjtNum* original = (isforward ? dmain->qfrc_applied : dmain->qacc);
// finite-difference over force or acceleration: skip = mjSTAGE_VEL
for (int i=istart; i<iend; i++) {
// perturb selected target
target[i] += eps;
// evaluate dynamics, with center warmstart
if (isforward) {
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
} else {
mj_inverseSkip(m, d, mjSTAGE_VEL, 1);
}
// undo perturbation
target[i] = original[i];
// compute column i of derivative 2
for (int j=0; j<nv; j++) {
deriv[(3*isforward+2)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
}
// finite-difference over velocity: skip = mjSTAGE_POS
for (int i=istart; i<iend; i++) {
// perturb velocity
d->qvel[i] += eps;
// evaluate dynamics, with center warmstart
if (isforward) {
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_POS, 1);
} else {
mj_inverseSkip(m, d, mjSTAGE_POS, 1);
}
// undo perturbation
d->qvel[i] = dmain->qvel[i];
// compute column i of derivative 1
for (int j=0; j<nv; j++) {
deriv[(3*isforward+1)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
}
// finite-difference over position: skip = mjSTAGE_NONE
for (int i=istart; i<iend; i++) {
// get joint id for this dof
int jid = m->dof_jntid[i];
// get quaternion address and dof position within quaternion (-1: not in quaternion)
int quatadr = -1, dofpos = 0;
if (m->jnt_type[jid]==mjJNT_BALL) {
quatadr = m->jnt_qposadr[jid];
dofpos = i - m->jnt_dofadr[jid];
} else if (m->jnt_type[jid]==mjJNT_FREE && i>=m->jnt_dofadr[jid]+3) {
quatadr = m->jnt_qposadr[jid] + 3;
dofpos = i - m->jnt_dofadr[jid] - 3;
}
// apply quaternion or simple perturbation
if (quatadr>=0) {
mjtNum angvel[3] = {0, 0, 0};
angvel[dofpos] = eps;
mju_quatIntegrate(d->qpos+quatadr, angvel, 1);
} else {
d->qpos[m->jnt_qposadr[jid] + i - m->jnt_dofadr[jid]] += eps;
}
// evaluate dynamics, with center warmstart
if (isforward) {
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_NONE, 1);
} else {
mj_inverseSkip(m, d, mjSTAGE_NONE, 1);
}
// undo perturbation
mju_copy(d->qpos, dmain->qpos, m->nq); mju_copy(d->qpos, dmain->qpos, m->nq);
mju_copy(d->qvel, dmain->qvel, m->nv);
mju_copy(d->qacc, dmain->qacc, m->nv);
mju_copy(d->qacc_warmstart, dmain->qacc_warmstart, m->nv);
mju_copy(d->qfrc_applied, dmain->qfrc_applied, m->nv);
mju_copy(d->xfrc_applied, dmain->xfrc_applied, 6*m->nbody);
mju_copy(d->ctrl, dmain->ctrl, m->nu);
// run full computation at center point (usually faster than copying dmain) // compute column i of derivative 0
if( isforward ) for (int j=0; j<nv; j++) {
{ deriv[(3*isforward+0)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
mj_forward(m, d);
// extra solver iterations to improve warmstart (qacc) at center point
for( int rep=1; rep<nwarmup; rep++ )
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
} }
else }
mj_inverse(m, d);
// select output from forward or inverse dynamics mjFREESTACK
mjtNum* output = (isforward ? d->qacc : d->qfrc_inverse);
// save output for center point and warmstart (needed in forward only)
mju_copy(center, output, nv);
mju_copy(warmstart, d->qacc_warmstart, nv);
// select target vector and original vector for force or acceleration derivative
mjtNum* target = (isforward ? d->qfrc_applied : d->qacc);
const mjtNum* original = (isforward ? dmain->qfrc_applied : dmain->qacc);
// finite-difference over force or acceleration: skip = mjSTAGE_VEL
for( int i=istart; i<iend; i++ )
{
// perturb selected target
target[i] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_VEL, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_VEL, 1);
// undo perturbation
target[i] = original[i];
// compute column i of derivative 2
for( int j=0; j<nv; j++ )
deriv[(3*isforward+2)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
// finite-difference over velocity: skip = mjSTAGE_POS
for( int i=istart; i<iend; i++ )
{
// perturb velocity
d->qvel[i] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_POS, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_POS, 1);
// undo perturbation
d->qvel[i] = dmain->qvel[i];
// compute column i of derivative 1
for( int j=0; j<nv; j++ )
deriv[(3*isforward+1)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
// finite-difference over position: skip = mjSTAGE_NONE
for( int i=istart; i<iend; i++ )
{
// get joint id for this dof
int jid = m->dof_jntid[i];
// get quaternion address and dof position within quaternion (-1: not in quaternion)
int quatadr = -1, dofpos = 0;
if( m->jnt_type[jid]==mjJNT_BALL )
{
quatadr = m->jnt_qposadr[jid];
dofpos = i - m->jnt_dofadr[jid];
}
else if( m->jnt_type[jid]==mjJNT_FREE && i>=m->jnt_dofadr[jid]+3 )
{
quatadr = m->jnt_qposadr[jid] + 3;
dofpos = i - m->jnt_dofadr[jid] - 3;
}
// apply quaternion or simple perturbation
if( quatadr>=0 )
{
mjtNum angvel[3] = {0,0,0};
angvel[dofpos] = eps;
mju_quatIntegrate(d->qpos+quatadr, angvel, 1);
}
else
d->qpos[m->jnt_qposadr[jid] + i - m->jnt_dofadr[jid]] += eps;
// evaluate dynamics, with center warmstart
if( isforward )
{
mju_copy(d->qacc_warmstart, warmstart, m->nv);
mj_forwardSkip(m, d, mjSTAGE_NONE, 1);
}
else
mj_inverseSkip(m, d, mjSTAGE_NONE, 1);
// undo perturbation
mju_copy(d->qpos, dmain->qpos, m->nq);
// compute column i of derivative 0
for( int j=0; j<nv; j++ )
deriv[(3*isforward+0)*nv*nv + i + j*nv] = (output[j] - center[j])/eps;
}
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]);
{ L1base += mju_abs(base[i]);
L1res += mju_abs(residual[i]); }
L1base += mju_abs(base[i]);
}
return (double) mju_log10(mju_max(mjMINVAL,L1res/mju_max(mjMINVAL,L1base))); return (double) mju_log10(mju_max(mjMINVAL, L1res/mju_max(mjMINVAL, L1base)));
} }
// names of residuals for accuracy check // names of residuals for accuracy check
const char* accuracy[8] = { const char* accuracy[8] = {
"G2*F2 - I ", "G2*F2 - I ",
"G2 - G2' ", "G2 - G2' ",
"G1 - G1' ", "G1 - G1' ",
"F2 - F2' ", "F2 - F2' ",
"G1 + G2*F1", "G1 + G2*F1",
"G0 + G2*F0", "G0 + G2*F0",
"F1 + F2*G1", "F1 + F2*G1",
"F0 + F2*G0" "F0 + F2*G0"
}; };
// 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
mjMARKSTACK mjMARKSTACK
mjtNum* mat = mj_stackAlloc(d, nv*nv); mjtNum* mat = mj_stackAlloc(d, nv*nv);
// get pointers to derivative matrices // get pointers to derivative matrices
mjtNum* G0 = deriv; // dinv/dpos mjtNum* G0 = deriv; // dinv/dpos
mjtNum* G1 = deriv + nv*nv; // dinv/dvel mjtNum* G1 = deriv + nv*nv; // dinv/dvel
mjtNum* G2 = deriv + 2*nv*nv; // dinv/dacc mjtNum* G2 = deriv + 2*nv*nv; // dinv/dacc
mjtNum* F0 = deriv + 3*nv*nv; // dacc/dpos mjtNum* F0 = deriv + 3*nv*nv; // dacc/dpos
mjtNum* F1 = deriv + 4*nv*nv; // dacc/dvel mjtNum* F1 = deriv + 4*nv*nv; // dacc/dvel
mjtNum* F2 = deriv + 5*nv*nv; // dacc/dfrc mjtNum* F2 = deriv + 5*nv*nv; // dacc/dfrc
// 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'
mju_transpose(mat, G2, nv, nv); mju_transpose(mat, G2, nv, nv);
mju_sub(mat, mat, G2, nv*nv); mju_sub(mat, mat, G2, nv*nv);
error[1] = relnorm(mat, G2, nv*nv); error[1] = relnorm(mat, G2, nv*nv);
// G1 - G1' // G1 - G1'
mju_transpose(mat, G1, nv, nv); mju_transpose(mat, G1, nv, nv);
mju_sub(mat, mat, G1, nv*nv); mju_sub(mat, mat, G1, nv*nv);
error[2] = relnorm(mat, G1, nv*nv); error[2] = relnorm(mat, G1, nv*nv);
// F2 - F2' // F2 - F2'
mju_transpose(mat, F2, nv, nv); mju_transpose(mat, F2, nv, nv);
mju_sub(mat, mat, F2, nv*nv); mju_sub(mat, mat, F2, nv*nv);
error[3] = relnorm(mat, F2, nv*nv); error[3] = relnorm(mat, F2, nv*nv);
// G1 + G2*F1 // G1 + G2*F1
mju_mulMatMat(mat, G2, F1, nv, nv, nv); mju_mulMatMat(mat, G2, F1, nv, nv, nv);
mju_addTo(mat, G1, nv*nv); mju_addTo(mat, G1, nv*nv);
error[4] = relnorm(mat, G1, nv*nv); error[4] = relnorm(mat, G1, nv*nv);
// G0 + G2*F0 // G0 + G2*F0
mju_mulMatMat(mat, G2, F0, nv, nv, nv); mju_mulMatMat(mat, G2, F0, nv, nv, nv);
mju_addTo(mat, G0, nv*nv); mju_addTo(mat, G0, nv*nv);
error[5] = relnorm(mat, G0, nv*nv); error[5] = relnorm(mat, G0, nv*nv);
// F1 + F2*G1 // F1 + F2*G1
mju_mulMatMat(mat, F2, G1, nv, nv, nv); mju_mulMatMat(mat, F2, G1, nv, nv, nv);
mju_addTo(mat, F1, nv*nv); mju_addTo(mat, F1, nv*nv);
error[6] = relnorm(mat, F1, nv*nv); error[6] = relnorm(mat, F1, nv*nv);
// F0 + F2*G0 // F0 + F2*G0
mju_mulMatMat(mat, F2, G0, nv, nv, nv); mju_mulMatMat(mat, F2, G0, nv, nv, nv);
mju_addTo(mat, F0, nv*nv); mju_addTo(mat, F0, nv*nv);
error[7] = relnorm(mat, F0, nv*nv); error[7] = relnorm(mat, F0, nv*nv);
mjFREESTACK mjFREESTACK
} }
// 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");
{ return 1;
printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n"); }
return 1;
}
// default nthread = number of logical cores (usually optimal) // default nthread = number of logical cores (usually optimal)
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);
// set up OpenMP (if not enabled, this does nothing) // set up OpenMP (if not enabled, this does nothing)
omp_set_dynamic(0); omp_set_dynamic(0);
omp_set_num_threads(nthread); omp_set_num_threads(nthread);
// save solver options // save solver options
int save_iterations = m->opt.iterations; int save_iterations = m->opt.iterations;
mjtNum save_tolerance = m->opt.tolerance; mjtNum save_tolerance = m->opt.tolerance;
// allocate statistics // allocate statistics
int nefc = 0; int nefc = 0;
double cputm[MAXEPOCH][2]; double cputm[MAXEPOCH][2];
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
nefc += dmain->nefc;
// set solver options for finite differences
m->opt.iterations = niter;
m->opt.tolerance = 0;
// test forward and inverse
for( isforward=0; isforward<2; isforward++ )
{
// start timer
double starttm = omp_get_wtime();
// run worker threads in parallel if OpenMP is enabled
#pragma omp parallel for schedule(static)
for( int n=0; n<nthread; n++ )
worker(m, dmain, d[n], n);
// record duration in ms
cputm[epoch][isforward] = 1000*(omp_get_wtime() - starttm);
}
// check derivatives
checkderiv(m, d[0], error[epoch]);
} }
// compute statistics // count number of active constraints
double mcputm[2] = {0,0}, merror[8] = {0,0,0,0,0,0,0,0}; nefc += dmain->nefc;
for( int epoch=0; epoch<nepoch; epoch++ )
{
mcputm[0] += cputm[epoch][0];
mcputm[1] += cputm[epoch][1];
for( int ie=0; ie<8; ie++ ) // set solver options for finite differences
merror[ie] += error[epoch][ie]; m->opt.iterations = niter;
m->opt.tolerance = 0;
// test forward and inverse
for (isforward=0; isforward<2; isforward++) {
// start timer
double starttm = omp_get_wtime();
// run worker threads in parallel if OpenMP is enabled
#pragma omp parallel for schedule(static)
for (int n=0; n<nthread; n++) {
worker(m, dmain, d[n], n);
}
// record duration in ms
cputm[epoch][isforward] = 1000*(omp_get_wtime() - starttm);
} }
// print sizes, timing, accuracy // check derivatives
printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch); checkderiv(m, d[0], error[epoch]);
printf("inverse : %.2f ms\n", mcputm[0]/nepoch); }
printf("forward : %.2f ms\n\n", mcputm[1]/nepoch);
printf("accuracy: log10(residual L1 relnorm)\n");
printf("------------------------------------\n");
for( int ie=0; ie<8; ie++ )
printf(" %s : %.2g\n", accuracy[ie], merror[ie]/nepoch);
printf("\n");
// shut down // compute statistics
mju_free(deriv); double mcputm[2] = {0, 0}, merror[8] = {0, 0, 0, 0, 0, 0, 0, 0};
mj_deleteData(dmain); for (int epoch=0; epoch<nepoch; epoch++) {
for( int n=0; n<nthread; n++ ) mcputm[0] += cputm[epoch][0];
mj_deleteData(d[n]); mcputm[1] += cputm[epoch][1];
mj_deleteModel(m);
return 0; for (int ie=0; ie<8; ie++) {
merror[ie] += error[epoch][ie];
}
}
// print sizes, timing, accuracy
std::printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch);
std::printf("inverse : %.2f ms\n", mcputm[0]/nepoch);
std::printf("forward : %.2f ms\n\n", mcputm[1]/nepoch);
std::printf("accuracy: log10(residual L1 relnorm)\n");
std::printf("------------------------------------\n");
for (int ie=0; ie<8; ie++) {
std::printf(" %s : %.2g\n", accuracy[ie], merror[ie]/nepoch);
}
std::printf("\n");
// shut down
mju_free(deriv);
mj_deleteData(dmain);
for (int n=0; n<nthread; n++) {
mj_deleteData(d[n]);
}
mj_deleteModel(m);
return 0;
} }
+217 -208
View File
@@ -12,23 +12,25 @@
// 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)
#include <EGL/egl.h> #include <EGL/egl.h>
#elif defined(MJ_OSMESA) #elif defined(MJ_OSMESA)
#include <GL/osmesa.h> #include <GL/osmesa.h>
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,266 +48,273 @@ 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 (std::strlen(filename)>4 && !std::strcmp(filename+std::strlen(filename)-4, ".mjb")) {
if( strlen(filename)>4 && !strcmp(filename+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);
mj_forward(m, d); mj_forward(m, d);
// initialize visualization data structures // initialize visualization data structures
mjv_defaultCamera(&cam); mjv_defaultCamera(&cam);
mjv_defaultOption(&opt); mjv_defaultOption(&opt);
mjv_defaultScene(&scn); mjv_defaultScene(&scn);
mjr_defaultContext(&con); mjr_defaultContext(&con);
// create scene and context // create scene and context
mjv_makeScene(m, &scn, 2000); mjv_makeScene(m, &scn, 2000);
mjr_makeContext(m, &con, 200); mjr_makeContext(m, &con, 200);
// center and scale view // center and scale view
cam.lookat[0] = m->stat.center[0]; cam.lookat[0] = m->stat.center[0];
cam.lookat[1] = m->stat.center[1]; cam.lookat[1] = m->stat.center[1];
cam.lookat[2] = m->stat.center[2]; cam.lookat[2] = m->stat.center[2];
cam.distance = 1.5 * m->stat.extent; cam.distance = 1.5 * m->stat.extent;
} }
// 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); mjv_freeScene(&scn);
mjv_freeScene(&scn);
} }
// 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
const EGLint configAttribs[] ={ const EGLint configAttribs[] = {
EGL_RED_SIZE, 8, EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8, EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8, EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8, EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24, EGL_DEPTH_SIZE, 24,
EGL_STENCIL_SIZE, 8, EGL_STENCIL_SIZE, 8,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE EGL_NONE
}; };
// 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);
#endif #endif
} }
// 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();
// release context // release context
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);
//------------------------ OSMESA //------------------------ OSMESA
#elif defined(MJ_OSMESA) #elif defined(MJ_OSMESA)
OSMesaDestroyContext(ctx); OSMesaDestroyContext(ctx);
//------------------------ GLFW //------------------------ GLFW
#else #else
// terminate GLFW (crashes with Linux NVidia drivers) // terminate GLFW (crashes with Linux NVidia drivers)
#if defined(__APPLE__) || defined(_WIN32) #if defined(__APPLE__) || defined(_WIN32)
glfwTerminate(); glfwTerminate();
#endif #endif
#endif #endif
} }
//-------------------------------- 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");
{ return 0;
printf(" USAGE: record modelfile duration fps rgbfile\n"); }
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();
initMuJoCo(argv[1]); initMuJoCo(argv[1]);
// 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);
int W = viewport.width; int W = viewport.width;
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
{ mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
// update abstract scene
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
// render scene in offscreen buffer // render scene in offscreen buffer
mjr_render(viewport, &scn, &con); mjr_render(viewport, &scn, &con);
// 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
mjr_readPixels(rgb, depth, viewport, &con); mjr_readPixels(rgb, depth, viewport, &con);
// 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] = (unsigned char)((1.0f-depth[r*W+c])*255.0f);
rgb[3*adr] = rgb[3*adr+1] = rgb[3*adr+2] =
(unsigned char)((1.0f-depth[r*W+c])*255.0f);
}
// write rgb image to file
fwrite(rgb, 3, W*H, fp);
// print every 10 frames: '.' if ok, 'x' if OpenGL error
if( ((framecount++)%10)==0 )
{
if( mjr_getError() )
printf("x");
else
printf(".");
}
// save simulation time
frametime = d->time;
} }
// advance simulation // write rgb image to file
mj_step(m, d); std::fwrite(rgb, 3, W*H, fp);
// print every 10 frames: '.' if ok, 'x' if OpenGL error
if (((framecount++)%10)==0) {
if (mjr_getError()) {
std::printf("x");
} else {
std::printf(".");
}
}
// save simulation time
frametime = d->time;
} }
printf("\n");
// close file, free buffers // advance simulation
fclose(fp); mj_step(m, d);
free(rgb); }
free(depth); std::printf("\n");
// close MuJoCo and OpenGL // close file, free buffers
closeMuJoCo(); std::fclose(fp);
closeOpenGL(); std::free(rgb);
std::free(depth);
return 1; // close MuJoCo and OpenGL
closeMuJoCo();
closeOpenGL();
return 1;
} }
+1690 -1641
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+159 -133
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,161 +33,189 @@ 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
// advance simulation if (ctrlnoise)
mj_step(m, d[id]); 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);
}
// accumulate statistics // advance simulation
contacts[id] += d[id]->ncon; mj_step(m, d[id]);
constraints[id] += d[id]->nefc;
} // accumulate statistics
simtime[id] = gettm() - start; contacts[id] += d[id]->ncon;
constraints[id] += d[id]->nefc;
}
simtime[id] = gettm() - start;
} }
// 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 || argc>6) {
if( argc<3 || argc>5 ) return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
return finish("\n Usage: testspeed modelfile nstep [nthread [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
return finish("Invalid nstep argument"); mjtNum ctrlnoise = 0.01;
if( argc>3 ) if (argc>2)
if( sscanf(argv[3], "%d", &nthread)!=1 ) if (std::sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0) {
return finish("Invalid nthread argument"); return finish("Invalid nstep argument");
if( argc>4 ) }
if( sscanf(argv[4], "%d", &profile)!=1 ) if (argc>3)
return finish("Invalid profile argument"); if (std::sscanf(argv[3], "%d", &nthread)!=1) {
return finish("Invalid nthread argument");
// clamp nthread to [1, 64] }
nthread = mjMAX(1, mjMIN(64, nthread)); if (argc>4)
if (std::sscanf(argv[4], "%lf", &ctrlnoise)!=1) {
// get filename, determine file type return finish("Invalid ctrlnoise argument");
std::string filename(argv[1]); }
bool binary = (filename.find(".mjb")!=std::string::npos); if (argc>5)
if (std::sscanf(argv[5], "%d", &profile)!=1) {
// load model return finish("Invalid profile argument");
char error[1000] = "Could not load binary model";
if( binary )
m = mj_loadModel(argv[1], 0);
else
m = mj_loadXML(argv[1], 0, error, 1000);
if( !m )
return finish(error);
// make per-thread data
int testkey = mj_name2id(m, mjOBJ_KEY, "test");
for( int id=0; id<nthread; id++ )
{
d[id] = mj_makeData(m);
if( !d[id] )
return finish("Could not allocate mjData", m);
// init to keyframe "test" if present
if( testkey>=0 )
{
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]->act, m->key_act + testkey*m->na, m->na);
}
} }
// install timer callback for profiling if requested // clamp ctrlnoise to [0.0, 1.0]
tm_start = chrono::system_clock::now(); ctrlnoise = mjMAX(0.0, mjMIN(ctrlnoise, 1.0));
if( profile )
mjcb_time = gettm;
// print start // clamp nthread to [1, 64]
if( nthread>1 ) nthread = mjMAX(1, mjMIN(64, nthread));
printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep);
else
printf("\nRunning %d steps at dt = %g ...\n\n", nstep, m->opt.timestep);
// run simulation, record total time // get filename, determine file type
thread th[64]; std::string filename(argv[1]);
double starttime = gettm(); bool binary = (filename.find(".mjb")!=std::string::npos);
for( int id=0; id<nthread; id++ )
th[id] = thread(simulate, id, nstep);
for( int id=0; id<nthread; id++ )
th[id].join();
double tottime = gettm() - starttime;
// all-thread summary // load model
if( nthread>1 ) char error[1000] = "Could not load binary model";
{ if (binary) {
printf("Summary for all %d threads\n\n", nthread); m = mj_loadModel(argv[1], 0);
printf(" Total simulation time : %.2f s\n", tottime); } else {
printf(" Total steps per second : %.0f\n", nthread*nstep/tottime); m = mj_loadXML(argv[1], 0, error, 1000);
printf(" Total realtime factor : %.2f x\n", nthread*nstep*m->opt.timestep/tottime); }
printf(" Total time per step : %.4f ms\n\n", 1000*tottime/(nthread*nstep)); if (!m) {
return finish(error);
}
printf("Details for thread 0\n\n"); // make per-thread data
int testkey = mj_name2id(m, mjOBJ_KEY, "test");
for (int id=0; id<nthread; id++) {
d[id] = mj_makeData(m);
if (!d[id]) {
return finish("Could not allocate mjData", m);
} }
// details for thread 0 // init to keyframe "test" if present
printf(" Simulation time : %.2f s\n", simtime[0]); if (testkey>=0) {
printf(" Steps per second : %.0f\n", nstep/simtime[0]); mju_copy(d[id]->qpos, m->key_qpos + testkey*m->nq, m->nq);
printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]); mju_copy(d[id]->qvel, m->key_qvel + testkey*m->nv, m->nv);
printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep); mju_copy(d[id]->act, m->key_act + testkey*m->na, m->na);
printf(" Contacts per step : %d\n", contacts[0]/nstep); }
printf(" Constraints per step : %d\n", constraints[0]/nstep); }
printf(" Degrees of freedom : %d\n\n", m->nv);
// profiler results for thread 0 // install timer callback for profiling if requested
if( profile ) tm_start = std::chrono::system_clock::now();
{ if (profile) {
printf(" Profiler phase (ms per step)\n"); mjcb_time = gettm;
mjtNum tstep = d[0]->timer[mjTIMER_STEP].duration/d[0]->timer[mjTIMER_STEP].number; }
for( int i=0; i<mjNTIMER; i++ )
if( d[0]->timer[i].number>0 ) // print start
{ if (nthread>1) {
mjtNum istep = d[0]->timer[i].duration/d[0]->timer[i].number; std::printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep);
printf(" %16s : %.5f (%6.2f %%)\n", mjTIMERSTRING[i], } else {
std::printf("\nRunning %d steps at dt = %g ...\n\n", nstep, m->opt.timestep);
}
// run simulation, record total time
std::thread th[64];
double starttime = gettm();
for (int id=0; id<nthread; id++) {
th[id] = std::thread(simulate, id, nstep, ctrlnoise);
}
for (int id=0; id<nthread; id++) {
th[id].join();
}
double tottime = gettm() - starttime;
// all-thread summary
if (nthread>1) {
std::printf("Summary for all %d threads\n\n", nthread);
std::printf(" Total simulation time : %.2f s\n", tottime);
std::printf(" Total steps per second : %.0f\n", nthread*nstep/tottime);
std::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));
std::printf("Details for thread 0\n\n");
}
// details for thread 0
std::printf(" Simulation time : %.2f s\n", simtime[0]);
std::printf(" Steps per second : %.0f\n", nstep/simtime[0]);
std::printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]);
std::printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep);
std::printf(" Contacts per step : %.2f\n", static_cast<float>(contacts[0])/nstep);
std::printf(" Constraints per step : %.2f\n", static_cast<float>(constraints[0])/nstep);
std::printf(" Degrees of freedom : %d\n\n", m->nv);
// profiler results for thread 0
if (profile) {
printf(" Profiler phase (ms per step)\n");
mjtNum tstep = d[0]->timer[mjTIMER_STEP].duration/d[0]->timer[mjTIMER_STEP].number;
for (int i=0; i<mjNTIMER; i++)
if (d[0]->timer[i].number>0) {
mjtNum istep = d[0]->timer[i].duration/d[0]->timer[i].number;
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
+107 -111
View File
@@ -12,163 +12,159 @@
// 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
// compare arrays // compare arrays
#define X(type, name, nr, nc) \ #define X(type, name, nr, nc) \
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
// 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
// compare arrays in mjOption // compare arrays in mjOption
#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
// mjVisual and mjStatistics ignored for now // mjVisual and mjStatistics ignored for now
return maxdif; return maxdif;
} }
// 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);
remove(tempfile.c_str()); remove(tempfile.c_str());
// finalize // finalize
return finish(); return finish();
} }
Executable → Regular
+205 -214
View File
@@ -13,221 +13,216 @@
// 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;
// mouse buttons // mouse buttons
state->left = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS); state->left = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
state->right = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS); state->right = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
state->middle = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS); state->middle = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
// keyboard modifiers // keyboard modifiers
state->control = (glfwGetKey(wnd, GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS || state->control = (glfwGetKey(wnd, GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_CONTROL)==GLFW_PRESS); glfwGetKey(wnd, GLFW_KEY_RIGHT_CONTROL)==GLFW_PRESS);
state->shift = (glfwGetKey(wnd, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS || state->shift = (glfwGetKey(wnd, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
glfwGetKey(wnd, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS); glfwGetKey(wnd, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
state->alt = (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS || state->alt = (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
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; }
}
// get mouse position, scale by buffer-to-window ratio // get mouse position, scale by buffer-to-window ratio
double x, y; double x, y;
glfwGetCursorPos(wnd, &x, &y); glfwGetCursorPos(wnd, &x, &y);
x *= ptr->buffer2window; x *= ptr->buffer2window;
y *= ptr->buffer2window; y *= ptr->buffer2window;
// invert y to match OpenGL convention // invert y to match OpenGL convention
y = state->rect[0].height - y; y = state->rect[0].height - y;
// save // save
state->dx = x - state->x; state->dx = x - state->x;
state->dy = y - state->y; state->dy = y - state->y;
state->x = x; state->x = x;
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);
mjuiState* state = ptr->state; mjuiState* state = ptr->state;
// update state // update state
uiUpdateState(wnd); uiUpdateState(wnd);
// set key info // set key info
state->type = mjEVENT_KEY; state->type = mjEVENT_KEY;
state->key = key; state->key = key;
state->keytime = glfwGetTime(); state->keytime = glfwGetTime();
// application-specific processing // application-specific processing
ptr->uiEvent(state); ptr->uiEvent(state);
} }
// 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;
// update state // update state
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
if (act==GLFW_PRESS) {
// detect doubleclick: 250 ms
if (button==state->button && glfwGetTime()-state->buttontime<0.25) {
state->doubleclick = 1;
} else {
state->doubleclick = 0;
} }
// press // set info
if( act==GLFW_PRESS ) state->type = mjEVENT_PRESS;
{ state->button = button;
// detect doubleclick: 250 ms state->buttontime = glfwGetTime();
if( button==state->button && glfwGetTime()-state->buttontime<0.25 )
state->doubleclick = 1;
else
state->doubleclick = 0;
// set info // start dragging
state->type = mjEVENT_PRESS; if (state->mouserect) {
state->button = button; state->dragbutton = state->button;
state->buttontime = glfwGetTime(); state->dragrect = state->mouserect;
// start dragging
if( state->mouserect )
{
state->dragbutton = state->button;
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; }
}
} }
// 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);
// set move info // set move info
state->type = mjEVENT_MOVE; state->type = mjEVENT_MOVE;
// application-specific processing // application-specific processing
ptr->uiEvent(state); ptr->uiEvent(state);
} }
// 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;
// update state // update state
uiUpdateState(wnd); uiUpdateState(wnd);
// set scroll info, scale by buffer-to-window ratio // set scroll info, scale by buffer-to-window ratio
state->type = mjEVENT_SCROLL; state->type = mjEVENT_SCROLL;
state->sx = xoffset * ptr->buffer2window; state->sx = xoffset * ptr->buffer2window;
state->sy = yoffset * ptr->buffer2window; state->sy = yoffset * ptr->buffer2window;
// application-specific processing // application-specific processing
ptr->uiEvent(state); ptr->uiEvent(state);
} }
// 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;
// set layout // set layout
ptr->uiLayout(state); ptr->uiLayout(state);
// update state // update state
uiUpdateState(wnd); uiUpdateState(wnd);
// set resize info // set resize info
state->type = mjEVENT_RESIZE; state->type = mjEVENT_RESIZE;
// stop dragging // stop dragging
state->dragbutton = 0; state->dragbutton = 0;
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);
}
} }
@@ -235,88 +230,84 @@ static void uiResize(GLFWwindow* wnd, int width, int height)
//----------------------------------- 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); glfwGetFramebufferSize(wnd, &width_buf, &height);
glfwGetFramebufferSize(wnd, &width_buf, &height); double b2w = (double)width_buf / (double)width_win;
double b2w = (double)width_buf / (double)width_win;
// compute PPI // compute PPI
int width_MM, height_MM; int width_MM, height_MM;
glfwGetMonitorPhysicalSize(glfwGetPrimaryMonitor(), &width_MM, &height_MM); glfwGetMonitorPhysicalSize(glfwGetPrimaryMonitor(), &width_MM, &height_MM);
int width_vmode = glfwGetVideoMode(glfwGetPrimaryMonitor())->width; int width_vmode = glfwGetVideoMode(glfwGetPrimaryMonitor())->width;
double PPI = 25.4 * b2w * (double)width_vmode / (double)width_MM; double PPI = 25.4 * b2w * (double)width_vmode / (double)width_MM;
// 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 = mjMIN(300, mjMAX(100, fs)); fs = mju_round(fs * 0.02) * 50;
fs = mjMIN(300, mjMAX(100, fs));
return fs; return fs;
} }
// 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; ptr->uiEvent = uiEvent;
ptr->uiEvent = uiEvent; ptr->uiLayout = uiLayout;
ptr->uiLayout = uiLayout; glfwSetWindowUserPointer(wnd, ptr);
glfwSetWindowUserPointer(wnd, ptr);
// compute framebuffer-to-window pixel ratio // compute framebuffer-to-window pixel ratio
int width_win, width_buf, height; int width_win, width_buf, height;
glfwGetWindowSize(wnd, &width_win, &height); glfwGetWindowSize(wnd, &width_win, &height);
glfwGetFramebufferSize(wnd, &width_buf, &height); glfwGetFramebufferSize(wnd, &width_buf, &height);
ptr->buffer2window = (double)width_buf / (double)width_win; ptr->buffer2window = (double)width_buf / (double)width_win;
// set internal callbacks // set internal callbacks
glfwSetKeyCallback(wnd, uiKeyboard); glfwSetKeyCallback(wnd, uiKeyboard);
glfwSetCursorPosCallback(wnd, uiMouseMove); glfwSetCursorPosCallback(wnd, uiMouseMove);
glfwSetMouseButtonCallback(wnd, uiMouseButton); glfwSetMouseButtonCallback(wnd, uiMouseButton);
glfwSetScrollCallback(wnd, uiScroll); glfwSetScrollCallback(wnd, uiScroll);
glfwSetWindowSizeCallback(wnd, uiResize); glfwSetWindowSizeCallback(wnd, uiResize);
} }
// 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));
{ glfwSetWindowUserPointer(wnd, NULL);
mju_free(glfwGetWindowUserPointer(wnd)); }
glfwSetWindowUserPointer(wnd, NULL);
}
// clear internal callbacks // clear internal callbacks
glfwSetKeyCallback(wnd, NULL); glfwSetKeyCallback(wnd, NULL);
glfwSetCursorPosCallback(wnd, NULL); glfwSetCursorPosCallback(wnd, NULL);
glfwSetMouseButtonCallback(wnd, NULL); glfwSetMouseButtonCallback(wnd, NULL);
glfwSetScrollCallback(wnd, NULL); glfwSetScrollCallback(wnd, NULL);
glfwSetWindowSizeCallback(wnd, NULL); glfwSetWindowSizeCallback(wnd, NULL);
} }
// 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); mjui_update(-1, -1, ui, state, con);
mjui_update(-1, -1, ui, state, con);
} }
Executable → Regular
+7 -10
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,12 +30,11 @@ 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; double buffer2window;
double buffer2window;
}; };
typedef struct _uiUserPointer uiUserPointer; typedef struct _uiUserPointer uiUserPointer;