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:
@@ -1,7 +1,3 @@
|
||||
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
|
||||
=============
|
||||
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
|
||||
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
|
||||
constructed programmatically (say using an XML library that writes to memory). Once all desired files are in the VFS,
|
||||
the user can call :ref:`mj_loadModel` or :ref:`mj_loadXML` with a pointer to the VFS. When
|
||||
constructed programmatically (say using a Python library that writes to memory). Once all desired files are in the
|
||||
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
|
||||
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
|
||||
@@ -5254,7 +5250,7 @@ mjui_add
|
||||
Add definitions to UI.
|
||||
|
||||
mjui_addToSection
|
||||
~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -6426,7 +6422,7 @@ Insertion sort, resulting list is in increasing order.
|
||||
.. _mju_insertionSortInt:
|
||||
|
||||
mju_insertionSortInt
|
||||
~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
|
||||
=============
|
||||
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
|
||||
feature should be enabled, because the availability of convex hulls substantially speeds up collision detection with
|
||||
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
|
||||
used when computing the length ranges of actuators, but in the future additional compiler phases may be
|
||||
multi-threaded.
|
||||
|
||||
+109
-5
@@ -1,12 +1,111 @@
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
|
||||
=========
|
||||
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
|
||||
^^^^^^^^^^^^
|
||||
@@ -63,3 +162,8 @@ Earlier Versions
|
||||
----------------
|
||||
|
||||
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
|
||||
|
||||
@@ -60,6 +60,12 @@ redirects = {
|
||||
'index': 'overview.html',
|
||||
}
|
||||
|
||||
rst_prolog = """
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
.. include:: <isonum.txt>
|
||||
"""
|
||||
|
||||
# -- Options for autodoc -----------------------------------------------------
|
||||
|
||||
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
@@ -1,7 +1,3 @@
|
||||
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
|
||||
========
|
||||
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
|
||||
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.
|
||||
|
||||
.. _CTree:
|
||||
@@ -144,7 +140,7 @@ the model. We start with an example.
|
||||
<geom type="ellipsoid"/>
|
||||
<geom type="sphere" rgba="0 0 1 0"/>
|
||||
<geom type="cylinder" class="main"/>
|
||||
</geom>
|
||||
</body>
|
||||
</worldbody>
|
||||
</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
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
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
|
||||
@@ -298,7 +294,7 @@ contact-related solver parameters at runtime, so as to experiment interactively
|
||||
continuation methods for numerical optimization.
|
||||
|
||||
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
|
||||
constraint impedance, and a0 the acceleration in the absence of constraint force. Our earlier analysis revealed that
|
||||
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
|
||||
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
|
||||
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.
|
||||
margin, gap
|
||||
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
|
||||
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
|
||||
require two wrapping objects to be separated by a fixed site in the tendon path. This is to avoid the need for
|
||||
iterative computations of tendon paths. As of MuJoCo 2.0 we also allow "side sites" to be placed inside the sphere or
|
||||
cylinder, which causes an inverse wrap: the tendon path is constrained to pass through the object instead of go around
|
||||
it. This can replace torus wrapping objects used in OpenSim to keep the tendon path within a given area. Overall,
|
||||
tendon wrapping is the most challenging part of converting an OpenSim model to a MuJoCo model, and requires some
|
||||
manual work. On the bright side, there is a small number of high-quality OpenSim models in use, so once they are
|
||||
converted we are done.
|
||||
Tendon wrapping is also more limited in MuJoCo. We allow spheres and infinite cylinders as wrapping objects, and require
|
||||
two wrapping objects to be separated by a fixed site in the tendon path. This is to avoid the need for iterative
|
||||
computations of tendon paths. As of MuJoCo 2.0 we also allow "side sites" to be placed inside the sphere or cylinder,
|
||||
which causes an inverse wrap: the tendon path is constrained to pass through the object instead of going around it. This
|
||||
can replace torus wrapping objects used in OpenSim to keep the tendon path within a given area. Overall, tendon wrapping
|
||||
is the most challenging part of converting an OpenSim model to a MuJoCo model, and requires some manual work. On the
|
||||
bright side, there is a small number of high-quality OpenSim models in use, so once they are 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
|
||||
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.
|
||||
|
||||
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
|
||||
the same place in the XML where a regular child body may have been defined. Each automatically-generated element body
|
||||
has a single geom attached to it, usually a sphere but could also be capsule or ellipsoid. Thus the composite object
|
||||
is essentially a particle system, however the particles can be constrained to move together in ways that simulate
|
||||
various flexible objects. The initial positions of the element bodies form a regular grid in 1D, 2D or 3D. They could
|
||||
all be children of the parent body (which can be the world or another regular body; composite objects cannot be
|
||||
nested) and have joints allowing motion relative to the parent, or they could form a kinematic tree with joints
|
||||
between the element bodies. They can also be connected with tendons with soft equality constraints on the tendon
|
||||
length, creating the necessary coupling. Joint equality constraints are also used in some cases. The :at:`solref`
|
||||
and :at:`solimp` attributes of these equality constraints can be adjusted by the user, thereby adjusting the
|
||||
softness and flexibility of the composite objects.
|
||||
bodies are created as children of the body within which :el:`composite` appears; thus a composite object appears in the
|
||||
same place in the XML where a regular child body may have been defined. Each automatically-generated element body has a
|
||||
single geom attached to it, usually a sphere but could also be a capsule or an ellipsoid. Thus the composite object is
|
||||
essentially a particle system, however the particles can be constrained to move together in ways that simulate various
|
||||
flexible objects. The initial positions of the element bodies form a regular grid in 1D, 2D or 3D. They could all be
|
||||
children of the parent body (which can be the world or another regular body; composite objects cannot be nested) and
|
||||
have joints allowing motion relative to the parent, or they could form a kinematic tree with joints between the element
|
||||
bodies. They can also be connected with tendons with soft equality constraints on the tendon length, creating the
|
||||
necessary coupling. Joint equality constraints are also used in some cases. The :at:`solref` and :at:`solimp` attributes
|
||||
of these equality constraints can be adjusted by the user, thereby adjusting the softness and flexibility of the
|
||||
composite 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
|
||||
@@ -1046,7 +1041,7 @@ points to the outside, thus creating a thicker shell which is harder to penetrat
|
||||
</composite>
|
||||
</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
|
||||
: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
|
||||
@@ -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
|
||||
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>`,
|
||||
: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
|
||||
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
|
||||
@@ -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
|
||||
this?
|
||||
|
||||
The first step is to define a mocap body in the MJCF model, and at implement code that reads the data stream at
|
||||
runtime and sets mjModel.mocap_pos and mjModel.mocap_quat to the position and orientation received from the motion
|
||||
capture system. The `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ code sample uses
|
||||
the mouse as a motion capture device, allowing the user to move mocap bodies around.
|
||||
The first step is to define a mocap body in the MJCF model, and implement code that reads the data stream at runtime and
|
||||
sets mjModel.mocap_pos and mjModel.mocap_quat to the position and orientation received from the motion capture system.
|
||||
The `simulate.cc <https://github.com/deepmind/mujoco/blob/main/sample/simulate.cc>`_ code sample uses the mouse as a
|
||||
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
|
||||
to move from one simulation time step to the next by updating their position and orientation directly, but as far as
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
|
||||
.. include:: includes/macros.rst
|
||||
.. include:: includes/roles.rst
|
||||
|
||||
===========
|
||||
Programming
|
||||
===========
|
||||
|
||||
Executable → Regular
+228
-233
@@ -15,310 +15,305 @@
|
||||
#ifndef MUJOCO_MJDATA_H_
|
||||
#define MUJOCO_MJDATA_H_
|
||||
|
||||
//---------------------------- primitive types (mjt) ------------------------------------
|
||||
#include "mjmodel.h"
|
||||
|
||||
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
|
||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||
|
||||
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;
|
||||
|
||||
|
||||
typedef enum _mjtTimer
|
||||
{
|
||||
// main api
|
||||
mjTIMER_STEP = 0, // step
|
||||
mjTIMER_FORWARD, // forward
|
||||
mjTIMER_INVERSE, // inverse
|
||||
typedef enum mjtTimer_ {
|
||||
// main api
|
||||
mjTIMER_STEP = 0, // step
|
||||
mjTIMER_FORWARD, // forward
|
||||
mjTIMER_INVERSE, // inverse
|
||||
|
||||
// breakdown of step/forward
|
||||
mjTIMER_POSITION, // fwdPosition
|
||||
mjTIMER_VELOCITY, // fwdVelocity
|
||||
mjTIMER_ACTUATION, // fwdActuation
|
||||
mjTIMER_ACCELERATION, // fwdAcceleration
|
||||
mjTIMER_CONSTRAINT, // fwdConstraint
|
||||
// breakdown of step/forward
|
||||
mjTIMER_POSITION, // fwdPosition
|
||||
mjTIMER_VELOCITY, // fwdVelocity
|
||||
mjTIMER_ACTUATION, // fwdActuation
|
||||
mjTIMER_ACCELERATION, // fwdAcceleration
|
||||
mjTIMER_CONSTRAINT, // fwdConstraint
|
||||
|
||||
// breakdown of fwdPosition
|
||||
mjTIMER_POS_KINEMATICS, // kinematics, com, tendon, transmission
|
||||
mjTIMER_POS_INERTIA, // inertia computations
|
||||
mjTIMER_POS_COLLISION, // collision detection
|
||||
mjTIMER_POS_MAKE, // make constraints
|
||||
mjTIMER_POS_PROJECT, // project constraints
|
||||
// breakdown of fwdPosition
|
||||
mjTIMER_POS_KINEMATICS, // kinematics, com, tendon, transmission
|
||||
mjTIMER_POS_INERTIA, // inertia computations
|
||||
mjTIMER_POS_COLLISION, // collision detection
|
||||
mjTIMER_POS_MAKE, // make constraints
|
||||
mjTIMER_POS_PROJECT, // project constraints
|
||||
|
||||
mjNTIMER // number of timers
|
||||
mjNTIMER // number of timers
|
||||
} mjtTimer;
|
||||
|
||||
|
||||
//------------------------------ mjContact ----------------------------------------------
|
||||
//---------------------------------- mjContact -----------------------------------------------------
|
||||
|
||||
struct _mjContact // result of collision detection functions
|
||||
{
|
||||
// contact parameters set by geom-specific collision detector
|
||||
mjtNum dist; // distance between nearest points; neg: penetration
|
||||
mjtNum pos[3]; // position of contact point: midpoint between geoms
|
||||
mjtNum frame[9]; // normal is in [0-2]
|
||||
struct mjContact_ { // result of collision detection functions
|
||||
// contact parameters set by geom-specific collision detector
|
||||
mjtNum dist; // distance between nearest points; neg: penetration
|
||||
mjtNum pos[3]; // position of contact point: midpoint between geoms
|
||||
mjtNum frame[9]; // normal is in [0-2]
|
||||
|
||||
// contact parameters set by mj_collideGeoms
|
||||
mjtNum includemargin; // include if dist<includemargin=margin-gap
|
||||
mjtNum friction[5]; // tangent1, 2, spin, roll1, 2
|
||||
mjtNum solref[mjNREF]; // constraint solver reference
|
||||
mjtNum solimp[mjNIMP]; // constraint solver impedance
|
||||
// contact parameters set by mj_collideGeoms
|
||||
mjtNum includemargin; // include if dist<includemargin=margin-gap
|
||||
mjtNum friction[5]; // tangent1, 2, spin, roll1, 2
|
||||
mjtNum solref[mjNREF]; // constraint solver reference
|
||||
mjtNum solimp[mjNIMP]; // constraint solver impedance
|
||||
|
||||
// internal storage used by solver
|
||||
mjtNum mu; // friction of regularized cone, set by mj_makeConstraint
|
||||
mjtNum H[36]; // cone Hessian, set by mj_updateConstraint
|
||||
// internal storage used by solver
|
||||
mjtNum mu; // friction of regularized cone, set by mj_makeConstraint
|
||||
mjtNum H[36]; // cone Hessian, set by mj_updateConstraint
|
||||
|
||||
// contact descriptors set by mj_collideGeoms
|
||||
int dim; // contact space dimensionality: 1, 3, 4 or 6
|
||||
int geom1; // id of geom 1
|
||||
int geom2; // id of geom 2
|
||||
// contact descriptors set by mj_collideGeoms
|
||||
int dim; // contact space dimensionality: 1, 3, 4 or 6
|
||||
int geom1; // id of geom 1
|
||||
int geom2; // id of geom 2
|
||||
|
||||
// flag set by mj_fuseContact or mj_instantianteEquality
|
||||
int exclude; // 0: include, 1: in gap, 2: fused, 3: equality, 4: no dofs
|
||||
// flag set by mj_fuseContact or mj_instantianteEquality
|
||||
int exclude; // 0: include, 1: in gap, 2: fused, 3: equality, 4: no dofs
|
||||
|
||||
// address computed by mj_instantiateContact
|
||||
int efc_address; // address in efc; -1: not included, -2-i: distance constraint i
|
||||
// address computed by mj_instantiateContact
|
||||
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
|
||||
{
|
||||
int lastinfo; // info from last warning
|
||||
int number; // how many times was warning raised
|
||||
struct mjWarningStat_ { // warning statistics
|
||||
int lastinfo; // info from last warning
|
||||
int number; // how many times was warning raised
|
||||
};
|
||||
typedef struct _mjWarningStat mjWarningStat;
|
||||
typedef struct mjWarningStat_ mjWarningStat;
|
||||
|
||||
|
||||
struct _mjTimerStat // timer statistics
|
||||
{
|
||||
mjtNum duration; // cumulative duration
|
||||
int number; // how many times was timer called
|
||||
struct mjTimerStat_ { // timer statistics
|
||||
mjtNum duration; // cumulative duration
|
||||
int number; // how many times was timer called
|
||||
};
|
||||
typedef struct _mjTimerStat mjTimerStat;
|
||||
typedef struct mjTimerStat_ mjTimerStat;
|
||||
|
||||
|
||||
struct _mjSolverStat // per-iteration solver statistics
|
||||
{
|
||||
mjtNum improvement; // cost reduction, scaled by 1/trace(M(qpos0))
|
||||
mjtNum gradient; // gradient norm (primal only, scaled)
|
||||
mjtNum lineslope; // slope in linesearch
|
||||
int nactive; // number of active constraints
|
||||
int nchange; // number of constraint state changes
|
||||
int neval; // number of cost evaluations in line search
|
||||
int nupdate; // number of Cholesky updates in line search
|
||||
struct mjSolverStat_ { // per-iteration solver statistics
|
||||
mjtNum improvement; // cost reduction, scaled by 1/trace(M(qpos0))
|
||||
mjtNum gradient; // gradient norm (primal only, scaled)
|
||||
mjtNum lineslope; // slope in linesearch
|
||||
int nactive; // number of active constraints
|
||||
int nchange; // number of constraint state changes
|
||||
int neval; // number of cost evaluations in line search
|
||||
int nupdate; // number of Cholesky updates in line search
|
||||
};
|
||||
typedef struct _mjSolverStat mjSolverStat;
|
||||
typedef struct mjSolverStat_ mjSolverStat;
|
||||
|
||||
|
||||
//---------------------------------- mjData ---------------------------------------------
|
||||
//---------------------------------- mjData --------------------------------------------------------
|
||||
|
||||
struct _mjData
|
||||
{
|
||||
// constant sizes
|
||||
int nstack; // number of mjtNums that can fit in stack
|
||||
int nbuffer; // size of main buffer in bytes
|
||||
struct mjData_ {
|
||||
// constant sizes
|
||||
int nstack; // number of mjtNums that can fit in stack
|
||||
int nbuffer; // size of main buffer in bytes
|
||||
|
||||
// stack pointer
|
||||
int pstack; // first available mjtNum address in stack
|
||||
// stack pointer
|
||||
int pstack; // first available mjtNum address in stack
|
||||
|
||||
// memory utilization stats
|
||||
int maxuse_stack; // maximum stack allocation
|
||||
int maxuse_con; // maximum number of contacts
|
||||
int maxuse_efc; // maximum number of scalar constraints
|
||||
// memory utilization stats
|
||||
int maxuse_stack; // maximum stack allocation
|
||||
int maxuse_con; // maximum number of contacts
|
||||
int maxuse_efc; // maximum number of scalar constraints
|
||||
|
||||
// diagnostics
|
||||
mjWarningStat warning[mjNWARNING]; // warning statistics
|
||||
mjTimerStat timer[mjNTIMER]; // timer statistics
|
||||
mjSolverStat solver[mjNSOLVER]; // solver statistics per iteration
|
||||
int solver_iter; // number of solver iterations
|
||||
int solver_nnz; // number of non-zeros in Hessian or efc_AR
|
||||
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
||||
// diagnostics
|
||||
mjWarningStat warning[mjNWARNING]; // warning statistics
|
||||
mjTimerStat timer[mjNTIMER]; // timer statistics
|
||||
mjSolverStat solver[mjNSOLVER]; // solver statistics per iteration
|
||||
int solver_iter; // number of solver iterations
|
||||
int solver_nnz; // number of non-zeros in Hessian or efc_AR
|
||||
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
||||
|
||||
// variable sizes
|
||||
int ne; // number of equality constraints
|
||||
int nf; // number of friction constraints
|
||||
int nefc; // number of constraints
|
||||
int ncon; // number of detected contacts
|
||||
// variable sizes
|
||||
int ne; // number of equality constraints
|
||||
int nf; // number of friction constraints
|
||||
int nefc; // number of constraints
|
||||
int ncon; // number of detected contacts
|
||||
|
||||
// global properties
|
||||
mjtNum time; // simulation time
|
||||
mjtNum energy[2]; // potential, kinetic energy
|
||||
// global properties
|
||||
mjtNum time; // simulation time
|
||||
mjtNum energy[2]; // potential, kinetic energy
|
||||
|
||||
//-------------------------------- end of info header
|
||||
//-------------------------------- end of info header
|
||||
|
||||
// buffers
|
||||
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
||||
mjtNum* stack; // stack buffer (nstack mjtNums)
|
||||
// buffers
|
||||
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
||||
mjtNum* stack; // stack buffer (nstack mjtNums)
|
||||
|
||||
//-------------------------------- main inputs and outputs of the computation
|
||||
//-------------------------------- main inputs and outputs of the computation
|
||||
|
||||
// state
|
||||
mjtNum* qpos; // position (nq x 1)
|
||||
mjtNum* qvel; // velocity (nv x 1)
|
||||
mjtNum* act; // actuator activation (na x 1)
|
||||
mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1)
|
||||
// state
|
||||
mjtNum* qpos; // position (nq x 1)
|
||||
mjtNum* qvel; // velocity (nv x 1)
|
||||
mjtNum* act; // actuator activation (na x 1)
|
||||
mjtNum* qacc_warmstart; // acceleration used for warmstart (nv x 1)
|
||||
|
||||
// control
|
||||
mjtNum* ctrl; // control (nu x 1)
|
||||
mjtNum* qfrc_applied; // applied generalized force (nv x 1)
|
||||
mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6)
|
||||
// control
|
||||
mjtNum* ctrl; // control (nu x 1)
|
||||
mjtNum* qfrc_applied; // applied generalized force (nv x 1)
|
||||
mjtNum* xfrc_applied; // applied Cartesian force/torque (nbody x 6)
|
||||
|
||||
// dynamics
|
||||
mjtNum* qacc; // acceleration (nv x 1)
|
||||
mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
|
||||
// dynamics
|
||||
mjtNum* qacc; // acceleration (nv x 1)
|
||||
mjtNum* act_dot; // time-derivative of actuator activation (na x 1)
|
||||
|
||||
// mocap data
|
||||
mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3)
|
||||
mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4)
|
||||
// mocap data
|
||||
mjtNum* mocap_pos; // positions of mocap bodies (nmocap x 3)
|
||||
mjtNum* mocap_quat; // orientations of mocap bodies (nmocap x 4)
|
||||
|
||||
// user data
|
||||
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
|
||||
// user data
|
||||
mjtNum* userdata; // user data, not touched by engine (nuserdata x 1)
|
||||
|
||||
// sensors
|
||||
mjtNum* sensordata; // sensor data array (nsensordata x 1)
|
||||
// sensors
|
||||
mjtNum* sensordata; // sensor data array (nsensordata x 1)
|
||||
|
||||
//-------------------------------- POSITION dependent
|
||||
//-------------------------------- POSITION dependent
|
||||
|
||||
// computed by mj_fwdPosition/mj_kinematics
|
||||
mjtNum* xpos; // Cartesian position of body frame (nbody x 3)
|
||||
mjtNum* xquat; // Cartesian orientation of body frame (nbody x 4)
|
||||
mjtNum* xmat; // Cartesian orientation of body frame (nbody x 9)
|
||||
mjtNum* xipos; // Cartesian position of body com (nbody x 3)
|
||||
mjtNum* ximat; // Cartesian orientation of body inertia (nbody x 9)
|
||||
mjtNum* xanchor; // Cartesian position of joint anchor (njnt x 3)
|
||||
mjtNum* xaxis; // Cartesian joint axis (njnt x 3)
|
||||
mjtNum* geom_xpos; // Cartesian geom position (ngeom x 3)
|
||||
mjtNum* geom_xmat; // Cartesian geom orientation (ngeom x 9)
|
||||
mjtNum* site_xpos; // Cartesian site position (nsite x 3)
|
||||
mjtNum* site_xmat; // Cartesian site orientation (nsite x 9)
|
||||
mjtNum* cam_xpos; // Cartesian camera position (ncam x 3)
|
||||
mjtNum* cam_xmat; // Cartesian camera orientation (ncam x 9)
|
||||
mjtNum* light_xpos; // Cartesian light position (nlight x 3)
|
||||
mjtNum* light_xdir; // Cartesian light direction (nlight x 3)
|
||||
// computed by mj_fwdPosition/mj_kinematics
|
||||
mjtNum* xpos; // Cartesian position of body frame (nbody x 3)
|
||||
mjtNum* xquat; // Cartesian orientation of body frame (nbody x 4)
|
||||
mjtNum* xmat; // Cartesian orientation of body frame (nbody x 9)
|
||||
mjtNum* xipos; // Cartesian position of body com (nbody x 3)
|
||||
mjtNum* ximat; // Cartesian orientation of body inertia (nbody x 9)
|
||||
mjtNum* xanchor; // Cartesian position of joint anchor (njnt x 3)
|
||||
mjtNum* xaxis; // Cartesian joint axis (njnt x 3)
|
||||
mjtNum* geom_xpos; // Cartesian geom position (ngeom x 3)
|
||||
mjtNum* geom_xmat; // Cartesian geom orientation (ngeom x 9)
|
||||
mjtNum* site_xpos; // Cartesian site position (nsite x 3)
|
||||
mjtNum* site_xmat; // Cartesian site orientation (nsite x 9)
|
||||
mjtNum* cam_xpos; // Cartesian camera position (ncam x 3)
|
||||
mjtNum* cam_xmat; // Cartesian camera orientation (ncam x 9)
|
||||
mjtNum* light_xpos; // Cartesian light position (nlight x 3)
|
||||
mjtNum* light_xdir; // Cartesian light direction (nlight x 3)
|
||||
|
||||
// computed by mj_fwdPosition/mj_comPos
|
||||
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* cinert; // com-based body inertia and mass (nbody x 10)
|
||||
// computed by mj_fwdPosition/mj_comPos
|
||||
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* cinert; // com-based body inertia and mass (nbody x 10)
|
||||
|
||||
// computed by mj_fwdPosition/mj_tendon
|
||||
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_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_colind; // column indices in sparse Jacobian (ntendon x nv)
|
||||
mjtNum* ten_length; // tendon lengths (ntendon x 1)
|
||||
mjtNum* ten_J; // tendon Jacobian (ntendon x nv)
|
||||
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)
|
||||
// computed by mj_fwdPosition/mj_tendon
|
||||
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_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_colind; // column indices in sparse Jacobian (ntendon x nv)
|
||||
mjtNum* ten_length; // tendon lengths (ntendon x 1)
|
||||
mjtNum* ten_J; // tendon Jacobian (ntendon x nv)
|
||||
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)
|
||||
|
||||
// computed by mj_fwdPosition/mj_transmission
|
||||
mjtNum* actuator_length; // actuator lengths (nu x 1)
|
||||
mjtNum* actuator_moment; // actuator moments (nu x nv)
|
||||
// computed by mj_fwdPosition/mj_transmission
|
||||
mjtNum* actuator_length; // actuator lengths (nu x 1)
|
||||
mjtNum* actuator_moment; // actuator moments (nu x nv)
|
||||
|
||||
// computed by mj_fwdPosition/mj_crb
|
||||
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
|
||||
mjtNum* qM; // total inertia (nM x 1)
|
||||
// computed by mj_fwdPosition/mj_crb
|
||||
mjtNum* crb; // com-based composite inertia and mass (nbody x 10)
|
||||
mjtNum* qM; // total inertia (nM x 1)
|
||||
|
||||
// computed by mj_fwdPosition/mj_factorM
|
||||
mjtNum* qLD; // L'*D*L factorization of M (nM x 1)
|
||||
mjtNum* qLDiagInv; // 1/diag(D) (nv x 1)
|
||||
mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1)
|
||||
// computed by mj_fwdPosition/mj_factorM
|
||||
mjtNum* qLD; // L'*D*L factorization of M (nM x 1)
|
||||
mjtNum* qLDiagInv; // 1/diag(D) (nv x 1)
|
||||
mjtNum* qLDiagSqrtInv; // 1/sqrt(diag(D)) (nv x 1)
|
||||
|
||||
// computed by mj_fwdPosition/mj_collision
|
||||
mjContact* contact; // list of all detected contacts (nconmax x 1)
|
||||
// computed by mj_fwdPosition/mj_collision
|
||||
mjContact* contact; // list of all detected contacts (nconmax x 1)
|
||||
|
||||
// computed by mj_fwdPosition/mj_makeConstraint
|
||||
int* efc_type; // constraint type (mjtConstraint) (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_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_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_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_colind; // column indices in Jacobian T (nv x njmax)
|
||||
mjtNum* efc_J; // constraint Jacobian (njmax x nv)
|
||||
mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax)
|
||||
mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1)
|
||||
mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1)
|
||||
mjtNum* efc_frictionloss; // frictionloss (friction) (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_D; // constraint mass (njmax x 1)
|
||||
mjtNum* efc_R; // inverse constraint mass (njmax x 1)
|
||||
// computed by mj_fwdPosition/mj_makeConstraint
|
||||
int* efc_type; // constraint type (mjtConstraint) (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_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_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_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_colind; // column indices in Jacobian T (nv x njmax)
|
||||
mjtNum* efc_J; // constraint Jacobian (njmax x nv)
|
||||
mjtNum* efc_JT; // constraint Jacobian transposed (nv x njmax)
|
||||
mjtNum* efc_pos; // constraint position (equality, contact) (njmax x 1)
|
||||
mjtNum* efc_margin; // inclusion margin (contact) (njmax x 1)
|
||||
mjtNum* efc_frictionloss; // frictionloss (friction) (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_D; // constraint mass (njmax x 1)
|
||||
mjtNum* efc_R; // inverse constraint mass (njmax x 1)
|
||||
|
||||
// computed by mj_fwdPosition/mj_projectConstraint
|
||||
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_colind; // column indices in sparse AR (njmax x njmax)
|
||||
mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax)
|
||||
// computed by mj_fwdPosition/mj_projectConstraint
|
||||
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_colind; // column indices in sparse AR (njmax x njmax)
|
||||
mjtNum* efc_AR; // J*inv(M)*J' + R (njmax x njmax)
|
||||
|
||||
//-------------------------------- POSITION, VELOCITY dependent
|
||||
//-------------------------------- POSITION, VELOCITY dependent
|
||||
|
||||
// computed by mj_fwdVelocity
|
||||
mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
|
||||
mjtNum* actuator_velocity; // actuator velocities (nu x 1)
|
||||
// computed by mj_fwdVelocity
|
||||
mjtNum* ten_velocity; // tendon velocities (ntendon x 1)
|
||||
mjtNum* actuator_velocity; // actuator velocities (nu x 1)
|
||||
|
||||
// computed by mj_fwdVelocity/mj_comVel
|
||||
mjtNum* cvel; // com-based velocity [3D rot; 3D tran] (nbody x 6)
|
||||
mjtNum* cdof_dot; // time-derivative of cdof (nv x 6)
|
||||
// computed by mj_fwdVelocity/mj_comVel
|
||||
mjtNum* cvel; // com-based velocity [3D rot; 3D tran] (nbody x 6)
|
||||
mjtNum* cdof_dot; // time-derivative of cdof (nv x 6)
|
||||
|
||||
// computed by mj_fwdVelocity/mj_rne (without acceleration)
|
||||
mjtNum* qfrc_bias; // C(qpos,qvel) (nv x 1)
|
||||
// computed by mj_fwdVelocity/mj_rne (without acceleration)
|
||||
mjtNum* qfrc_bias; // C(qpos,qvel) (nv x 1)
|
||||
|
||||
// computed by mj_fwdVelocity/mj_passive
|
||||
mjtNum* qfrc_passive; // passive force (nv x 1)
|
||||
// computed by mj_fwdVelocity/mj_passive
|
||||
mjtNum* qfrc_passive; // passive force (nv x 1)
|
||||
|
||||
// computed by mj_fwdVelocity/mj_referenceConstraint
|
||||
mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1)
|
||||
mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1)
|
||||
// computed by mj_fwdVelocity/mj_referenceConstraint
|
||||
mjtNum* efc_vel; // velocity in constraint space: J*qvel (njmax x 1)
|
||||
mjtNum* efc_aref; // reference pseudo-acceleration (njmax x 1)
|
||||
|
||||
// computed by mj_sensorVel/mj_subtreeVel if needed
|
||||
mjtNum* subtree_linvel; // linear velocity of subtree com (nbody x 3)
|
||||
mjtNum* subtree_angmom; // angular momentum about subtree com (nbody x 3)
|
||||
// computed by mj_sensorVel/mj_subtreeVel if needed
|
||||
mjtNum* subtree_linvel; // linear velocity of 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
|
||||
mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
|
||||
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||
// computed by mj_fwdActuation
|
||||
mjtNum* actuator_force; // actuator force in actuation space (nu x 1)
|
||||
mjtNum* qfrc_actuator; // actuator force (nv x 1)
|
||||
|
||||
// computed by mj_fwdAcceleration
|
||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
||||
// computed by mj_fwdAcceleration
|
||||
mjtNum* qfrc_unc; // net unconstrained force (nv x 1)
|
||||
mjtNum* qacc_unc; // unconstrained acceleration (nv x 1)
|
||||
|
||||
// computed by mj_fwdConstraint/mj_inverse
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
|
||||
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||
// computed by mj_fwdConstraint/mj_inverse
|
||||
mjtNum* efc_b; // linear cost term: J*qacc_unc - aref (njmax x 1)
|
||||
mjtNum* efc_force; // constraint force in constraint space (njmax x 1)
|
||||
int* efc_state; // constraint state (mjtConstraintState) (njmax x 1)
|
||||
mjtNum* qfrc_constraint; // constraint force (nv x 1)
|
||||
|
||||
// computed by mj_inverse
|
||||
mjtNum* qfrc_inverse; // net external force; should equal: (nv x 1)
|
||||
// qfrc_applied + J'*xfrc_applied + qfrc_actuator
|
||||
// computed by mj_inverse
|
||||
mjtNum* qfrc_inverse; // net external force; should equal: (nv x 1)
|
||||
// qfrc_applied + J'*xfrc_applied + qfrc_actuator
|
||||
|
||||
// computed by mj_sensorAcc/mj_rnePostConstraint if needed; rotation:translation format
|
||||
mjtNum* cacc; // com-based acceleration (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)
|
||||
// computed by mj_sensorAcc/mj_rnePostConstraint if needed; rotation:translation format
|
||||
mjtNum* cacc; // com-based acceleration (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)
|
||||
};
|
||||
typedef struct _mjData mjData;
|
||||
typedef struct mjData_ mjData;
|
||||
|
||||
|
||||
//---------------------------------- callback function types ----------------------------
|
||||
//---------------------------------- callback function types ---------------------------------------
|
||||
|
||||
// generic MuJoCo function
|
||||
typedef void (*mjfGeneric)(const mjModel* m, mjData* d);
|
||||
|
||||
Executable → Regular
+733
-770
File diff suppressed because it is too large
Load Diff
Executable → Regular
+103
-103
@@ -15,137 +15,137 @@
|
||||
#ifndef MUJOCO_MJRENDER_H_
|
||||
#define MUJOCO_MJRENDER_H_
|
||||
|
||||
#define mjNAUX 10 // number of auxiliary buffers
|
||||
#define mjMAXTEXTURE 1000 // maximum number of textures
|
||||
#include "mjmodel.h"
|
||||
|
||||
#define mjNAUX 10 // number of auxiliary buffers
|
||||
#define mjMAXTEXTURE 1000 // maximum number of textures
|
||||
|
||||
|
||||
typedef enum _mjtGridPos // grid position for overlay
|
||||
{
|
||||
mjGRID_TOPLEFT = 0, // top left
|
||||
mjGRID_TOPRIGHT, // top right
|
||||
mjGRID_BOTTOMLEFT, // bottom left
|
||||
mjGRID_BOTTOMRIGHT // bottom right
|
||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||
|
||||
typedef enum mjtGridPos_ { // grid position for overlay
|
||||
mjGRID_TOPLEFT = 0, // top left
|
||||
mjGRID_TOPRIGHT, // top right
|
||||
mjGRID_BOTTOMLEFT, // bottom left
|
||||
mjGRID_BOTTOMRIGHT // bottom right
|
||||
} mjtGridPos;
|
||||
|
||||
|
||||
typedef enum _mjtFramebuffer // OpenGL framebuffer option
|
||||
{
|
||||
mjFB_WINDOW = 0, // default/window buffer
|
||||
mjFB_OFFSCREEN // offscreen buffer
|
||||
typedef enum mjtFramebuffer_ { // OpenGL framebuffer option
|
||||
mjFB_WINDOW = 0, // default/window buffer
|
||||
mjFB_OFFSCREEN // offscreen buffer
|
||||
} mjtFramebuffer;
|
||||
|
||||
|
||||
typedef enum _mjtFontScale // font scale, used at context creation
|
||||
{
|
||||
mjFONTSCALE_50 = 50, // 50% scale, suitable for low-res rendering
|
||||
mjFONTSCALE_100 = 100, // normal scale, suitable in the absence of DPI scaling
|
||||
mjFONTSCALE_150 = 150, // 150% scale
|
||||
mjFONTSCALE_200 = 200, // 200% scale
|
||||
mjFONTSCALE_250 = 250, // 250% scale
|
||||
mjFONTSCALE_300 = 300 // 300% scale
|
||||
typedef enum mjtFontScale_ { // font scale, used at context creation
|
||||
mjFONTSCALE_50 = 50, // 50% scale, suitable for low-res rendering
|
||||
mjFONTSCALE_100 = 100, // normal scale, suitable in the absence of DPI scaling
|
||||
mjFONTSCALE_150 = 150, // 150% scale
|
||||
mjFONTSCALE_200 = 200, // 200% scale
|
||||
mjFONTSCALE_250 = 250, // 250% scale
|
||||
mjFONTSCALE_300 = 300 // 300% scale
|
||||
} mjtFontScale;
|
||||
|
||||
|
||||
typedef enum _mjtFont // font type, used at each text operation
|
||||
{
|
||||
mjFONT_NORMAL = 0, // normal font
|
||||
mjFONT_SHADOW, // normal font with shadow (for higher contrast)
|
||||
mjFONT_BIG // big font (for user alerts)
|
||||
typedef enum mjtFont_ { // font type, used at each text operation
|
||||
mjFONT_NORMAL = 0, // normal font
|
||||
mjFONT_SHADOW, // normal font with shadow (for higher contrast)
|
||||
mjFONT_BIG // big font (for user alerts)
|
||||
} mjtFont;
|
||||
|
||||
|
||||
struct _mjrRect // OpenGL rectangle
|
||||
{
|
||||
int left; // left (usually 0)
|
||||
int bottom; // bottom (usually 0)
|
||||
int width; // width (usually buffer width)
|
||||
int height; // height (usually buffer height)
|
||||
struct mjrRect_ { // OpenGL rectangle
|
||||
int left; // left (usually 0)
|
||||
int bottom; // bottom (usually 0)
|
||||
int width; // width (usually buffer width)
|
||||
int height; // height (usually buffer height)
|
||||
};
|
||||
typedef struct _mjrRect mjrRect;
|
||||
typedef struct mjrRect_ mjrRect;
|
||||
|
||||
|
||||
struct _mjrContext // custom OpenGL context
|
||||
{
|
||||
// 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
|
||||
//---------------------------------- mjrContext ----------------------------------------------------
|
||||
|
||||
// parameters specified at creation
|
||||
int fontScale; // font scale
|
||||
int auxWidth[mjNAUX]; // auxiliary buffer width
|
||||
int auxHeight[mjNAUX]; // auxiliary buffer height
|
||||
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
||||
struct mjrContext_ { // custom OpenGL context
|
||||
// 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
|
||||
|
||||
// offscreen rendering objects
|
||||
unsigned int offFBO; // offscreen framebuffer object
|
||||
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
|
||||
// parameters specified at creation
|
||||
int fontScale; // font scale
|
||||
int auxWidth[mjNAUX]; // auxiliary buffer width
|
||||
int auxHeight[mjNAUX]; // auxiliary buffer height
|
||||
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
||||
|
||||
// shadow rendering objects
|
||||
unsigned int shadowFBO; // shadow map framebuffer object
|
||||
unsigned int shadowTex; // shadow map texture
|
||||
// offscreen rendering objects
|
||||
unsigned int offFBO; // offscreen framebuffer object
|
||||
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
|
||||
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
||||
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
||||
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
||||
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
|
||||
// shadow rendering objects
|
||||
unsigned int shadowFBO; // shadow map framebuffer object
|
||||
unsigned int shadowTex; // shadow map texture
|
||||
|
||||
// texture objects and info
|
||||
int ntexture; // number of allocated textures
|
||||
int textureType[100]; // type of texture (mjtTexture)
|
||||
unsigned int texture[100]; // texture names
|
||||
// auxiliary buffers
|
||||
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
||||
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
||||
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
||||
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
|
||||
|
||||
// displaylist starting positions
|
||||
unsigned int basePlane; // all planes from model
|
||||
unsigned int baseMesh; // all meshes from model
|
||||
unsigned int baseHField; // all hfields from model
|
||||
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
|
||||
// texture objects and info
|
||||
int ntexture; // number of allocated textures
|
||||
int textureType[100]; // type of texture (mjtTexture)
|
||||
unsigned int texture[100]; // texture names
|
||||
|
||||
// displaylist ranges
|
||||
int rangePlane; // all planes from model
|
||||
int rangeMesh; // all meshes from model
|
||||
int rangeHField; // all hfields from model
|
||||
int rangeBuiltin; // all builtin geoms, with quality from model
|
||||
int rangeFont; // all characters in font
|
||||
// displaylist starting positions
|
||||
unsigned int basePlane; // all planes from model
|
||||
unsigned int baseMesh; // all meshes from model
|
||||
unsigned int baseHField; // all hfields from model
|
||||
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
|
||||
|
||||
// skin VBOs
|
||||
int nskin; // number of skins
|
||||
unsigned int* skinvertVBO; // skin vertex position VBOs
|
||||
unsigned int* skinnormalVBO; // skin vertex normal VBOs
|
||||
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs
|
||||
unsigned int* skinfaceVBO; // skin face index VBOs
|
||||
// displaylist ranges
|
||||
int rangePlane; // all planes from model
|
||||
int rangeMesh; // all meshes from model
|
||||
int rangeHField; // all hfields from model
|
||||
int rangeBuiltin; // all builtin geoms, with quality from model
|
||||
int rangeFont; // all characters in font
|
||||
|
||||
// character info
|
||||
int charWidth[127]; // character widths: normal and shadow
|
||||
int charWidthBig[127]; // chacarter widths: big
|
||||
int charHeight; // character heights: normal and shadow
|
||||
int charHeightBig; // character heights: big
|
||||
// skin VBOs
|
||||
int nskin; // number of skins
|
||||
unsigned int* skinvertVBO; // skin vertex position VBOs
|
||||
unsigned int* skinnormalVBO; // skin vertex normal VBOs
|
||||
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs
|
||||
unsigned int* skinfaceVBO; // skin face index VBOs
|
||||
|
||||
// capabilities
|
||||
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
|
||||
// character info
|
||||
int charWidth[127]; // character widths: normal and shadow
|
||||
int charWidthBig[127]; // chacarter widths: big
|
||||
int charHeight; // character heights: normal and shadow
|
||||
int charHeightBig; // character heights: big
|
||||
|
||||
// framebuffer
|
||||
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
|
||||
// capabilities
|
||||
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_
|
||||
|
||||
Executable → Regular
+195
-192
@@ -15,6 +15,8 @@
|
||||
#ifndef MUJOCO_MJUI_H_
|
||||
#define MUJOCO_MJUI_H_
|
||||
|
||||
#include "mjrender.h"
|
||||
|
||||
#define mjMAXUISECT 10 // maximum number of sections
|
||||
#define mjMAXUIITEM 80 // maximum number of items per section
|
||||
#define mjMAXUITEXT 300 // maximum number of chars in edittext and other
|
||||
@@ -55,48 +57,47 @@
|
||||
#define mjKEY_F12 301
|
||||
|
||||
|
||||
typedef enum _mjtButton // mouse button
|
||||
{
|
||||
mjBUTTON_NONE = 0, // no button
|
||||
mjBUTTON_LEFT, // left button
|
||||
mjBUTTON_RIGHT, // right button
|
||||
mjBUTTON_MIDDLE // middle button
|
||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||
|
||||
typedef enum mjtButton_ { // mouse button
|
||||
mjBUTTON_NONE = 0, // no button
|
||||
mjBUTTON_LEFT, // left button
|
||||
mjBUTTON_RIGHT, // right button
|
||||
mjBUTTON_MIDDLE // middle button
|
||||
} mjtButton;
|
||||
|
||||
|
||||
typedef enum _mjtEvent // mouse and keyboard event type
|
||||
{
|
||||
mjEVENT_NONE = 0, // no event
|
||||
mjEVENT_MOVE, // mouse move
|
||||
mjEVENT_PRESS, // mouse button press
|
||||
mjEVENT_RELEASE, // mouse button release
|
||||
mjEVENT_SCROLL, // scroll
|
||||
mjEVENT_KEY, // key press
|
||||
mjEVENT_RESIZE // resize
|
||||
typedef enum mjtEvent_ { // mouse and keyboard event type
|
||||
mjEVENT_NONE = 0, // no event
|
||||
mjEVENT_MOVE, // mouse move
|
||||
mjEVENT_PRESS, // mouse button press
|
||||
mjEVENT_RELEASE, // mouse button release
|
||||
mjEVENT_SCROLL, // scroll
|
||||
mjEVENT_KEY, // key press
|
||||
mjEVENT_RESIZE // resize
|
||||
} mjtEvent;
|
||||
|
||||
|
||||
typedef enum _mjtItem // UI item type
|
||||
{
|
||||
mjITEM_END = -2, // end of definition list (not an item)
|
||||
mjITEM_SECTION = -1, // section (not an item)
|
||||
mjITEM_SEPARATOR = 0, // separator
|
||||
mjITEM_STATIC, // static text
|
||||
mjITEM_BUTTON, // button
|
||||
typedef enum mjtItem_ { // UI item type
|
||||
mjITEM_END = -2, // end of definition list (not an item)
|
||||
mjITEM_SECTION = -1, // section (not an item)
|
||||
mjITEM_SEPARATOR = 0, // separator
|
||||
mjITEM_STATIC, // static text
|
||||
mjITEM_BUTTON, // button
|
||||
|
||||
// the rest have data pointer
|
||||
mjITEM_CHECKINT, // check box, int value
|
||||
mjITEM_CHECKBYTE, // check box, mjtByte value
|
||||
mjITEM_RADIO, // radio group
|
||||
mjITEM_RADIOLINE, // radio group, single line
|
||||
mjITEM_SELECT, // selection box
|
||||
mjITEM_SLIDERINT, // slider, int value
|
||||
mjITEM_SLIDERNUM, // slider, mjtNum value
|
||||
mjITEM_EDITINT, // editable array, int values
|
||||
mjITEM_EDITNUM, // editable array, mjtNum values
|
||||
mjITEM_EDITTXT, // editable text
|
||||
// the rest have data pointer
|
||||
mjITEM_CHECKINT, // check box, int value
|
||||
mjITEM_CHECKBYTE, // check box, mjtByte value
|
||||
mjITEM_RADIO, // radio group
|
||||
mjITEM_RADIOLINE, // radio group, single line
|
||||
mjITEM_SELECT, // selection box
|
||||
mjITEM_SLIDERINT, // slider, int value
|
||||
mjITEM_SLIDERNUM, // slider, mjtNum value
|
||||
mjITEM_EDITINT, // editable array, int values
|
||||
mjITEM_EDITNUM, // editable array, mjtNum values
|
||||
mjITEM_EDITTXT, // editable text
|
||||
|
||||
mjNITEM // number of item types
|
||||
mjNITEM // number of item types
|
||||
} mjtItem;
|
||||
|
||||
|
||||
@@ -104,206 +105,208 @@ typedef enum _mjtItem // UI item type
|
||||
typedef int (*mjfItemEnable)(int category, void* data);
|
||||
|
||||
|
||||
struct _mjuiState // mouse and keyboard state
|
||||
{
|
||||
// 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)
|
||||
//---------------------------------- mjuiState -----------------------------------------------------
|
||||
|
||||
// event type
|
||||
int type; // (type mjtEvent)
|
||||
struct mjuiState_ { // mouse and keyboard state
|
||||
// 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
|
||||
int left; // is left button down
|
||||
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
|
||||
// event type
|
||||
int type; // (type mjtEvent)
|
||||
|
||||
// mouse position
|
||||
double x; // x position
|
||||
double y; // y position
|
||||
double dx; // x displacement
|
||||
double dy; // y displacement
|
||||
double sx; // x scroll
|
||||
double sy; // y scroll
|
||||
// mouse buttons
|
||||
int left; // is left button down
|
||||
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
|
||||
|
||||
// keyboard
|
||||
int control; // is control down
|
||||
int shift; // is shift down
|
||||
int alt; // is alt down
|
||||
int key; // which key was pressed
|
||||
double keytime; // time of last key press
|
||||
// mouse position
|
||||
double x; // x position
|
||||
double y; // y position
|
||||
double dx; // x displacement
|
||||
double dy; // y displacement
|
||||
double sx; // x scroll
|
||||
double sy; // y scroll
|
||||
|
||||
// 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)
|
||||
// keyboard
|
||||
int control; // is control down
|
||||
int shift; // is shift down
|
||||
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
|
||||
{
|
||||
int total; // total width
|
||||
int scroll; // scrollbar width
|
||||
int label; // label width
|
||||
int section; // section gap
|
||||
int itemside; // item side gap
|
||||
int itemmid; // item middle gap
|
||||
int itemver; // item vertical gap
|
||||
int texthor; // text horizontal gap
|
||||
int textver; // text vertical gap
|
||||
int linescroll; // number of pixels to scroll
|
||||
int samples; // number of multisamples
|
||||
//---------------------------------- mjuiThemeSpacing ----------------------------------------------
|
||||
|
||||
struct mjuiThemeSpacing_ { // UI visualization theme spacing
|
||||
int total; // total width
|
||||
int scroll; // scrollbar width
|
||||
int label; // label width
|
||||
int section; // section gap
|
||||
int itemside; // item side gap
|
||||
int itemmid; // item middle gap
|
||||
int itemver; // item vertical gap
|
||||
int texthor; // text horizontal gap
|
||||
int textver; // text vertical gap
|
||||
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
|
||||
{
|
||||
float master[3]; // master background
|
||||
float thumb[3]; // scrollbar thumb
|
||||
float secttitle[3]; // section title
|
||||
float sectfont[3]; // section font
|
||||
float sectsymbol[3]; // section symbol
|
||||
float sectpane[3]; // section pane
|
||||
float shortcut[3]; // shortcut background
|
||||
float fontactive[3]; // font active
|
||||
float fontinactive[3]; // font inactive
|
||||
float decorinactive[3]; // decor inactive
|
||||
float decorinactive2[3]; // inactive slider color 2
|
||||
float button[3]; // button
|
||||
float check[3]; // check
|
||||
float radio[3]; // radio
|
||||
float select[3]; // select
|
||||
float select2[3]; // select pane
|
||||
float slider[3]; // slider
|
||||
float slider2[3]; // slider color 2
|
||||
float edit[3]; // edit
|
||||
float edit2[3]; // edit invalid
|
||||
float cursor[3]; // edit cursor
|
||||
//---------------------------------- mjuiThemeColor ------------------------------------------------
|
||||
|
||||
struct mjuiThemeColor_ { // UI visualization theme color
|
||||
float master[3]; // master background
|
||||
float thumb[3]; // scrollbar thumb
|
||||
float secttitle[3]; // section title
|
||||
float sectfont[3]; // section font
|
||||
float sectsymbol[3]; // section symbol
|
||||
float sectpane[3]; // section pane
|
||||
float shortcut[3]; // shortcut background
|
||||
float fontactive[3]; // font active
|
||||
float fontinactive[3]; // font inactive
|
||||
float decorinactive[3]; // decor inactive
|
||||
float decorinactive2[3]; // inactive slider color 2
|
||||
float button[3]; // button
|
||||
float check[3]; // check
|
||||
float radio[3]; // radio
|
||||
float select[3]; // select
|
||||
float select2[3]; // select pane
|
||||
float slider[3]; // slider
|
||||
float slider2[3]; // slider color 2
|
||||
float edit[3]; // edit
|
||||
float edit2[3]; // edit invalid
|
||||
float cursor[3]; // edit cursor
|
||||
};
|
||||
typedef struct _mjuiThemeColor mjuiThemeColor;
|
||||
typedef struct mjuiThemeColor_ mjuiThemeColor;
|
||||
|
||||
|
||||
struct _mjuiItemSingle // check and button-related
|
||||
{
|
||||
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
||||
int shortcut; // shortcut key; 0: undefined
|
||||
//---------------------------------- mjuiItem ------------------------------------------------------
|
||||
|
||||
struct mjuiItemSingle_ { // check and button-related
|
||||
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
||||
int shortcut; // shortcut key; 0: undefined
|
||||
};
|
||||
|
||||
|
||||
struct _mjuiItemMulti // static, radio and select-related
|
||||
{
|
||||
int nelem; // number of elements in group
|
||||
char name[mjMAXUIMULTI][mjMAXUINAME]; // element names
|
||||
struct mjuiItemMulti_ { // static, radio and select-related
|
||||
int nelem; // number of elements in group
|
||||
char name[mjMAXUIMULTI][mjMAXUINAME]; // element names
|
||||
};
|
||||
|
||||
|
||||
struct _mjuiItemSlider // slider-related
|
||||
{
|
||||
double range[2]; // slider range
|
||||
double divisions; // number of range divisions
|
||||
struct mjuiItemSlider_ { // slider-related
|
||||
double range[2]; // slider range
|
||||
double divisions; // number of range divisions
|
||||
};
|
||||
|
||||
|
||||
struct _mjuiItemEdit // edit-related
|
||||
{
|
||||
int nelem; // number of elements in list
|
||||
double range[mjMAXUIEDIT][2]; // element range (min>=max: ignore)
|
||||
struct mjuiItemEdit_ { // edit-related
|
||||
int nelem; // number of elements in list
|
||||
double range[mjMAXUIEDIT][2]; // element range (min>=max: ignore)
|
||||
};
|
||||
|
||||
|
||||
struct _mjuiItem // UI item
|
||||
{
|
||||
// common properties
|
||||
int type; // type (mjtItem)
|
||||
char name[mjMAXUINAME]; // name
|
||||
int state; // 0: disable, 1: enable, 2+: use predicate
|
||||
void *pdata; // data pointer (type-specific)
|
||||
int sectionid; // id of section containing item
|
||||
int itemid; // id of item within section
|
||||
struct mjuiItem_ { // UI item
|
||||
// common properties
|
||||
int type; // type (mjtItem)
|
||||
char name[mjMAXUINAME]; // name
|
||||
int state; // 0: disable, 1: enable, 2+: use predicate
|
||||
void *pdata; // data pointer (type-specific)
|
||||
int sectionid; // id of section containing item
|
||||
int itemid; // id of item within section
|
||||
|
||||
// type-specific properties
|
||||
union
|
||||
{
|
||||
struct _mjuiItemSingle single; // check and button
|
||||
struct _mjuiItemMulti multi; // static, radio and select
|
||||
struct _mjuiItemSlider slider; // slider
|
||||
struct _mjuiItemEdit edit; // edit
|
||||
};
|
||||
// type-specific properties
|
||||
union {
|
||||
struct mjuiItemSingle_ single; // check and button
|
||||
struct mjuiItemMulti_ multi; // static, radio and select
|
||||
struct mjuiItemSlider_ slider; // slider
|
||||
struct mjuiItemEdit_ edit; // edit
|
||||
};
|
||||
|
||||
// internal
|
||||
mjrRect rect; // rectangle occupied by item
|
||||
// internal
|
||||
mjrRect rect; // rectangle occupied by item
|
||||
};
|
||||
typedef struct _mjuiItem mjuiItem;
|
||||
typedef struct mjuiItem_ mjuiItem;
|
||||
|
||||
|
||||
struct _mjuiSection // UI section
|
||||
{
|
||||
// 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
|
||||
//---------------------------------- mjuiSection ---------------------------------------------------
|
||||
|
||||
// internal
|
||||
mjrRect rtitle; // rectangle occupied by title
|
||||
mjrRect rcontent; // rectangle occupied by content
|
||||
struct mjuiSection_ { // UI section
|
||||
// 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
|
||||
mjrRect rtitle; // rectangle occupied by title
|
||||
mjrRect rcontent; // rectangle occupied by content
|
||||
};
|
||||
typedef struct _mjuiSection mjuiSection;
|
||||
typedef struct mjuiSection_ mjuiSection;
|
||||
|
||||
|
||||
struct _mjUI // entire UI
|
||||
{
|
||||
// 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)
|
||||
//---------------------------------- mjUI ----------------------------------------------------------
|
||||
|
||||
// UI sizes (framebuffer units)
|
||||
int width; // width
|
||||
int height; // current heigth
|
||||
int maxheight; // height when all sections open
|
||||
int scroll; // scroll from top of UI
|
||||
struct mjUI_ { // entire UI
|
||||
// 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)
|
||||
|
||||
// mouse focus
|
||||
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
||||
int mouseitem; // item within section
|
||||
int mousehelp; // help button down: print shortcuts
|
||||
// UI sizes (framebuffer units)
|
||||
int width; // width
|
||||
int height; // current heigth
|
||||
int maxheight; // height when all sections open
|
||||
int scroll; // scroll from top of UI
|
||||
|
||||
// keyboard focus and edit
|
||||
int editsect; // 0: none, otherwise 1+section
|
||||
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
|
||||
// mouse focus
|
||||
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
||||
int mouseitem; // item within section
|
||||
int mousehelp; // help button down: print shortcuts
|
||||
|
||||
// sections
|
||||
int nsect; // number of sections in use
|
||||
mjuiSection sect[mjMAXUISECT]; // preallocated array of sections
|
||||
// keyboard focus and edit
|
||||
int editsect; // 0: none, otherwise 1+section
|
||||
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()
|
||||
{
|
||||
int type; // type (mjtItem); -1: section
|
||||
char name[mjMAXUINAME]; // name
|
||||
int state; // state
|
||||
void* pdata; // pointer to data
|
||||
char other[mjMAXUITEXT]; // string with type-specific properties
|
||||
//---------------------------------- mjuiDef -------------------------------------------------------
|
||||
|
||||
struct mjuiDef_ { // table passed to mjui_add()
|
||||
int type; // type (mjtItem); -1: section
|
||||
char name[mjMAXUINAME]; // name
|
||||
int state; // state
|
||||
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_
|
||||
|
||||
Executable → Regular
+264
-261
@@ -15,336 +15,339 @@
|
||||
#ifndef MUJOCO_MJVISUALIZE_H_
|
||||
#define MUJOCO_MJVISUALIZE_H_
|
||||
|
||||
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
|
||||
#define mjMAXOVERLAY 500 // maximum number of characters in overlay text
|
||||
#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
|
||||
#include "mjmodel.h"
|
||||
|
||||
#define mjNGROUP 6 // number of geom, site, joint groups with visflags
|
||||
#define mjMAXOVERLAY 500 // maximum number of characters in overlay text
|
||||
#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
|
||||
{
|
||||
mjCAT_STATIC = 1, // model elements in body 0
|
||||
mjCAT_DYNAMIC = 2, // model elements in all other bodies
|
||||
mjCAT_DECOR = 4, // decorative geoms
|
||||
mjCAT_ALL = 7 // select all categories
|
||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||
|
||||
typedef enum mjtCatBit_ { // bitflags for mjvGeom category
|
||||
mjCAT_STATIC = 1, // model elements in body 0
|
||||
mjCAT_DYNAMIC = 2, // model elements in all other bodies
|
||||
mjCAT_DECOR = 4, // decorative geoms
|
||||
mjCAT_ALL = 7 // select all categories
|
||||
} mjtCatBit;
|
||||
|
||||
|
||||
typedef enum _mjtMouse // mouse interaction mode
|
||||
{
|
||||
mjMOUSE_NONE = 0, // no action
|
||||
mjMOUSE_ROTATE_V, // rotate, vertical plane
|
||||
mjMOUSE_ROTATE_H, // rotate, horizontal plane
|
||||
mjMOUSE_MOVE_V, // move, vertical plane
|
||||
mjMOUSE_MOVE_H, // move, horizontal plane
|
||||
mjMOUSE_ZOOM, // zoom
|
||||
mjMOUSE_SELECT // selection
|
||||
typedef enum mjtMouse_ { // mouse interaction mode
|
||||
mjMOUSE_NONE = 0, // no action
|
||||
mjMOUSE_ROTATE_V, // rotate, vertical plane
|
||||
mjMOUSE_ROTATE_H, // rotate, horizontal plane
|
||||
mjMOUSE_MOVE_V, // move, vertical plane
|
||||
mjMOUSE_MOVE_H, // move, horizontal plane
|
||||
mjMOUSE_ZOOM, // zoom
|
||||
mjMOUSE_SELECT // selection
|
||||
} mjtMouse;
|
||||
|
||||
|
||||
typedef enum _mjtPertBit // mouse perturbations
|
||||
{
|
||||
mjPERT_TRANSLATE = 1, // translation
|
||||
mjPERT_ROTATE = 2 // rotation
|
||||
typedef enum mjtPertBit_ { // mouse perturbations
|
||||
mjPERT_TRANSLATE = 1, // translation
|
||||
mjPERT_ROTATE = 2 // rotation
|
||||
} mjtPertBit;
|
||||
|
||||
|
||||
typedef enum _mjtCamera // abstract camera type
|
||||
{
|
||||
mjCAMERA_FREE = 0, // free camera
|
||||
mjCAMERA_TRACKING, // tracking camera; uses trackbodyid
|
||||
mjCAMERA_FIXED, // fixed camera; uses fixedcamid
|
||||
mjCAMERA_USER // user is responsible for setting OpenGL camera
|
||||
typedef enum mjtCamera_ { // abstract camera type
|
||||
mjCAMERA_FREE = 0, // free camera
|
||||
mjCAMERA_TRACKING, // tracking camera; uses trackbodyid
|
||||
mjCAMERA_FIXED, // fixed camera; uses fixedcamid
|
||||
mjCAMERA_USER // user is responsible for setting OpenGL camera
|
||||
} mjtCamera;
|
||||
|
||||
|
||||
typedef enum _mjtLabel // object labeling
|
||||
{
|
||||
mjLABEL_NONE = 0, // nothing
|
||||
mjLABEL_BODY, // body labels
|
||||
mjLABEL_JOINT, // joint labels
|
||||
mjLABEL_GEOM, // geom labels
|
||||
mjLABEL_SITE, // site labels
|
||||
mjLABEL_CAMERA, // camera labels
|
||||
mjLABEL_LIGHT, // light labels
|
||||
mjLABEL_TENDON, // tendon labels
|
||||
mjLABEL_ACTUATOR, // actuator labels
|
||||
mjLABEL_CONSTRAINT, // constraint labels
|
||||
mjLABEL_SKIN, // skin labels
|
||||
mjLABEL_SELECTION, // selected object
|
||||
mjLABEL_SELPNT, // coordinates of selection point
|
||||
mjLABEL_CONTACTFORCE, // magnitude of contact force
|
||||
typedef enum mjtLabel_ { // object labeling
|
||||
mjLABEL_NONE = 0, // nothing
|
||||
mjLABEL_BODY, // body labels
|
||||
mjLABEL_JOINT, // joint labels
|
||||
mjLABEL_GEOM, // geom labels
|
||||
mjLABEL_SITE, // site labels
|
||||
mjLABEL_CAMERA, // camera labels
|
||||
mjLABEL_LIGHT, // light labels
|
||||
mjLABEL_TENDON, // tendon labels
|
||||
mjLABEL_ACTUATOR, // actuator labels
|
||||
mjLABEL_CONSTRAINT, // constraint labels
|
||||
mjLABEL_SKIN, // skin labels
|
||||
mjLABEL_SELECTION, // selected object
|
||||
mjLABEL_SELPNT, // coordinates of selection point
|
||||
mjLABEL_CONTACTFORCE, // magnitude of contact force
|
||||
|
||||
mjNLABEL // number of label types
|
||||
mjNLABEL // number of label types
|
||||
} mjtLabel;
|
||||
|
||||
|
||||
typedef enum _mjtFrame // frame visualization
|
||||
{
|
||||
mjFRAME_NONE = 0, // no frames
|
||||
mjFRAME_BODY, // body frames
|
||||
mjFRAME_GEOM, // geom frames
|
||||
mjFRAME_SITE, // site frames
|
||||
mjFRAME_CAMERA, // camera frames
|
||||
mjFRAME_LIGHT, // light frames
|
||||
mjFRAME_WORLD, // world frame
|
||||
typedef enum mjtFrame_ { // frame visualization
|
||||
mjFRAME_NONE = 0, // no frames
|
||||
mjFRAME_BODY, // body frames
|
||||
mjFRAME_GEOM, // geom frames
|
||||
mjFRAME_SITE, // site frames
|
||||
mjFRAME_CAMERA, // camera frames
|
||||
mjFRAME_LIGHT, // light frames
|
||||
mjFRAME_WORLD, // world frame
|
||||
|
||||
mjNFRAME // number of visualization frames
|
||||
mjNFRAME // number of visualization frames
|
||||
} mjtFrame;
|
||||
|
||||
|
||||
typedef enum _mjtVisFlag // flags enabling model element visualization
|
||||
{
|
||||
mjVIS_CONVEXHULL = 0, // mesh convex hull
|
||||
mjVIS_TEXTURE, // textures
|
||||
mjVIS_JOINT, // joints
|
||||
mjVIS_ACTUATOR, // actuators
|
||||
mjVIS_CAMERA, // cameras
|
||||
mjVIS_LIGHT, // lights
|
||||
mjVIS_TENDON, // tendons
|
||||
mjVIS_RANGEFINDER, // rangefinder sensors
|
||||
mjVIS_CONSTRAINT, // point constraints
|
||||
mjVIS_INERTIA, // equivalent inertia boxes
|
||||
mjVIS_SCLINERTIA, // scale equivalent inertia boxes with mass
|
||||
mjVIS_PERTFORCE, // perturbation force
|
||||
mjVIS_PERTOBJ, // perturbation object
|
||||
mjVIS_CONTACTPOINT, // contact points
|
||||
mjVIS_CONTACTFORCE, // contact force
|
||||
mjVIS_CONTACTSPLIT, // split contact force into normal and tanget
|
||||
mjVIS_TRANSPARENT, // make dynamic geoms more transparent
|
||||
mjVIS_AUTOCONNECT, // auto connect joints and body coms
|
||||
mjVIS_COM, // center of mass
|
||||
mjVIS_SELECT, // selection point
|
||||
mjVIS_STATIC, // static bodies
|
||||
mjVIS_SKIN, // skin
|
||||
typedef enum mjtVisFlag_ { // flags enabling model element visualization
|
||||
mjVIS_CONVEXHULL = 0, // mesh convex hull
|
||||
mjVIS_TEXTURE, // textures
|
||||
mjVIS_JOINT, // joints
|
||||
mjVIS_ACTUATOR, // actuators
|
||||
mjVIS_CAMERA, // cameras
|
||||
mjVIS_LIGHT, // lights
|
||||
mjVIS_TENDON, // tendons
|
||||
mjVIS_RANGEFINDER, // rangefinder sensors
|
||||
mjVIS_CONSTRAINT, // point constraints
|
||||
mjVIS_INERTIA, // equivalent inertia boxes
|
||||
mjVIS_SCLINERTIA, // scale equivalent inertia boxes with mass
|
||||
mjVIS_PERTFORCE, // perturbation force
|
||||
mjVIS_PERTOBJ, // perturbation object
|
||||
mjVIS_CONTACTPOINT, // contact points
|
||||
mjVIS_CONTACTFORCE, // contact force
|
||||
mjVIS_CONTACTSPLIT, // split contact force into normal and tanget
|
||||
mjVIS_TRANSPARENT, // make dynamic geoms more transparent
|
||||
mjVIS_AUTOCONNECT, // auto connect joints and body coms
|
||||
mjVIS_COM, // center of mass
|
||||
mjVIS_SELECT, // selection point
|
||||
mjVIS_STATIC, // static bodies
|
||||
mjVIS_SKIN, // skin
|
||||
|
||||
mjNVISFLAG // number of visualization flags
|
||||
mjNVISFLAG // number of visualization flags
|
||||
} mjtVisFlag;
|
||||
|
||||
|
||||
typedef enum _mjtRndFlag // flags enabling rendering effects
|
||||
{
|
||||
mjRND_SHADOW = 0, // shadows
|
||||
mjRND_WIREFRAME, // wireframe
|
||||
mjRND_REFLECTION, // reflections
|
||||
mjRND_ADDITIVE, // additive transparency
|
||||
mjRND_SKYBOX, // skybox
|
||||
mjRND_FOG, // fog
|
||||
mjRND_HAZE, // haze
|
||||
mjRND_SEGMENT, // segmentation with random color
|
||||
mjRND_IDCOLOR, // segmentation with segid color
|
||||
typedef enum mjtRndFlag_ { // flags enabling rendering effects
|
||||
mjRND_SHADOW = 0, // shadows
|
||||
mjRND_WIREFRAME, // wireframe
|
||||
mjRND_REFLECTION, // reflections
|
||||
mjRND_ADDITIVE, // additive transparency
|
||||
mjRND_SKYBOX, // skybox
|
||||
mjRND_FOG, // fog
|
||||
mjRND_HAZE, // haze
|
||||
mjRND_SEGMENT, // segmentation with random color
|
||||
mjRND_IDCOLOR, // segmentation with segid color
|
||||
|
||||
mjNRNDFLAG // number of rendering flags
|
||||
mjNRNDFLAG // number of rendering flags
|
||||
} mjtRndFlag;
|
||||
|
||||
|
||||
typedef enum _mjtStereo // type of stereo rendering
|
||||
{
|
||||
mjSTEREO_NONE = 0, // no stereo; use left eye only
|
||||
mjSTEREO_QUADBUFFERED, // quad buffered; revert to side-by-side if no hardware support
|
||||
mjSTEREO_SIDEBYSIDE // side-by-side
|
||||
typedef enum mjtStereo_ { // type of stereo rendering
|
||||
mjSTEREO_NONE = 0, // no stereo; use left eye only
|
||||
mjSTEREO_QUADBUFFERED, // quad buffered; revert to side-by-side if no hardware support
|
||||
mjSTEREO_SIDEBYSIDE // side-by-side
|
||||
} mjtStereo;
|
||||
|
||||
|
||||
struct _mjvPerturb // object selection and perturbation
|
||||
{
|
||||
int select; // selected body id; non-positive: none
|
||||
int skinselect; // selected skin id; negative: none
|
||||
int active; // perturbation bitmask (mjtPertBit)
|
||||
int active2; // secondary perturbation bitmask (mjtPertBit)
|
||||
mjtNum refpos[3]; // desired position for selected object
|
||||
mjtNum refquat[4]; // desired orientation for selected object
|
||||
mjtNum localpos[3]; // selection point in object coordinates
|
||||
mjtNum scale; // relative mouse motion-to-space scaling (set by initPerturb)
|
||||
//---------------------------------- mjvPerturb ----------------------------------------------------
|
||||
|
||||
struct mjvPerturb_ { // object selection and perturbation
|
||||
int select; // selected body id; non-positive: none
|
||||
int skinselect; // selected skin id; negative: none
|
||||
int active; // perturbation bitmask (mjtPertBit)
|
||||
int active2; // secondary perturbation bitmask (mjtPertBit)
|
||||
mjtNum refpos[3]; // desired position for selected object
|
||||
mjtNum refquat[4]; // desired orientation for selected object
|
||||
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
|
||||
{
|
||||
// type and ids
|
||||
int type; // camera type (mjtCamera)
|
||||
int fixedcamid; // fixed camera id
|
||||
int trackbodyid; // body id to track
|
||||
//---------------------------------- mjvCamera -----------------------------------------------------
|
||||
|
||||
// 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)
|
||||
struct mjvCamera_ { // abstract camera
|
||||
// type and ids
|
||||
int type; // camera type (mjtCamera)
|
||||
int fixedcamid; // fixed camera id
|
||||
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
|
||||
{
|
||||
// camera frame
|
||||
float pos[3]; // position
|
||||
float forward[3]; // forward direction
|
||||
float up[3]; // up direction
|
||||
//---------------------------------- mjvGLCamera ---------------------------------------------------
|
||||
|
||||
// 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
|
||||
struct mjvGLCamera_ { // OpenGL camera
|
||||
// camera frame
|
||||
float pos[3]; // position
|
||||
float forward[3]; // forward direction
|
||||
float up[3]; // up direction
|
||||
|
||||
// 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
|
||||
{
|
||||
// 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
|
||||
//---------------------------------- mjvGeom -------------------------------------------------------
|
||||
|
||||
// OpenGL info
|
||||
float texrepeat[2]; // texture repetition for 2D mapping
|
||||
float size[3]; // size parameters
|
||||
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
|
||||
struct mjvGeom_ { // abstract geom
|
||||
// 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
|
||||
|
||||
// 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
|
||||
// OpenGL info
|
||||
float texrepeat[2]; // texture repetition for 2D mapping
|
||||
float size[3]; // size parameters
|
||||
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
|
||||
{
|
||||
float pos[3]; // position rel. to body frame
|
||||
float dir[3]; // direction rel. to body frame
|
||||
float attenuation[3]; // OpenGL attenuation (quadratic model)
|
||||
float cutoff; // OpenGL cutoff
|
||||
float exponent; // OpenGL exponent
|
||||
float ambient[3]; // ambient rgb (alpha=1)
|
||||
float diffuse[3]; // diffuse rgb (alpha=1)
|
||||
float specular[3]; // specular rgb (alpha=1)
|
||||
mjtByte headlight; // headlight
|
||||
mjtByte directional; // directional light
|
||||
mjtByte castshadow; // does light cast shadows
|
||||
//---------------------------------- mjvLight ------------------------------------------------------
|
||||
|
||||
struct mjvLight_ { // OpenGL light
|
||||
float pos[3]; // position rel. to body frame
|
||||
float dir[3]; // direction rel. to body frame
|
||||
float attenuation[3]; // OpenGL attenuation (quadratic model)
|
||||
float cutoff; // OpenGL cutoff
|
||||
float exponent; // OpenGL exponent
|
||||
float ambient[3]; // ambient rgb (alpha=1)
|
||||
float diffuse[3]; // diffuse rgb (alpha=1)
|
||||
float specular[3]; // specular rgb (alpha=1)
|
||||
mjtByte headlight; // headlight
|
||||
mjtByte directional; // directional light
|
||||
mjtByte castshadow; // does light cast shadows
|
||||
};
|
||||
typedef struct _mjvLight mjvLight;
|
||||
typedef struct mjvLight_ mjvLight;
|
||||
|
||||
|
||||
struct _mjvOption // abstract visualization options
|
||||
{
|
||||
int label; // what objects to label (mjtLabel)
|
||||
int frame; // which frame to show (mjtFrame)
|
||||
mjtByte geomgroup[mjNGROUP]; // geom visualization by group
|
||||
mjtByte sitegroup[mjNGROUP]; // site visualization by group
|
||||
mjtByte jointgroup[mjNGROUP]; // joint visualization by group
|
||||
mjtByte tendongroup[mjNGROUP]; // tendon visualization by group
|
||||
mjtByte actuatorgroup[mjNGROUP]; // actuator visualization by group
|
||||
mjtByte flags[mjNVISFLAG]; // visualization flags (indexed by mjtVisFlag)
|
||||
//---------------------------------- mjvOption -----------------------------------------------------
|
||||
|
||||
struct mjvOption_ { // abstract visualization options
|
||||
int label; // what objects to label (mjtLabel)
|
||||
int frame; // which frame to show (mjtFrame)
|
||||
mjtByte geomgroup[mjNGROUP]; // geom visualization by group
|
||||
mjtByte sitegroup[mjNGROUP]; // site visualization by group
|
||||
mjtByte jointgroup[mjNGROUP]; // joint visualization by group
|
||||
mjtByte tendongroup[mjNGROUP]; // tendon visualization by group
|
||||
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
|
||||
{
|
||||
// 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
|
||||
//---------------------------------- mjvScene ------------------------------------------------------
|
||||
|
||||
// skin data
|
||||
int nskin; // number of skins
|
||||
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
|
||||
struct mjvScene_ { // abstract scene passed to OpenGL renderer
|
||||
// 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
|
||||
|
||||
// OpenGL lights
|
||||
int nlight; // number of lights currently in buffer
|
||||
mjvLight lights[8]; // buffer for lights
|
||||
// skin data
|
||||
int nskin; // number of skins
|
||||
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
|
||||
mjvGLCamera camera[2]; // left and right camera
|
||||
// OpenGL lights
|
||||
int nlight; // number of lights currently in buffer
|
||||
mjvLight lights[8]; // buffer for lights
|
||||
|
||||
// OpenGL model transformation
|
||||
mjtByte enabletransform; // enable model transformation
|
||||
float translate[3]; // model translation
|
||||
float rotate[4]; // model quaternion rotation
|
||||
float scale; // model scaling
|
||||
// OpenGL cameras
|
||||
mjvGLCamera camera[2]; // left and right camera
|
||||
|
||||
// OpenGL rendering effects
|
||||
int stereo; // stereoscopic rendering (mjtStereo)
|
||||
mjtByte flags[mjNRNDFLAG]; // rendering flags (indexed by mjtRndFlag)
|
||||
// OpenGL model transformation
|
||||
mjtByte enabletransform; // enable model transformation
|
||||
float translate[3]; // model translation
|
||||
float rotate[4]; // model quaternion rotation
|
||||
float scale; // model scaling
|
||||
|
||||
// framing
|
||||
int framewidth; // frame pixel width; 0: disable framing
|
||||
float framergb[3]; // frame color
|
||||
// OpenGL rendering effects
|
||||
int stereo; // stereoscopic rendering (mjtStereo)
|
||||
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
|
||||
{
|
||||
// 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
|
||||
//---------------------------------- mjvFigure -----------------------------------------------------
|
||||
|
||||
// style settings
|
||||
float linewidth; // line width
|
||||
float gridwidth; // grid line width
|
||||
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
|
||||
struct mjvFigure_ { // abstract 2D figure passed to OpenGL renderer
|
||||
// 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
|
||||
|
||||
// text labels
|
||||
char title[1000]; // figure title; subplots separated with 2+ spaces
|
||||
char xlabel[100]; // x-axis label
|
||||
char linename[mjMAXLINE][100]; // line names for legend
|
||||
// style settings
|
||||
float linewidth; // line width
|
||||
float gridwidth; // grid line width
|
||||
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
|
||||
int legendoffset; // number of lines to offset legend
|
||||
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
|
||||
// text labels
|
||||
char title[1000]; // figure title; subplots separated with 2+ spaces
|
||||
char xlabel[100]; // x-axis label
|
||||
char linename[mjMAXLINE][100]; // line names for legend
|
||||
|
||||
// line data
|
||||
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
||||
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
||||
// dynamic settings
|
||||
int legendoffset; // number of lines to offset legend
|
||||
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
|
||||
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
|
||||
// line data
|
||||
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
||||
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
||||
|
||||
// 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_
|
||||
|
||||
Executable → Regular
+32
-1
@@ -18,7 +18,7 @@
|
||||
//-------------------------------- mjOption ---------------------------------------------
|
||||
|
||||
// scalar fields of mjOption
|
||||
#define MJOPTION_SCALARS \
|
||||
#define MJOPTION_FLOATS \
|
||||
X( mjtNum, timestep ) \
|
||||
X( mjtNum, apirate ) \
|
||||
X( mjtNum, impratio ) \
|
||||
@@ -28,6 +28,9 @@
|
||||
X( mjtNum, density ) \
|
||||
X( mjtNum, viscosity ) \
|
||||
X( mjtNum, o_margin ) \
|
||||
|
||||
|
||||
#define MJOPTION_INTS \
|
||||
X( int, integrator ) \
|
||||
X( int, collision ) \
|
||||
X( int, cone ) \
|
||||
@@ -40,6 +43,11 @@
|
||||
X( int, enableflags )
|
||||
|
||||
|
||||
#define MJOPTION_SCALARS \
|
||||
MJOPTION_FLOATS \
|
||||
MJOPTION_INTS
|
||||
|
||||
|
||||
// vector fields of mjOption
|
||||
#define MJOPTION_VECTORS \
|
||||
X( gravity, 3 ) \
|
||||
@@ -113,6 +121,23 @@
|
||||
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
|
||||
#define MJMODEL_POINTERS \
|
||||
X( mjtNum, qpos0, nq, 1 ) \
|
||||
@@ -386,6 +411,12 @@
|
||||
|
||||
//-------------------------------- 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
|
||||
#define MJDATA_POINTERS \
|
||||
X( mjtNum, qpos, nq, 1 ) \
|
||||
|
||||
Executable → Regular
+62
-65
@@ -15,27 +15,16 @@
|
||||
#ifndef MUJOCO_MUJOCO_H_
|
||||
#define MUJOCO_MUJOCO_H_
|
||||
|
||||
// cross-platform import
|
||||
#if defined(MJ_STATIC)
|
||||
#define MJAPI
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
#define MJAPI __declspec(dllimport)
|
||||
#else
|
||||
#define MJAPI
|
||||
#endif
|
||||
#endif
|
||||
#include "mujoco_export.h"
|
||||
|
||||
|
||||
// this is a C-API
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#include "stdlib.h"
|
||||
@@ -89,7 +78,7 @@ MJAPI extern const char* mjVISSTRING[mjNVISFLAG][3];
|
||||
MJAPI extern const char* mjRNDSTRING[mjNRNDFLAG][3];
|
||||
|
||||
|
||||
//---------------------- Activation -----------------------------------------------------
|
||||
//---------------------------------- Activation ----------------------------------------------------
|
||||
|
||||
// Return 1 (for backward compatibility).
|
||||
MJAPI int mj_activate(const char* filename);
|
||||
@@ -98,7 +87,7 @@ MJAPI int mj_activate(const char* filename);
|
||||
MJAPI void mj_deactivate(void);
|
||||
|
||||
|
||||
//---------------------- Virtual file system --------------------------------------------
|
||||
//---------------------------------- Virtual file system -------------------------------------------
|
||||
|
||||
// Initialize VFS to empty (no deallocation).
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Parse and compile ----------------------------------------------
|
||||
//---------------------------------- Parse and compile ---------------------------------------------
|
||||
|
||||
// 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.
|
||||
@@ -140,7 +129,7 @@ MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz,
|
||||
int flg_html, int flg_pad);
|
||||
|
||||
|
||||
//---------------------- Main simulation ------------------------------------------------
|
||||
//---------------------------------- Main simulation -----------------------------------------------
|
||||
|
||||
// Advance simulation, use control callback to obtain external force and control.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Initialization -------------------------------------------------
|
||||
//---------------------------------- Initialization ------------------------------------------------
|
||||
|
||||
// Set default options for length range computation.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- 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.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Components -----------------------------------------------------
|
||||
//---------------------------------- Components ----------------------------------------------------
|
||||
|
||||
// Run position-dependent computations.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Sub components -------------------------------------------------
|
||||
//---------------------------------- Sub components ------------------------------------------------
|
||||
|
||||
// Evaluate position-dependent sensors.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Support --------------------------------------------------------
|
||||
//---------------------------------- Support -------------------------------------------------------
|
||||
|
||||
// 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);
|
||||
@@ -473,8 +467,11 @@ MJAPI void mj_setTotalmass(mjModel* m, mjtNum newmass);
|
||||
// Return version number: 1.0.2 is encoded as 102.
|
||||
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.
|
||||
// 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);
|
||||
|
||||
|
||||
//---------------------- Interaction ----------------------------------------------------
|
||||
//---------------------------------- Interaction ---------------------------------------------------
|
||||
|
||||
// Set default camera.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Visualization --------------------------------------------------
|
||||
//---------------------------------- Visualization -------------------------------------------------
|
||||
|
||||
// Set default visualization options.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- OpenGL rendering -----------------------------------------------
|
||||
//---------------------------------- OpenGL rendering ----------------------------------------------
|
||||
|
||||
// Set default mjrContext.
|
||||
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.
|
||||
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,
|
||||
const mjrContext* con);
|
||||
const mjrContext* con);
|
||||
|
||||
// Draw 2D figure.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- UI framework ---------------------------------------------------
|
||||
//---------------------------------- UI framework --------------------------------------------------
|
||||
|
||||
// Get builtin UI theme spacing (ind: 0-1).
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Error and memory -----------------------------------------------
|
||||
//---------------------------------- Error and memory ----------------------------------------------
|
||||
|
||||
// Main error function; does not return to caller.
|
||||
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);
|
||||
|
||||
|
||||
//---------------------- Standard math --------------------------------------------------
|
||||
//---------------------------------- Standard math -------------------------------------------------
|
||||
|
||||
#define mjMAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define mjMIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#ifdef mjUSEDOUBLE
|
||||
#define mju_sqrt sqrt
|
||||
#define mju_exp exp
|
||||
#define mju_sin sin
|
||||
#define mju_cos cos
|
||||
#define mju_tan tan
|
||||
#define mju_asin asin
|
||||
#define mju_acos acos
|
||||
#define mju_atan2 atan2
|
||||
#define mju_tanh tanh
|
||||
#define mju_pow pow
|
||||
#define mju_abs fabs
|
||||
#define mju_log log
|
||||
#define mju_log10 log10
|
||||
#define mju_floor floor
|
||||
#define mju_ceil ceil
|
||||
#define mju_sqrt sqrt
|
||||
#define mju_exp exp
|
||||
#define mju_sin sin
|
||||
#define mju_cos cos
|
||||
#define mju_tan tan
|
||||
#define mju_asin asin
|
||||
#define mju_acos acos
|
||||
#define mju_atan2 atan2
|
||||
#define mju_tanh tanh
|
||||
#define mju_pow pow
|
||||
#define mju_abs fabs
|
||||
#define mju_log log
|
||||
#define mju_log10 log10
|
||||
#define mju_floor floor
|
||||
#define mju_ceil ceil
|
||||
|
||||
#else
|
||||
#define mju_sqrt sqrtf
|
||||
#define mju_exp expf
|
||||
#define mju_sin sinf
|
||||
#define mju_cos cosf
|
||||
#define mju_tan tanf
|
||||
#define mju_asin asinf
|
||||
#define mju_acos acosf
|
||||
#define mju_atan2 atan2f
|
||||
#define mju_tanh tanhf
|
||||
#define mju_pow powf
|
||||
#define mju_abs fabsf
|
||||
#define mju_log logf
|
||||
#define mju_log10 log10f
|
||||
#define mju_floor floorf
|
||||
#define mju_ceil ceilf
|
||||
#define mju_sqrt sqrtf
|
||||
#define mju_exp expf
|
||||
#define mju_sin sinf
|
||||
#define mju_cos cosf
|
||||
#define mju_tan tanf
|
||||
#define mju_asin asinf
|
||||
#define mju_acos acosf
|
||||
#define mju_atan2 atan2f
|
||||
#define mju_tanh tanhf
|
||||
#define mju_pow powf
|
||||
#define mju_abs fabsf
|
||||
#define mju_log logf
|
||||
#define mju_log10 log10f
|
||||
#define mju_floor floorf
|
||||
#define mju_ceil ceilf
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------ Vector math --------------------------------------------
|
||||
//---------------------------------- Vector math ---------------------------------------------------
|
||||
|
||||
// Set res = 0.
|
||||
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]);
|
||||
|
||||
|
||||
//---------------------- Quaternions ----------------------------------------------------
|
||||
//---------------------------------- Quaternions ---------------------------------------------------
|
||||
|
||||
// Rotate vector by quaternion.
|
||||
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]);
|
||||
|
||||
|
||||
//---------------------- Poses ----------------------------------------------------------
|
||||
//---------------------------------- Poses ---------------------------------------------------------
|
||||
|
||||
// Multiply two poses.
|
||||
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]);
|
||||
|
||||
|
||||
//---------------------- Decompositions --------------------------------------------------
|
||||
//--------------------------------- Decompositions -------------------------------------------------
|
||||
|
||||
// Cholesky decomposition: mat = L*L'; return rank.
|
||||
MJAPI int mju_cholFactor(mjtNum* mat, int n, mjtNum mindiag);
|
||||
|
||||
@@ -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
@@ -14,23 +14,22 @@
|
||||
-->
|
||||
|
||||
<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">
|
||||
<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>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -14,17 +14,16 @@
|
||||
-->
|
||||
|
||||
<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">
|
||||
<skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
<geom size=".02"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
<worldbody>
|
||||
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
||||
<skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
<geom size=".02"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
+12
-13
@@ -14,20 +14,19 @@
|
||||
-->
|
||||
|
||||
<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">
|
||||
<freejoint/>
|
||||
<composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
<worldbody>
|
||||
<body name="B0" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="loop" count="20 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
@@ -14,20 +14,32 @@
|
||||
-->
|
||||
|
||||
<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>
|
||||
<map stiffness="100"/>
|
||||
</visual>
|
||||
<default>
|
||||
<default class="wall">
|
||||
<geom type="plane" size=".5 .5 .05"/>
|
||||
</default>
|
||||
</default>
|
||||
|
||||
<worldbody>
|
||||
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
<worldbody>
|
||||
<geom name="+x" class="wall" zaxis="1 0 0" pos="-.5 0 -.25"/>
|
||||
<geom name="-x" class="wall" zaxis="-1 0 0" pos=".5 0 -.25"/>
|
||||
<geom name="+y" class="wall" zaxis="0 1 0" pos="0 -.5 -.25"/>
|
||||
<geom name="-y" class="wall" zaxis="0 -1 0" pos="0 .5 -.25"/>
|
||||
<composite type="particle" count="10 10 10" spacing="0.07" offset="0 0 1">
|
||||
<geom size=".025" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
+12
-13
@@ -14,20 +14,19 @@
|
||||
-->
|
||||
|
||||
<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">
|
||||
<freejoint/>
|
||||
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
<worldbody>
|
||||
<body name="B10" pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
|
||||
<joint kind="main" damping="0.005"/>
|
||||
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
+28
-28
@@ -14,39 +14,39 @@
|
||||
-->
|
||||
|
||||
<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>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="2048"/>
|
||||
<map stiffness="700" shadowscale="0.5" fogstart="10" fogend="15" zfar="40" haze="0.3"/>
|
||||
</visual>
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
|
||||
width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
|
||||
<texture name="texcarpet" type="2d" file="carpet.png"/>
|
||||
<texture name="texsponge" type="2d" file="sponge.png"/>
|
||||
<texture name="texmarble" type="cube" file="marble.png"/>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
|
||||
width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
|
||||
<texture name="texcarpet" type="2d" file="carpet.png"/>
|
||||
<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"/>
|
||||
<material name="matcarpet" texture="texcarpet"/>
|
||||
<material name="matsponge" texture="texsponge" specular="0.3"/>
|
||||
<material name="matmarble" texture="texmarble" rgba=".7 .7 .7 1"/>
|
||||
</asset>
|
||||
|
||||
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
|
||||
<material name="matcarpet" texture="texcarpet"/>
|
||||
<material name="matsponge" texture="texsponge" specular="0.3"/>
|
||||
<material name="matmarble" texture="texmarble" rgba=".7 .7 .7 1"/>
|
||||
</asset>
|
||||
<worldbody>
|
||||
<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"/>
|
||||
|
||||
<worldbody>
|
||||
<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"/>
|
||||
|
||||
<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>
|
||||
</worldbody>
|
||||
<body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1">
|
||||
<geom type="capsule" size=".1 .1" material="matmarble" group="1" condim="1"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
+17
-13
@@ -14,20 +14,24 @@
|
||||
-->
|
||||
|
||||
<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">
|
||||
<freejoint/>
|
||||
<composite type="box" count="7 7 7" spacing="0.04">
|
||||
<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>
|
||||
<worldbody>
|
||||
<body pos="0 0 1">
|
||||
<freejoint/>
|
||||
<composite type="box" count="7 7 7" spacing="0.04">
|
||||
<skin texcoord="true" material="matsponge" rgba=".7 .7 .7 1"/>
|
||||
<geom type="capsule" size=".015 0.05" rgba=".8 .2 .1 1"/>
|
||||
<joint kind="main" solreffix="0.03 1" solimpfix="0 .1 .01"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -14,152 +14,50 @@
|
||||
-->
|
||||
|
||||
<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>
|
||||
<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"/>
|
||||
|
||||
<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>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="2048"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="plane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2"
|
||||
width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
|
||||
<texture name="hammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1"
|
||||
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>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<include file="humanoid_body.xml"/>
|
||||
|
||||
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
|
||||
|
||||
<texture name="texhammock" type="2d" builtin="checker" rgb1=".1 .5 .1" rgb2=".5 .1 .1" width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
|
||||
|
||||
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
|
||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||
|
||||
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
|
||||
<material name="mathammock" texture="texhammock"/>
|
||||
|
||||
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
||||
</asset>
|
||||
|
||||
<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>
|
||||
<worldbody>
|
||||
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="plane" condim="3"/>
|
||||
<light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
|
||||
<light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4" dir="0 0 -1"/>
|
||||
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
|
||||
<skin texcoord="true" material="hammock" 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>
|
||||
</worldbody>
|
||||
|
||||
</mujoco>
|
||||
|
||||
Executable
+157
@@ -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
@@ -14,136 +14,152 @@
|
||||
-->
|
||||
|
||||
<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>
|
||||
<joint limited="true" damping="1" armature="0"/>
|
||||
<geom condim="1" material="matgeom"/>
|
||||
<motor ctrlrange="-.4 .4" ctrllimited="true"/>
|
||||
<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>
|
||||
|
||||
<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"/>
|
||||
|
||||
<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>
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
|
||||
|
||||
<texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
|
||||
|
||||
<texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
|
||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
|
||||
|
||||
<material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
|
||||
|
||||
<material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
||||
</asset>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="matplane" condim="3"/>
|
||||
|
||||
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
|
||||
<light mode="targetbodycom" target="torso" directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/>
|
||||
|
||||
<body name="torso" pos="0 0 1.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>
|
||||
<worldbody>
|
||||
<geom name="floor" size="0 0 .05" type="plane" material="grid" condim="3"/>
|
||||
<light name="spotlight" mode="targetbodycom" target="torso"
|
||||
diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 -20 4" cutoff="10"/>
|
||||
<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 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 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>
|
||||
</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>
|
||||
</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>
|
||||
|
||||
+460
-540
File diff suppressed because it is too large
Load Diff
Executable
+158
@@ -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
@@ -14,108 +14,107 @@
|
||||
-->
|
||||
|
||||
<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>
|
||||
<rgba haze=".3 .3 .3 1"/>
|
||||
</visual>
|
||||
<default>
|
||||
<joint type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="0 120" damping="0.1"/>
|
||||
<muscle ctrllimited="true" ctrlrange="0 1"/>
|
||||
</default>
|
||||
|
||||
<default>
|
||||
<joint type="hinge" pos="0 0 0" axis="0 0 1" limited="true" range="0 120" damping="0.1"/>
|
||||
<muscle ctrllimited="true" ctrlrange="0 1"/>
|
||||
</default>
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1="0.6 0.6 0.6" rgb2="0 0 0" width="512" height="512"/>
|
||||
|
||||
<asset>
|
||||
<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"/>
|
||||
|
||||
<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"/>
|
||||
</asset>
|
||||
<worldbody>
|
||||
<geom name="floor" pos="0 0 -0.5" size="0 0 1" type="plane" material="matplane"/>
|
||||
|
||||
<worldbody>
|
||||
<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"/>
|
||||
|
||||
<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"/>
|
||||
<site name="x0" pos="0 -0.15 0" size="0.02" rgba="0 .7 0 1" group="1"/>
|
||||
<body pos="0 0 0">
|
||||
<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">
|
||||
<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"/>
|
||||
<site name="s1" pos="0.15 0.06 0" size="0.02"/>
|
||||
<site name="s2" pos="0.15 -0.06 0" size="0.02"/>
|
||||
<site name="s3" pos="0.4 0.06 0" size="0.02"/>
|
||||
<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"/>
|
||||
<site name="s2" pos="0.15 -0.06 0" size="0.02"/>
|
||||
<site name="s3" pos="0.4 0.06 0" size="0.02"/>
|
||||
<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"/>
|
||||
<body pos="0.5 0 0">
|
||||
<geom name="forearm" type="capsule" size="0.035" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
|
||||
<joint name="elbow"/>
|
||||
<geom name="elbow" type="cylinder" pos="0 0 0" size=".08 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
|
||||
|
||||
<body pos="0.5 0 0">
|
||||
<geom name="forearm" type="capsule" size="0.035" fromto="0 0 0 0.5 0 0" rgba=".5 .1 .1 1"/>
|
||||
<joint name="elbow"/>
|
||||
<geom name="elbow" type="cylinder" pos="0 0 0" size=".08 .05" rgba=".5 .1 .8 .5" mass="0" group="1"/>
|
||||
<site name="s7" pos="0.11 0.05 0" size="0.02"/>
|
||||
<site name="s8" pos="0.11 -0.05 0" size="0.02"/>
|
||||
</body>
|
||||
</body>
|
||||
</worldbody>
|
||||
|
||||
<site name="s7" pos="0.11 0.05 0" size="0.02"/>
|
||||
<site name="s8" pos="0.11 -0.05 0" size="0.02"/>
|
||||
</body>
|
||||
</body>
|
||||
</worldbody>
|
||||
<tendon>
|
||||
<spatial name="SF" width="0.01">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder"/>
|
||||
<site site="s1"/>
|
||||
</spatial>
|
||||
|
||||
<tendon>
|
||||
<spatial name="SF" width="0.01">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder"/>
|
||||
<site site="s1"/>
|
||||
</spatial>
|
||||
<spatial name="SE" width="0.01">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder" sidesite="x0"/>
|
||||
<site site="s2"/>
|
||||
</spatial>
|
||||
|
||||
<spatial name="SE" width="0.01">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder" sidesite="x0"/>
|
||||
<site site="s2"/>
|
||||
</spatial>
|
||||
<spatial name="EF" width="0.01">
|
||||
<site site="s3"/>
|
||||
<geom geom="elbow"/>
|
||||
<site site="s7"/>
|
||||
</spatial>
|
||||
|
||||
<spatial name="EF" width="0.01">
|
||||
<site site="s3"/>
|
||||
<geom geom="elbow"/>
|
||||
<site site="s7"/>
|
||||
</spatial>
|
||||
<spatial name="EE" width="0.01">
|
||||
<site site="s4"/>
|
||||
<geom geom="elbow" sidesite="x1"/>
|
||||
<site site="s8"/>
|
||||
</spatial>
|
||||
|
||||
<spatial name="EE" width="0.01">
|
||||
<site site="s4"/>
|
||||
<geom geom="elbow" sidesite="x1"/>
|
||||
<site site="s8"/>
|
||||
</spatial>
|
||||
<spatial name="BF" width="0.009" rgba=".4 .6 .4 1">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder"/>
|
||||
<site site="s5"/>
|
||||
<geom geom="elbow"/>
|
||||
<site site="s7"/>
|
||||
</spatial>
|
||||
|
||||
<spatial name="BF" width="0.009" rgba=".4 .6 .4 1">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder"/>
|
||||
<site site="s5"/>
|
||||
<geom geom="elbow"/>
|
||||
<site site="s7"/>
|
||||
</spatial>
|
||||
<spatial name="BE" width="0.009" rgba=".4 .6 .4 1">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder" sidesite="x0"/>
|
||||
<site site="s6"/>
|
||||
<geom geom="elbow" sidesite="x1"/>
|
||||
<site site="s8"/>
|
||||
</spatial>
|
||||
</tendon>
|
||||
|
||||
<spatial name="BE" width="0.009" rgba=".4 .6 .4 1">
|
||||
<site site="s0"/>
|
||||
<geom geom="shoulder" sidesite="x0"/>
|
||||
<site site="s6"/>
|
||||
<geom geom="elbow" sidesite="x1"/>
|
||||
<site site="s8"/>
|
||||
</spatial>
|
||||
</tendon>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
@@ -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
@@ -12,12 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include "glfw3.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "mujoco.h"
|
||||
|
||||
// MuJoCo data structures
|
||||
mjModel* m = NULL; // MuJoCo model
|
||||
@@ -36,158 +35,156 @@ double lasty = 0;
|
||||
|
||||
|
||||
// keyboard callback
|
||||
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods)
|
||||
{
|
||||
// backspace: reset simulation
|
||||
if( act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE )
|
||||
{
|
||||
mj_resetData(m, d);
|
||||
mj_forward(m, d);
|
||||
}
|
||||
void keyboard(GLFWwindow* window, int key, int scancode, int act, int mods) {
|
||||
// backspace: reset simulation
|
||||
if (act==GLFW_PRESS && key==GLFW_KEY_BACKSPACE) {
|
||||
mj_resetData(m, d);
|
||||
mj_forward(m, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mouse button callback
|
||||
void mouse_button(GLFWwindow* window, int button, int act, int mods)
|
||||
{
|
||||
// update button state
|
||||
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
void mouse_button(GLFWwindow* window, int button, int act, int mods) {
|
||||
// update button state
|
||||
button_left = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
button_middle = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
button_right = (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
|
||||
// update mouse position
|
||||
glfwGetCursorPos(window, &lastx, &lasty);
|
||||
// update mouse position
|
||||
glfwGetCursorPos(window, &lastx, &lasty);
|
||||
}
|
||||
|
||||
|
||||
// mouse move callback
|
||||
void mouse_move(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
// no buttons down: nothing to do
|
||||
if( !button_left && !button_middle && !button_right )
|
||||
return;
|
||||
void mouse_move(GLFWwindow* window, double xpos, double ypos) {
|
||||
// no buttons down: nothing to do
|
||||
if (!button_left && !button_middle && !button_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute mouse displacement, save
|
||||
double dx = xpos - lastx;
|
||||
double dy = ypos - lasty;
|
||||
lastx = xpos;
|
||||
lasty = ypos;
|
||||
// compute mouse displacement, save
|
||||
double dx = xpos - lastx;
|
||||
double dy = ypos - lasty;
|
||||
lastx = xpos;
|
||||
lasty = ypos;
|
||||
|
||||
// get current window size
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
// get current window size
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
|
||||
// get shift key state
|
||||
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
// get shift key state
|
||||
bool mod_shift = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
|
||||
// determine action based on mouse button
|
||||
mjtMouse action;
|
||||
if( button_right )
|
||||
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
|
||||
else if( button_left )
|
||||
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
|
||||
else
|
||||
action = mjMOUSE_ZOOM;
|
||||
// determine action based on mouse button
|
||||
mjtMouse action;
|
||||
if (button_right) {
|
||||
action = mod_shift ? mjMOUSE_MOVE_H : mjMOUSE_MOVE_V;
|
||||
} else if (button_left) {
|
||||
action = mod_shift ? mjMOUSE_ROTATE_H : mjMOUSE_ROTATE_V;
|
||||
} else {
|
||||
action = mjMOUSE_ZOOM;
|
||||
}
|
||||
|
||||
// move camera
|
||||
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
|
||||
// move camera
|
||||
mjv_moveCamera(m, action, dx/height, dy/height, &scn, &cam);
|
||||
}
|
||||
|
||||
|
||||
// scroll callback
|
||||
void scroll(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
// emulate vertical mouse motion = 5% of window height
|
||||
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
|
||||
void scroll(GLFWwindow* window, double xoffset, double yoffset) {
|
||||
// emulate vertical mouse motion = 5% of window height
|
||||
mjv_moveCamera(m, mjMOUSE_ZOOM, 0, -0.05*yoffset, &scn, &cam);
|
||||
}
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// check command-line arguments
|
||||
if( argc!=2 )
|
||||
{
|
||||
printf(" USAGE: basic modelfile\n");
|
||||
return 0;
|
||||
int main(int argc, const char** argv) {
|
||||
// check command-line arguments
|
||||
if (argc!=2) {
|
||||
std::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
|
||||
char error[1000] = "Could not load binary model";
|
||||
if( strlen(argv[1])>4 && !strcmp(argv[1]+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);
|
||||
// get framebuffer viewport
|
||||
mjrRect viewport = {0, 0, 0, 0};
|
||||
glfwGetFramebufferSize(window, &viewport.width, &viewport.height);
|
||||
|
||||
// make data
|
||||
d = mj_makeData(m);
|
||||
// update scene and render
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
mjr_render(viewport, &scn, &con);
|
||||
|
||||
// init GLFW
|
||||
if( !glfwInit() )
|
||||
mju_error("Could not initialize GLFW");
|
||||
// swap OpenGL buffers (blocking call due to v-sync)
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// create window, make OpenGL context current, request v-sync
|
||||
GLFWwindow* window = glfwCreateWindow(1200, 900, "Demo", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
// process pending GUI events, call GLFW callbacks
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// initialize visualization data structures
|
||||
mjv_defaultCamera(&cam);
|
||||
mjv_defaultOption(&opt);
|
||||
mjv_defaultScene(&scn);
|
||||
mjr_defaultContext(&con);
|
||||
//free visualization storage
|
||||
mjv_freeScene(&scn);
|
||||
mjr_freeContext(&con);
|
||||
|
||||
// create scene and context
|
||||
mjv_makeScene(m, &scn, 2000);
|
||||
mjr_makeContext(m, &con, mjFONTSCALE_150);
|
||||
// free MuJoCo model and data
|
||||
mj_deleteData(d);
|
||||
mj_deleteModel(m);
|
||||
|
||||
// install GLFW mouse and keyboard callbacks
|
||||
glfwSetKeyCallback(window, keyboard);
|
||||
glfwSetCursorPosCallback(window, mouse_move);
|
||||
glfwSetMouseButtonCallback(window, mouse_button);
|
||||
glfwSetScrollCallback(window, scroll);
|
||||
// terminate GLFW (crashes with Linux NVidia drivers)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glfwTerminate();
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
|
||||
// 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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+100
-98
@@ -12,135 +12,137 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <cctype>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "mujoco.h"
|
||||
|
||||
// help
|
||||
const char helpstring[] =
|
||||
"\n Usage: compile infile outfile\n"
|
||||
" infile can be in mjcf, urdf, mjb format\n"
|
||||
" outfile can be in mjcf, mjb, txt format\n\n"
|
||||
" Example: compile model.xml model.mjb\n";
|
||||
"\n Usage: compile infile outfile\n"
|
||||
" infile can be in mjcf, urdf, mjb format\n"
|
||||
" outfile can be in mjcf, mjb, txt format\n\n"
|
||||
" Example: compile model.xml model.mjb\n";
|
||||
|
||||
|
||||
// deallocate and print message
|
||||
int finish(const char* msg = 0, mjModel* m = 0)
|
||||
{
|
||||
// deallocated everything
|
||||
if( m )
|
||||
mj_deleteModel(m);
|
||||
int finish(const char* msg = 0, mjModel* m = 0) {
|
||||
// deallocated everything
|
||||
if (m) {
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
// print message
|
||||
if( msg )
|
||||
printf("%s\n", msg);
|
||||
// print message
|
||||
if (msg) {
|
||||
std::printf("%s\n", msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// possible file types
|
||||
enum
|
||||
{
|
||||
typeUNKNOWN = 0,
|
||||
typeXML,
|
||||
typeMJB,
|
||||
typeTXT
|
||||
enum {
|
||||
typeUNKNOWN = 0,
|
||||
typeXML,
|
||||
typeMJB,
|
||||
typeTXT
|
||||
};
|
||||
|
||||
|
||||
// determine file type
|
||||
int filetype(const char* filename)
|
||||
{
|
||||
// convert to lower case for string comparison
|
||||
char lower[1000];
|
||||
size_t i=0;
|
||||
while( i<strlen(filename) && i<999 )
|
||||
{
|
||||
lower[i] = (char)tolower(filename[i]);
|
||||
i++;
|
||||
}
|
||||
lower[i] = 0;
|
||||
int filetype(const char* filename) {
|
||||
// convert to lower case for string comparison
|
||||
char lower[1000];
|
||||
std::size_t i=0;
|
||||
while (i<std::strlen(filename) && i<999) {
|
||||
lower[i] = (char)tolower(filename[i]);
|
||||
i++;
|
||||
}
|
||||
lower[i] = 0;
|
||||
|
||||
// find last dot
|
||||
int dot = (int)strlen(lower);
|
||||
while( dot>=0 && lower[dot]!='.' )
|
||||
dot--;
|
||||
// find last dot
|
||||
int dot = (int)std::strlen(lower);
|
||||
while (dot>=0 && lower[dot]!='.') {
|
||||
dot--;
|
||||
}
|
||||
|
||||
// no dot found
|
||||
if( dot<0 )
|
||||
return typeUNKNOWN;
|
||||
// no dot found
|
||||
if (dot<0) {
|
||||
return typeUNKNOWN;
|
||||
}
|
||||
|
||||
// check extension
|
||||
if( !strcmp(lower+dot, ".xml") || !strcmp(lower+dot, ".urdf") )
|
||||
return typeXML;
|
||||
else if( !strcmp(lower+dot, ".mjb") )
|
||||
return typeMJB;
|
||||
else if( !strcmp(lower+dot, ".txt") )
|
||||
return typeTXT;
|
||||
else
|
||||
return typeUNKNOWN;
|
||||
// check extension
|
||||
if (!std::strcmp(lower+dot, ".xml") || !std::strcmp(lower+dot, ".urdf")) {
|
||||
return typeXML;
|
||||
} else if (!std::strcmp(lower+dot, ".mjb")) {
|
||||
return typeMJB;
|
||||
} else if (!std::strcmp(lower+dot, ".txt")) {
|
||||
return typeTXT;
|
||||
} else {
|
||||
return typeUNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// model and error
|
||||
mjModel* m = 0;
|
||||
char error[1000];
|
||||
int main(int argc, const char** argv) {
|
||||
// model and error
|
||||
mjModel* m = 0;
|
||||
char error[1000];
|
||||
|
||||
// print help if arguments are missing
|
||||
if( argc!=3 )
|
||||
return finish(helpstring);
|
||||
// print help if arguments are missing
|
||||
if (argc!=3) {
|
||||
return finish(helpstring);
|
||||
}
|
||||
|
||||
// determine file types
|
||||
int type1 = filetype(argv[1]);
|
||||
int type2 = filetype(argv[2]);
|
||||
// determine file types
|
||||
int type1 = filetype(argv[1]);
|
||||
int type2 = filetype(argv[2]);
|
||||
|
||||
// check types
|
||||
if( type1==typeUNKNOWN || type1==typeTXT ||
|
||||
type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML) )
|
||||
return finish("Illegal combination of file formats");
|
||||
// check types
|
||||
if (type1==typeUNKNOWN || type1==typeTXT ||
|
||||
type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML)) {
|
||||
return finish("Illegal combination of file formats");
|
||||
}
|
||||
|
||||
// make sure output file does not exist
|
||||
FILE* fp = fopen(argv[2], "r");
|
||||
if( fp )
|
||||
{
|
||||
fclose(fp);
|
||||
return finish("Output file already exists");
|
||||
// make sure output file does not exist
|
||||
std::FILE* fp = std::fopen(argv[2], "r");
|
||||
if (fp) {
|
||||
std::fclose(fp);
|
||||
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
|
||||
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);
|
||||
// save model
|
||||
if (type2==typeXML) {
|
||||
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]);
|
||||
}
|
||||
|
||||
// save model
|
||||
if( type2==typeXML )
|
||||
{
|
||||
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);
|
||||
// finalize
|
||||
return finish("Done", m);
|
||||
}
|
||||
|
||||
+341
-343
@@ -12,29 +12,32 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// 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
|
||||
#if defined(_OPENMP)
|
||||
#include <omp.h>
|
||||
#include <omp.h>
|
||||
#else
|
||||
// omp timer replacement
|
||||
#include <chrono>
|
||||
double omp_get_wtime(void)
|
||||
{
|
||||
static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start;
|
||||
return elapsed.count();
|
||||
}
|
||||
// omp timer replacement
|
||||
#include <chrono>
|
||||
double omp_get_wtime(void)
|
||||
{
|
||||
static std::chrono::system_clock::time_point _start = std::chrono::system_clock::now();
|
||||
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - _start;
|
||||
return elapsed.count();
|
||||
}
|
||||
|
||||
// omp functions used below
|
||||
void omp_set_dynamic(int) {}
|
||||
void omp_set_num_threads(int) {}
|
||||
int omp_get_num_procs(void) {return 1;}
|
||||
// omp functions used below
|
||||
void omp_set_dynamic(int) {}
|
||||
void omp_set_num_threads(int) {}
|
||||
int omp_get_num_procs(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -56,388 +59,383 @@ double eps = 1e-6; // finite-difference epsilon
|
||||
|
||||
|
||||
// worker function for parallel finite-difference computation of derivatives
|
||||
void worker(const mjModel* m, const mjData* dmain, mjData* d, int id)
|
||||
{
|
||||
int nv = m->nv;
|
||||
void worker(const mjModel* m, const mjData* dmain, mjData* d, int id) {
|
||||
int nv = m->nv;
|
||||
|
||||
// allocate stack space for result at center
|
||||
mjMARKSTACK
|
||||
mjtNum* center = mj_stackAlloc(d, nv);
|
||||
mjtNum* warmstart = mj_stackAlloc(d, nv);
|
||||
// allocate stack space for result at center
|
||||
mjMARKSTACK
|
||||
mjtNum* center = mj_stackAlloc(d, nv);
|
||||
mjtNum* warmstart = mj_stackAlloc(d, nv);
|
||||
|
||||
// prepare static schedule: range of derivative columns to be computed by this thread
|
||||
int chunk = (m->nv + nthread-1) / nthread;
|
||||
int istart = id * chunk;
|
||||
int iend = mjMIN(istart + chunk, m->nv);
|
||||
// prepare static schedule: range of derivative columns to be computed by this thread
|
||||
int chunk = (m->nv + nthread-1) / nthread;
|
||||
int istart = id * chunk;
|
||||
int iend = mjMIN(istart + chunk, m->nv);
|
||||
|
||||
// copy state and control from dmain to thread-specific d
|
||||
d->time = dmain->time;
|
||||
// copy state and control from dmain to thread-specific d
|
||||
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->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);
|
||||
// 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;
|
||||
}
|
||||
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);
|
||||
|
||||
// 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
|
||||
mjFREESTACK
|
||||
}
|
||||
|
||||
|
||||
// compute relative L1 norm of residual
|
||||
double relnorm(mjtNum* residual, mjtNum* base, int n)
|
||||
{
|
||||
mjtNum L1res = 0, L1base = 0;
|
||||
for( int i=0; i<n; i++ )
|
||||
{
|
||||
L1res += mju_abs(residual[i]);
|
||||
L1base += mju_abs(base[i]);
|
||||
}
|
||||
double relnorm(mjtNum* residual, mjtNum* base, int n) {
|
||||
mjtNum L1res = 0, L1base = 0;
|
||||
for (int i=0; i<n; 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
|
||||
const char* accuracy[8] = {
|
||||
"G2*F2 - I ",
|
||||
"G2 - G2' ",
|
||||
"G1 - G1' ",
|
||||
"F2 - F2' ",
|
||||
"G1 + G2*F1",
|
||||
"G0 + G2*F0",
|
||||
"F1 + F2*G1",
|
||||
"F0 + F2*G0"
|
||||
"G2*F2 - I ",
|
||||
"G2 - G2' ",
|
||||
"G1 - G1' ",
|
||||
"F2 - F2' ",
|
||||
"G1 + G2*F1",
|
||||
"G0 + G2*F0",
|
||||
"F1 + F2*G1",
|
||||
"F0 + F2*G0"
|
||||
};
|
||||
|
||||
|
||||
// check accuracy of derivatives using known mathematical identities
|
||||
void checkderiv(const mjModel* m, mjData* d, mjtNum error[7])
|
||||
{
|
||||
int nv = m->nv;
|
||||
void checkderiv(const mjModel* m, mjData* d, mjtNum error[7]) {
|
||||
int nv = m->nv;
|
||||
|
||||
// allocate space
|
||||
mjMARKSTACK
|
||||
mjtNum* mat = mj_stackAlloc(d, nv*nv);
|
||||
// allocate space
|
||||
mjMARKSTACK
|
||||
mjtNum* mat = mj_stackAlloc(d, nv*nv);
|
||||
|
||||
// get pointers to derivative matrices
|
||||
mjtNum* G0 = deriv; // dinv/dpos
|
||||
mjtNum* G1 = deriv + nv*nv; // dinv/dvel
|
||||
mjtNum* G2 = deriv + 2*nv*nv; // dinv/dacc
|
||||
mjtNum* F0 = deriv + 3*nv*nv; // dacc/dpos
|
||||
mjtNum* F1 = deriv + 4*nv*nv; // dacc/dvel
|
||||
mjtNum* F2 = deriv + 5*nv*nv; // dacc/dfrc
|
||||
// get pointers to derivative matrices
|
||||
mjtNum* G0 = deriv; // dinv/dpos
|
||||
mjtNum* G1 = deriv + nv*nv; // dinv/dvel
|
||||
mjtNum* G2 = deriv + 2*nv*nv; // dinv/dacc
|
||||
mjtNum* F0 = deriv + 3*nv*nv; // dacc/dpos
|
||||
mjtNum* F1 = deriv + 4*nv*nv; // dacc/dvel
|
||||
mjtNum* F2 = deriv + 5*nv*nv; // dacc/dfrc
|
||||
|
||||
// G2*F2 - I
|
||||
mju_mulMatMat(mat, G2, F2, nv, nv, nv);
|
||||
for( int i=0; i<nv; i++ )
|
||||
mat[i*(nv+1)] -= 1;
|
||||
error[0] = relnorm(mat, G2, nv*nv);
|
||||
// G2*F2 - I
|
||||
mju_mulMatMat(mat, G2, F2, nv, nv, nv);
|
||||
for (int i=0; i<nv; i++) {
|
||||
mat[i*(nv+1)] -= 1;
|
||||
}
|
||||
error[0] = relnorm(mat, G2, nv*nv);
|
||||
|
||||
// G2 - G2'
|
||||
mju_transpose(mat, G2, nv, nv);
|
||||
mju_sub(mat, mat, G2, nv*nv);
|
||||
error[1] = relnorm(mat, G2, nv*nv);
|
||||
// G2 - G2'
|
||||
mju_transpose(mat, G2, nv, nv);
|
||||
mju_sub(mat, mat, G2, nv*nv);
|
||||
error[1] = relnorm(mat, G2, nv*nv);
|
||||
|
||||
// G1 - G1'
|
||||
mju_transpose(mat, G1, nv, nv);
|
||||
mju_sub(mat, mat, G1, nv*nv);
|
||||
error[2] = relnorm(mat, G1, nv*nv);
|
||||
// G1 - G1'
|
||||
mju_transpose(mat, G1, nv, nv);
|
||||
mju_sub(mat, mat, G1, nv*nv);
|
||||
error[2] = relnorm(mat, G1, nv*nv);
|
||||
|
||||
// F2 - F2'
|
||||
mju_transpose(mat, F2, nv, nv);
|
||||
mju_sub(mat, mat, F2, nv*nv);
|
||||
error[3] = relnorm(mat, F2, nv*nv);
|
||||
// F2 - F2'
|
||||
mju_transpose(mat, F2, nv, nv);
|
||||
mju_sub(mat, mat, F2, nv*nv);
|
||||
error[3] = relnorm(mat, F2, nv*nv);
|
||||
|
||||
// G1 + G2*F1
|
||||
mju_mulMatMat(mat, G2, F1, nv, nv, nv);
|
||||
mju_addTo(mat, G1, nv*nv);
|
||||
error[4] = relnorm(mat, G1, nv*nv);
|
||||
// G1 + G2*F1
|
||||
mju_mulMatMat(mat, G2, F1, nv, nv, nv);
|
||||
mju_addTo(mat, G1, nv*nv);
|
||||
error[4] = relnorm(mat, G1, nv*nv);
|
||||
|
||||
// G0 + G2*F0
|
||||
mju_mulMatMat(mat, G2, F0, nv, nv, nv);
|
||||
mju_addTo(mat, G0, nv*nv);
|
||||
error[5] = relnorm(mat, G0, nv*nv);
|
||||
// G0 + G2*F0
|
||||
mju_mulMatMat(mat, G2, F0, nv, nv, nv);
|
||||
mju_addTo(mat, G0, nv*nv);
|
||||
error[5] = relnorm(mat, G0, nv*nv);
|
||||
|
||||
// F1 + F2*G1
|
||||
mju_mulMatMat(mat, F2, G1, nv, nv, nv);
|
||||
mju_addTo(mat, F1, nv*nv);
|
||||
error[6] = relnorm(mat, F1, nv*nv);
|
||||
// F1 + F2*G1
|
||||
mju_mulMatMat(mat, F2, G1, nv, nv, nv);
|
||||
mju_addTo(mat, F1, nv*nv);
|
||||
error[6] = relnorm(mat, F1, nv*nv);
|
||||
|
||||
// F0 + F2*G0
|
||||
mju_mulMatMat(mat, F2, G0, nv, nv, nv);
|
||||
mju_addTo(mat, F0, nv*nv);
|
||||
error[7] = relnorm(mat, F0, nv*nv);
|
||||
// F0 + F2*G0
|
||||
mju_mulMatMat(mat, F2, G0, nv, nv, nv);
|
||||
mju_addTo(mat, F0, nv*nv);
|
||||
error[7] = relnorm(mat, F0, nv*nv);
|
||||
|
||||
mjFREESTACK
|
||||
mjFREESTACK
|
||||
}
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// print help if not enough arguments
|
||||
if( argc<2 )
|
||||
{
|
||||
printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n");
|
||||
return 1;
|
||||
}
|
||||
int main(int argc, char** argv) {
|
||||
// print help if not enough arguments
|
||||
if (argc<2) {
|
||||
std::printf("\n Arguments: modelfile [nthread niter nwarmup nepoch nstep eps]\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// default nthread = number of logical cores (usually optimal)
|
||||
nthread = omp_get_num_procs();
|
||||
// default nthread = number of logical cores (usually optimal)
|
||||
nthread = omp_get_num_procs();
|
||||
|
||||
// get numeric command-line arguments
|
||||
if( argc>2 )
|
||||
sscanf(argv[2], "%d", &nthread);
|
||||
if( argc>3 )
|
||||
sscanf(argv[3], "%d", &niter);
|
||||
if( argc>4 )
|
||||
sscanf(argv[4], "%d", &nwarmup);
|
||||
if( argc>5 )
|
||||
sscanf(argv[5], "%d", &nepoch);
|
||||
if( argc>6 )
|
||||
sscanf(argv[6], "%d", &nstep);
|
||||
if( argc>7 )
|
||||
sscanf(argv[7], "%lf", &eps);
|
||||
// get numeric command-line arguments
|
||||
if (argc>2) {
|
||||
std::sscanf(argv[2], "%d", &nthread);
|
||||
}
|
||||
if (argc>3) {
|
||||
std::sscanf(argv[3], "%d", &niter);
|
||||
}
|
||||
if (argc>4) {
|
||||
std::sscanf(argv[4], "%d", &nwarmup);
|
||||
}
|
||||
if (argc>5) {
|
||||
std::sscanf(argv[5], "%d", &nepoch);
|
||||
}
|
||||
if (argc>6) {
|
||||
std::sscanf(argv[6], "%d", &nstep);
|
||||
}
|
||||
if (argc>7) {
|
||||
std::sscanf(argv[7], "%lf", &eps);
|
||||
}
|
||||
|
||||
// check number of threads
|
||||
if( nthread<1 || nthread>MAXTHREAD )
|
||||
{
|
||||
printf("nthread must be between 1 and %d\n", MAXTHREAD);
|
||||
return 1;
|
||||
}
|
||||
// check number of threads
|
||||
if (nthread<1 || nthread>MAXTHREAD) {
|
||||
std::printf("nthread must be between 1 and %d\n", MAXTHREAD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check number of epochs
|
||||
if( nepoch<1 || nepoch>MAXEPOCH )
|
||||
{
|
||||
printf("nepoch must be between 1 and %d\n", MAXEPOCH);
|
||||
return 1;
|
||||
}
|
||||
// check number of epochs
|
||||
if (nepoch<1 || nepoch>MAXEPOCH) {
|
||||
std::printf("nepoch must be between 1 and %d\n", MAXEPOCH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// load model
|
||||
mjModel* m = 0;
|
||||
if( strlen(argv[1])>4 && !strcmp(argv[1]+strlen(argv[1])-4, ".mjb") )
|
||||
m = mj_loadModel(argv[1], NULL);
|
||||
else
|
||||
m = mj_loadXML(argv[1], NULL, NULL, 0);
|
||||
if( !m )
|
||||
{
|
||||
printf("Could not load modelfile '%s'\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
// load model
|
||||
mjModel* m = 0;
|
||||
if (std::strlen(argv[1])>4 && !std::strcmp(argv[1]+std::strlen(argv[1])-4, ".mjb")) {
|
||||
m = mj_loadModel(argv[1], NULL);
|
||||
} else {
|
||||
m = mj_loadXML(argv[1], NULL, NULL, 0);
|
||||
}
|
||||
if (!m) {
|
||||
std::printf("Could not load modelfile '%s'\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// print arguments
|
||||
// print arguments
|
||||
#if defined(_OPENMP)
|
||||
printf("\nnthread : %d (OpenMP)\n", nthread);
|
||||
std::printf("\nnthread : %d (OpenMP)\n", nthread);
|
||||
#else
|
||||
printf("\nnthread : %d (serial)\n", nthread);
|
||||
std::printf("\nnthread : %d (serial)\n", nthread);
|
||||
#endif
|
||||
printf("niter : %d\n", niter);
|
||||
printf("nwarmup : %d\n", nwarmup);
|
||||
printf("nepoch : %d\n", nepoch);
|
||||
printf("nstep : %d\n", nstep);
|
||||
printf("eps : %g\n\n", eps);
|
||||
std::printf("niter : %d\n", niter);
|
||||
std::printf("nwarmup : %d\n", nwarmup);
|
||||
std::printf("nepoch : %d\n", nepoch);
|
||||
std::printf("nstep : %d\n", nstep);
|
||||
std::printf("eps : %g\n\n", eps);
|
||||
|
||||
// make mjData: main, per-thread
|
||||
mjData* dmain = mj_makeData(m);
|
||||
mjData* d[MAXTHREAD];
|
||||
for( int n=0; n<nthread; n++ )
|
||||
d[n] = mj_makeData(m);
|
||||
// make mjData: main, per-thread
|
||||
mjData* dmain = mj_makeData(m);
|
||||
mjData* d[MAXTHREAD];
|
||||
for (int n=0; n<nthread; n++) {
|
||||
d[n] = mj_makeData(m);
|
||||
}
|
||||
|
||||
// allocate derivatives
|
||||
deriv = (mjtNum*) mju_malloc(6*sizeof(mjtNum)*m->nv*m->nv);
|
||||
// allocate derivatives
|
||||
deriv = (mjtNum*) mju_malloc(6*sizeof(mjtNum)*m->nv*m->nv);
|
||||
|
||||
// set up OpenMP (if not enabled, this does nothing)
|
||||
omp_set_dynamic(0);
|
||||
omp_set_num_threads(nthread);
|
||||
// set up OpenMP (if not enabled, this does nothing)
|
||||
omp_set_dynamic(0);
|
||||
omp_set_num_threads(nthread);
|
||||
|
||||
// save solver options
|
||||
int save_iterations = m->opt.iterations;
|
||||
mjtNum save_tolerance = m->opt.tolerance;
|
||||
// save solver options
|
||||
int save_iterations = m->opt.iterations;
|
||||
mjtNum save_tolerance = m->opt.tolerance;
|
||||
|
||||
// allocate statistics
|
||||
int nefc = 0;
|
||||
double cputm[MAXEPOCH][2];
|
||||
mjtNum error[MAXEPOCH][8];
|
||||
// allocate statistics
|
||||
int nefc = 0;
|
||||
double cputm[MAXEPOCH][2];
|
||||
mjtNum error[MAXEPOCH][8];
|
||||
|
||||
// run epochs, collect statistics
|
||||
for( int epoch=0; epoch<nepoch; epoch++ )
|
||||
{
|
||||
// set solver options for main simulation
|
||||
m->opt.iterations = save_iterations;
|
||||
m->opt.tolerance = save_tolerance;
|
||||
// run epochs, collect statistics
|
||||
for (int epoch=0; epoch<nepoch; epoch++) {
|
||||
// set solver options for main simulation
|
||||
m->opt.iterations = save_iterations;
|
||||
m->opt.tolerance = save_tolerance;
|
||||
|
||||
// advance main simulation for nstep
|
||||
for( int i=0; i<nstep; i++ )
|
||||
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]);
|
||||
// advance main simulation for nstep
|
||||
for (int i=0; i<nstep; i++) {
|
||||
mj_step(m, dmain);
|
||||
}
|
||||
|
||||
// compute statistics
|
||||
double mcputm[2] = {0,0}, merror[8] = {0,0,0,0,0,0,0,0};
|
||||
for( int epoch=0; epoch<nepoch; epoch++ )
|
||||
{
|
||||
mcputm[0] += cputm[epoch][0];
|
||||
mcputm[1] += cputm[epoch][1];
|
||||
// count number of active constraints
|
||||
nefc += dmain->nefc;
|
||||
|
||||
for( int ie=0; ie<8; ie++ )
|
||||
merror[ie] += error[epoch][ie];
|
||||
// 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);
|
||||
}
|
||||
|
||||
// print sizes, timing, accuracy
|
||||
printf("sizes : nv %d, nefc %d\n\n", m->nv, nefc/nepoch);
|
||||
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");
|
||||
// check derivatives
|
||||
checkderiv(m, d[0], error[epoch]);
|
||||
}
|
||||
|
||||
// shut down
|
||||
mju_free(deriv);
|
||||
mj_deleteData(dmain);
|
||||
for( int n=0; n<nthread; n++ )
|
||||
mj_deleteData(d[n]);
|
||||
mj_deleteModel(m);
|
||||
return 0;
|
||||
// compute statistics
|
||||
double mcputm[2] = {0, 0}, merror[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
for (int epoch=0; epoch<nepoch; epoch++) {
|
||||
mcputm[0] += cputm[epoch][0];
|
||||
mcputm[1] += cputm[epoch][1];
|
||||
|
||||
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
@@ -12,23 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "mujoco.h"
|
||||
|
||||
// select EGL, OSMESA or GLFW
|
||||
#if defined(MJ_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/egl.h>
|
||||
#elif defined(MJ_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
OSMesaContext ctx;
|
||||
unsigned char buffer[10000000];
|
||||
#include <GL/osmesa.h>
|
||||
OSMesaContext ctx;
|
||||
unsigned char buffer[10000000];
|
||||
#else
|
||||
#include "glfw3.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif
|
||||
|
||||
#include "array_safety.h"
|
||||
namespace mju = ::mujoco::sample_util;
|
||||
|
||||
//-------------------------------- global data ------------------------------------------
|
||||
|
||||
@@ -46,266 +48,273 @@ mjrContext con;
|
||||
//-------------------------------- utility functions ------------------------------------
|
||||
|
||||
// load model, init simulation and rendering
|
||||
void initMuJoCo(const char* filename)
|
||||
{
|
||||
// load and compile
|
||||
char error[1000] = "Could not load binary model";
|
||||
if( strlen(filename)>4 && !strcmp(filename+strlen(filename)-4, ".mjb") )
|
||||
m = mj_loadModel(filename, 0);
|
||||
else
|
||||
m = mj_loadXML(filename, 0, error, 1000);
|
||||
if( !m )
|
||||
mju_error_s("Load model error: %s", error);
|
||||
void initMuJoCo(const char* filename) {
|
||||
// load and compile
|
||||
char error[1000] = "Could not load binary model";
|
||||
if (std::strlen(filename)>4 && !std::strcmp(filename+std::strlen(filename)-4, ".mjb")) {
|
||||
m = mj_loadModel(filename, 0);
|
||||
} else {
|
||||
m = mj_loadXML(filename, 0, error, 1000);
|
||||
}
|
||||
if (!m) {
|
||||
mju_error_s("Load model error: %s", error);
|
||||
}
|
||||
|
||||
// make data, run one computation to initialize all fields
|
||||
d = mj_makeData(m);
|
||||
mj_forward(m, d);
|
||||
// make data, run one computation to initialize all fields
|
||||
d = mj_makeData(m);
|
||||
mj_forward(m, d);
|
||||
|
||||
// initialize visualization data structures
|
||||
mjv_defaultCamera(&cam);
|
||||
mjv_defaultOption(&opt);
|
||||
mjv_defaultScene(&scn);
|
||||
mjr_defaultContext(&con);
|
||||
// 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, 200);
|
||||
// create scene and context
|
||||
mjv_makeScene(m, &scn, 2000);
|
||||
mjr_makeContext(m, &con, 200);
|
||||
|
||||
// center and scale view
|
||||
cam.lookat[0] = m->stat.center[0];
|
||||
cam.lookat[1] = m->stat.center[1];
|
||||
cam.lookat[2] = m->stat.center[2];
|
||||
cam.distance = 1.5 * m->stat.extent;
|
||||
// center and scale view
|
||||
cam.lookat[0] = m->stat.center[0];
|
||||
cam.lookat[1] = m->stat.center[1];
|
||||
cam.lookat[2] = m->stat.center[2];
|
||||
cam.distance = 1.5 * m->stat.extent;
|
||||
}
|
||||
|
||||
|
||||
// deallocate everything
|
||||
void closeMuJoCo(void)
|
||||
{
|
||||
mj_deleteData(d);
|
||||
mj_deleteModel(m);
|
||||
mjr_freeContext(&con);
|
||||
mjv_freeScene(&scn);
|
||||
void closeMuJoCo(void) {
|
||||
mj_deleteData(d);
|
||||
mj_deleteModel(m);
|
||||
mjr_freeContext(&con);
|
||||
mjv_freeScene(&scn);
|
||||
}
|
||||
|
||||
|
||||
// create OpenGL context/window
|
||||
void initOpenGL(void)
|
||||
{
|
||||
//------------------------ EGL
|
||||
void initOpenGL(void) {
|
||||
//------------------------ EGL
|
||||
#if defined(MJ_EGL)
|
||||
// desired config
|
||||
const EGLint configAttribs[] ={
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
// desired config
|
||||
const EGLint configAttribs[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// get default display
|
||||
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if( eglDpy==EGL_NO_DISPLAY )
|
||||
mju_error_i("Could not get EGL display, error 0x%x\n", eglGetError());
|
||||
// get default display
|
||||
EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (eglDpy==EGL_NO_DISPLAY) {
|
||||
mju_error_i("Could not get EGL display, error 0x%x\n", eglGetError());
|
||||
}
|
||||
|
||||
// initialize
|
||||
EGLint major, minor;
|
||||
if( eglInitialize(eglDpy, &major, &minor)!=EGL_TRUE )
|
||||
mju_error_i("Could not initialize EGL, error 0x%x\n", eglGetError());
|
||||
// initialize
|
||||
EGLint major, minor;
|
||||
if (eglInitialize(eglDpy, &major, &minor)!=EGL_TRUE) {
|
||||
mju_error_i("Could not initialize EGL, error 0x%x\n", eglGetError());
|
||||
}
|
||||
|
||||
// choose config
|
||||
EGLint numConfigs;
|
||||
EGLConfig eglCfg;
|
||||
if( eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE )
|
||||
mju_error_i("Could not choose EGL config, error 0x%x\n", eglGetError());
|
||||
// choose config
|
||||
EGLint numConfigs;
|
||||
EGLConfig eglCfg;
|
||||
if (eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE) {
|
||||
mju_error_i("Could not choose EGL config, error 0x%x\n", eglGetError());
|
||||
}
|
||||
|
||||
// bind OpenGL API
|
||||
if( eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE )
|
||||
mju_error_i("Could not bind EGL OpenGL API, error 0x%x\n", eglGetError());
|
||||
// bind OpenGL API
|
||||
if (eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE) {
|
||||
mju_error_i("Could not bind EGL OpenGL API, error 0x%x\n", eglGetError());
|
||||
}
|
||||
|
||||
// create context
|
||||
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);
|
||||
if( eglCtx==EGL_NO_CONTEXT )
|
||||
mju_error_i("Could not create EGL context, error 0x%x\n", eglGetError());
|
||||
// create context
|
||||
EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);
|
||||
if (eglCtx==EGL_NO_CONTEXT) {
|
||||
mju_error_i("Could not create EGL context, error 0x%x\n", eglGetError());
|
||||
}
|
||||
|
||||
// make context current, no surface (let OpenGL handle FBO)
|
||||
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());
|
||||
// make context current, no surface (let OpenGL handle FBO)
|
||||
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());
|
||||
}
|
||||
|
||||
//------------------------ OSMESA
|
||||
//------------------------ OSMESA
|
||||
#elif defined(MJ_OSMESA)
|
||||
// create context
|
||||
ctx = OSMesaCreateContextExt(GL_RGBA, 24, 8, 8, 0);
|
||||
if( !ctx )
|
||||
mju_error("OSMesa context creation failed");
|
||||
// create context
|
||||
ctx = OSMesaCreateContextExt(GL_RGBA, 24, 8, 8, 0);
|
||||
if (!ctx) {
|
||||
mju_error("OSMesa context creation failed");
|
||||
}
|
||||
|
||||
// make current
|
||||
if( !OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, 800, 800) )
|
||||
mju_error("OSMesa make current failed");
|
||||
// make current
|
||||
if (!OSMesaMakeCurrent(ctx, buffer, GL_UNSIGNED_BYTE, 800, 800)) {
|
||||
mju_error("OSMesa make current failed");
|
||||
}
|
||||
|
||||
//------------------------ GLFW
|
||||
//------------------------ GLFW
|
||||
#else
|
||||
// init GLFW
|
||||
if( !glfwInit() )
|
||||
mju_error("Could not initialize GLFW");
|
||||
// init GLFW
|
||||
if (!glfwInit()) {
|
||||
mju_error("Could not initialize GLFW");
|
||||
}
|
||||
|
||||
// create invisible window, single-buffered
|
||||
glfwWindowHint(GLFW_VISIBLE, 0);
|
||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
|
||||
GLFWwindow* window = glfwCreateWindow(800, 800, "Invisible window", NULL, NULL);
|
||||
if( !window )
|
||||
mju_error("Could not create GLFW window");
|
||||
// create invisible window, single-buffered
|
||||
glfwWindowHint(GLFW_VISIBLE, 0);
|
||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_FALSE);
|
||||
GLFWwindow* window = glfwCreateWindow(800, 800, "Invisible window", NULL, NULL);
|
||||
if (!window) {
|
||||
mju_error("Could not create GLFW window");
|
||||
}
|
||||
|
||||
// make context current
|
||||
glfwMakeContextCurrent(window);
|
||||
// make context current
|
||||
glfwMakeContextCurrent(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// close OpenGL context/window
|
||||
void closeOpenGL(void)
|
||||
{
|
||||
//------------------------ EGL
|
||||
void closeOpenGL(void) {
|
||||
//------------------------ EGL
|
||||
#if defined(MJ_EGL)
|
||||
// get current display
|
||||
EGLDisplay eglDpy = eglGetCurrentDisplay();
|
||||
if( eglDpy==EGL_NO_DISPLAY )
|
||||
return;
|
||||
// get current display
|
||||
EGLDisplay eglDpy = eglGetCurrentDisplay();
|
||||
if (eglDpy==EGL_NO_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get current context
|
||||
EGLContext eglCtx = eglGetCurrentContext();
|
||||
// get current context
|
||||
EGLContext eglCtx = eglGetCurrentContext();
|
||||
|
||||
// release context
|
||||
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
// release context
|
||||
eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
// destroy context if valid
|
||||
if( eglCtx!=EGL_NO_CONTEXT )
|
||||
eglDestroyContext(eglDpy, eglCtx);
|
||||
// destroy context if valid
|
||||
if (eglCtx!=EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(eglDpy, eglCtx);
|
||||
}
|
||||
|
||||
// terminate display
|
||||
eglTerminate(eglDpy);
|
||||
// terminate display
|
||||
eglTerminate(eglDpy);
|
||||
|
||||
//------------------------ OSMESA
|
||||
//------------------------ OSMESA
|
||||
#elif defined(MJ_OSMESA)
|
||||
OSMesaDestroyContext(ctx);
|
||||
OSMesaDestroyContext(ctx);
|
||||
|
||||
//------------------------ GLFW
|
||||
//------------------------ GLFW
|
||||
#else
|
||||
// terminate GLFW (crashes with Linux NVidia drivers)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glfwTerminate();
|
||||
#endif
|
||||
// terminate GLFW (crashes with Linux NVidia drivers)
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glfwTerminate();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------- main function ----------------------------------------
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// check command-line arguments
|
||||
if( argc!=5 )
|
||||
{
|
||||
printf(" USAGE: record modelfile duration fps rgbfile\n");
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, const char** argv) {
|
||||
// check command-line arguments
|
||||
if (argc!=5) {
|
||||
std::printf(" USAGE: record modelfile duration fps rgbfile\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// parse numeric arguments
|
||||
double duration = 10, fps = 30;
|
||||
sscanf(argv[2], "%lf", &duration);
|
||||
sscanf(argv[3], "%lf", &fps);
|
||||
// parse numeric arguments
|
||||
double duration = 10, fps = 30;
|
||||
std::sscanf(argv[2], "%lf", &duration);
|
||||
std::sscanf(argv[3], "%lf", &fps);
|
||||
|
||||
// initialize OpenGL and MuJoCo
|
||||
initOpenGL();
|
||||
initMuJoCo(argv[1]);
|
||||
// initialize OpenGL and MuJoCo
|
||||
initOpenGL();
|
||||
initMuJoCo(argv[1]);
|
||||
|
||||
// set rendering to offscreen buffer
|
||||
mjr_setBuffer(mjFB_OFFSCREEN, &con);
|
||||
if( con.currentBuffer!=mjFB_OFFSCREEN )
|
||||
printf("Warning: offscreen rendering not supported, using default/window framebuffer\n");
|
||||
// set rendering to offscreen buffer
|
||||
mjr_setBuffer(mjFB_OFFSCREEN, &con);
|
||||
if (con.currentBuffer!=mjFB_OFFSCREEN) {
|
||||
std::printf("Warning: offscreen rendering not supported, using default/window framebuffer\n");
|
||||
}
|
||||
|
||||
// get size of active renderbuffer
|
||||
mjrRect viewport = mjr_maxViewport(&con);
|
||||
int W = viewport.width;
|
||||
int H = viewport.height;
|
||||
// get size of active renderbuffer
|
||||
mjrRect viewport = mjr_maxViewport(&con);
|
||||
int W = viewport.width;
|
||||
int H = viewport.height;
|
||||
|
||||
// allocate rgb and depth buffers
|
||||
unsigned char* rgb = (unsigned char*)malloc(3*W*H);
|
||||
float* depth = (float*)malloc(sizeof(float)*W*H);
|
||||
if( !rgb || !depth )
|
||||
mju_error("Could not allocate buffers");
|
||||
// allocate rgb and depth buffers
|
||||
unsigned char* rgb = (unsigned char*)std::malloc(3*W*H);
|
||||
float* depth = (float*)std::malloc(sizeof(float)*W*H);
|
||||
if (!rgb || !depth) {
|
||||
mju_error("Could not allocate buffers");
|
||||
}
|
||||
|
||||
// create output rgb file
|
||||
FILE* fp = fopen(argv[4], "wb");
|
||||
if( !fp )
|
||||
mju_error("Could not open rgbfile for writing");
|
||||
// create output rgb file
|
||||
std::FILE* fp = std::fopen(argv[4], "wb");
|
||||
if (!fp) {
|
||||
mju_error("Could not open rgbfile for writing");
|
||||
}
|
||||
|
||||
// main loop
|
||||
double frametime = 0;
|
||||
int framecount = 0;
|
||||
while( d->time<duration )
|
||||
{
|
||||
// render new frame if it is time (or first frame)
|
||||
if( (d->time-frametime)>1/fps || frametime==0 )
|
||||
{
|
||||
// update abstract scene
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
// main loop
|
||||
double frametime = 0;
|
||||
int framecount = 0;
|
||||
while (d->time<duration) {
|
||||
// render new frame if it is time (or first frame)
|
||||
if ((d->time-frametime)>1/fps || frametime==0) {
|
||||
// update abstract scene
|
||||
mjv_updateScene(m, d, &opt, NULL, &cam, mjCAT_ALL, &scn);
|
||||
|
||||
// render scene in offscreen buffer
|
||||
mjr_render(viewport, &scn, &con);
|
||||
// render scene in offscreen buffer
|
||||
mjr_render(viewport, &scn, &con);
|
||||
|
||||
// add time stamp in upper-left corner
|
||||
char stamp[50];
|
||||
sprintf(stamp, "Time = %.3f", d->time);
|
||||
mjr_overlay(mjFONT_NORMAL, mjGRID_TOPLEFT, viewport, stamp, NULL, &con);
|
||||
// add time stamp in upper-left corner
|
||||
char stamp[50];
|
||||
mju::sprintf_arr(stamp, "Time = %.3f", d->time);
|
||||
mjr_overlay(mjFONT_NORMAL, mjGRID_TOPLEFT, viewport, stamp, NULL, &con);
|
||||
|
||||
// read rgb and depth buffers
|
||||
mjr_readPixels(rgb, depth, viewport, &con);
|
||||
// read rgb and depth buffers
|
||||
mjr_readPixels(rgb, depth, viewport, &con);
|
||||
|
||||
// insert subsampled depth image in lower-left corner of rgb image
|
||||
const int NS = 3; // depth image sub-sampling
|
||||
for( int r=0; r<H; r+=NS )
|
||||
for( int c=0; c<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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// insert subsampled depth image in lower-left corner of rgb image
|
||||
const int NS = 3; // depth image sub-sampling
|
||||
for (int r=0; r<H; r+=NS)
|
||||
for (int c=0; c<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);
|
||||
}
|
||||
|
||||
// advance simulation
|
||||
mj_step(m, d);
|
||||
// write rgb image to file
|
||||
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
|
||||
fclose(fp);
|
||||
free(rgb);
|
||||
free(depth);
|
||||
// advance simulation
|
||||
mj_step(m, d);
|
||||
}
|
||||
std::printf("\n");
|
||||
|
||||
// close MuJoCo and OpenGL
|
||||
closeMuJoCo();
|
||||
closeOpenGL();
|
||||
// close file, free buffers
|
||||
std::fclose(fp);
|
||||
std::free(rgb);
|
||||
std::free(depth);
|
||||
|
||||
return 1;
|
||||
// close MuJoCo and OpenGL
|
||||
closeMuJoCo();
|
||||
closeOpenGL();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
+1690
-1641
File diff suppressed because it is too large
Load Diff
Regular → Executable
+159
-133
@@ -12,15 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
#include "mujoco.h"
|
||||
|
||||
|
||||
// model and per-thread data
|
||||
@@ -35,161 +33,189 @@ double simtime[64];
|
||||
|
||||
|
||||
// timer
|
||||
chrono::system_clock::time_point tm_start;
|
||||
mjtNum gettm(void)
|
||||
{
|
||||
chrono::duration<double> elapsed = chrono::system_clock::now() - tm_start;
|
||||
return elapsed.count();
|
||||
std::chrono::system_clock::time_point tm_start;
|
||||
mjtNum gettm(void) {
|
||||
std::chrono::duration<double> elapsed = std::chrono::system_clock::now() - tm_start;
|
||||
return elapsed.count();
|
||||
}
|
||||
|
||||
|
||||
// deallocate and print message
|
||||
int finish(const char* msg = NULL, mjModel* m = NULL)
|
||||
{
|
||||
// deallocate model
|
||||
if( m )
|
||||
mj_deleteModel(m);
|
||||
int finish(const char* msg = NULL, mjModel* m = NULL) {
|
||||
// deallocate model
|
||||
if (m) {
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
// print message
|
||||
if( msg )
|
||||
printf("%s\n", msg);
|
||||
// print message
|
||||
if (msg) {
|
||||
std::printf("%s\n", msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// thread function
|
||||
void simulate(int id, int nstep)
|
||||
{
|
||||
// clear statistics
|
||||
contacts[id] = 0;
|
||||
constraints[id] = 0;
|
||||
void simulate(int id, int nstep, mjtNum ctrlnoise) {
|
||||
// clear statistics
|
||||
contacts[id] = 0;
|
||||
constraints[id] = 0;
|
||||
|
||||
// run and time
|
||||
double start = gettm();
|
||||
for( int i=0; i<nstep; i++ )
|
||||
{
|
||||
// advance simulation
|
||||
mj_step(m, d[id]);
|
||||
// run and time
|
||||
double start = gettm();
|
||||
for (int i=0; i<nstep; i++) {
|
||||
// inject pseuso-random control noise
|
||||
if (ctrlnoise)
|
||||
for (int j=0; j<m->nu; j++) {
|
||||
mjtNum center = 0.0;
|
||||
mjtNum radius = 1.0;
|
||||
mjtNum* range = m->actuator_ctrlrange + 2*j;
|
||||
if (m->actuator_ctrllimited[j]) {
|
||||
center = (range[1] + range[0]) / 2;
|
||||
radius = (range[1] - range[0]) / 2;
|
||||
}
|
||||
radius *= ctrlnoise;
|
||||
d[id]->ctrl[j] = center + radius * (2*mju_Halton(i, j+2) - 1);
|
||||
}
|
||||
|
||||
// accumulate statistics
|
||||
contacts[id] += d[id]->ncon;
|
||||
constraints[id] += d[id]->nefc;
|
||||
}
|
||||
simtime[id] = gettm() - start;
|
||||
// advance simulation
|
||||
mj_step(m, d[id]);
|
||||
|
||||
// accumulate statistics
|
||||
contacts[id] += d[id]->ncon;
|
||||
constraints[id] += d[id]->nefc;
|
||||
}
|
||||
simtime[id] = gettm() - start;
|
||||
}
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// print help if arguments are missing
|
||||
if( argc<3 || argc>5 )
|
||||
return finish("\n Usage: testspeed modelfile nstep [nthread [profile]]\n");
|
||||
int main(int argc, const char** argv) {
|
||||
// print help if arguments are missing
|
||||
if (argc<2 || argc>6) {
|
||||
return finish("\n Usage: testspeed modelfile [nstep nthread ctrlnoise profile]\n");
|
||||
}
|
||||
|
||||
// read nstep and nthread
|
||||
int nstep = 0, nthread = 0, profile = 0;
|
||||
if( sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0 )
|
||||
return finish("Invalid nstep argument");
|
||||
if( argc>3 )
|
||||
if( sscanf(argv[3], "%d", &nthread)!=1 )
|
||||
return finish("Invalid nthread argument");
|
||||
if( argc>4 )
|
||||
if( sscanf(argv[4], "%d", &profile)!=1 )
|
||||
return finish("Invalid profile argument");
|
||||
|
||||
// clamp nthread to [1, 64]
|
||||
nthread = mjMAX(1, mjMIN(64, nthread));
|
||||
|
||||
// get filename, determine file type
|
||||
std::string filename(argv[1]);
|
||||
bool binary = (filename.find(".mjb")!=std::string::npos);
|
||||
|
||||
// load model
|
||||
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);
|
||||
}
|
||||
// read arguments
|
||||
int nstep = 10000, nthread = 0, profile = 0;
|
||||
// inject small noise by default, to avoid fixed contact state
|
||||
mjtNum ctrlnoise = 0.01;
|
||||
if (argc>2)
|
||||
if (std::sscanf(argv[2], "%d", &nstep)!=1 || nstep<=0) {
|
||||
return finish("Invalid nstep argument");
|
||||
}
|
||||
if (argc>3)
|
||||
if (std::sscanf(argv[3], "%d", &nthread)!=1) {
|
||||
return finish("Invalid nthread argument");
|
||||
}
|
||||
if (argc>4)
|
||||
if (std::sscanf(argv[4], "%lf", &ctrlnoise)!=1) {
|
||||
return finish("Invalid ctrlnoise argument");
|
||||
}
|
||||
if (argc>5)
|
||||
if (std::sscanf(argv[5], "%d", &profile)!=1) {
|
||||
return finish("Invalid profile argument");
|
||||
}
|
||||
|
||||
// install timer callback for profiling if requested
|
||||
tm_start = chrono::system_clock::now();
|
||||
if( profile )
|
||||
mjcb_time = gettm;
|
||||
// clamp ctrlnoise to [0.0, 1.0]
|
||||
ctrlnoise = mjMAX(0.0, mjMIN(ctrlnoise, 1.0));
|
||||
|
||||
// print start
|
||||
if( nthread>1 )
|
||||
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);
|
||||
// clamp nthread to [1, 64]
|
||||
nthread = mjMAX(1, mjMIN(64, nthread));
|
||||
|
||||
// run simulation, record total time
|
||||
thread th[64];
|
||||
double starttime = gettm();
|
||||
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;
|
||||
// get filename, determine file type
|
||||
std::string filename(argv[1]);
|
||||
bool binary = (filename.find(".mjb")!=std::string::npos);
|
||||
|
||||
// all-thread summary
|
||||
if( nthread>1 )
|
||||
{
|
||||
printf("Summary for all %d threads\n\n", nthread);
|
||||
printf(" Total simulation time : %.2f s\n", tottime);
|
||||
printf(" Total steps per second : %.0f\n", nthread*nstep/tottime);
|
||||
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));
|
||||
// load model
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
printf(" Simulation time : %.2f s\n", simtime[0]);
|
||||
printf(" Steps per second : %.0f\n", nstep/simtime[0]);
|
||||
printf(" Realtime factor : %.2f x\n", nstep*m->opt.timestep/simtime[0]);
|
||||
printf(" Time per step : %.4f ms\n\n", 1000*simtime[0]/nstep);
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
printf(" %16s : %.5f (%6.2f %%)\n", mjTIMERSTRING[i],
|
||||
// install timer callback for profiling if requested
|
||||
tm_start = std::chrono::system_clock::now();
|
||||
if (profile) {
|
||||
mjcb_time = gettm;
|
||||
}
|
||||
|
||||
// print start
|
||||
if (nthread>1) {
|
||||
std::printf("\nRunning %d steps per thread at dt = %g ...\n\n", nstep, m->opt.timestep);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// free per-thread data
|
||||
for( int id=0; id<nthread; id++ )
|
||||
mj_deleteData(d[id]);
|
||||
// free per-thread data
|
||||
for (int id=0; id<nthread; id++) {
|
||||
mj_deleteData(d[id]);
|
||||
}
|
||||
|
||||
// finalize
|
||||
return finish();
|
||||
// finalize
|
||||
return finish();
|
||||
}
|
||||
|
||||
Regular → Executable
+107
-111
@@ -12,163 +12,159 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "mujoco.h"
|
||||
#include "mjxmacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#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
|
||||
const char helpstring[] = "\n Usage: testxml modelfile.xml\n";
|
||||
|
||||
|
||||
// deallocate and print message
|
||||
int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0)
|
||||
{
|
||||
// deallocated everything
|
||||
if( d )
|
||||
mj_deleteData(d);
|
||||
if( m )
|
||||
mj_deleteModel(m);
|
||||
int finish(const char* msg = 0, mjModel* m = 0, mjData* d = 0) {
|
||||
// deallocated everything
|
||||
if (d) {
|
||||
mj_deleteData(d);
|
||||
}
|
||||
if (m) {
|
||||
mj_deleteModel(m);
|
||||
}
|
||||
|
||||
// print message
|
||||
if( msg )
|
||||
printf("%s\n", msg);
|
||||
// print message
|
||||
if (msg) {
|
||||
std::printf("%s\n", msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// return absolute difference if it is below 1, relative difference otherwise
|
||||
static mjtNum _compare(mjtNum val1, mjtNum val2)
|
||||
{
|
||||
mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2));
|
||||
static mjtNum _compare(mjtNum val1, mjtNum val2) {
|
||||
mjtNum magnitude = mju_max(mju_abs(val1), mju_abs(val2));
|
||||
|
||||
if( magnitude>1.0 )
|
||||
return mju_abs(val1-val2) / magnitude;
|
||||
else
|
||||
return mju_abs(val1-val2);
|
||||
if (magnitude>1.0) {
|
||||
return mju_abs(val1-val2) / magnitude;
|
||||
} else {
|
||||
return mju_abs(val1-val2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// compare two models, return largest difference and field name
|
||||
mjtNum compareModel(const mjModel* m1, const mjModel* m2, char* field)
|
||||
{
|
||||
int r, c;
|
||||
mjtNum dif, maxdif = 0.0;
|
||||
mjtNum compareModel(const mjModel* m1, const mjModel* m2, char (&field)[kFieldSize]) {
|
||||
int r, c;
|
||||
mjtNum dif, maxdif = 0.0;
|
||||
|
||||
// define symbols corresponding to number of columns (needed in MJMODEL_POINTERS)
|
||||
int nq = m1->nq;
|
||||
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;
|
||||
// define symbols corresponding to number of columns (needed in MJMODEL_POINTERS)
|
||||
MJMODEL_POINTERS_PREAMBLE(m1);
|
||||
|
||||
// compare ints
|
||||
#define X(name) if(m1->name!=m2->name) {strcpy(field, #name); return 1.0;}
|
||||
// compare ints
|
||||
#define X(name) if(m1->name!=m2->name) {mju::strcpy_arr(field, #name); return 1.0;}
|
||||
|
||||
MJMODEL_INTS
|
||||
#undef X
|
||||
MJMODEL_INTS
|
||||
#undef X
|
||||
|
||||
// compare arrays
|
||||
#define X(type, name, nr, nc) \
|
||||
for( r=0; r<m1->nr; r++ ) \
|
||||
for( c=0; c<nc; c++ ) { \
|
||||
dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \
|
||||
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} }
|
||||
#define X(type, name, nr, nc) \
|
||||
for( r=0; r<m1->nr; r++ ) \
|
||||
for( c=0; c<nc; c++ ) { \
|
||||
dif = _compare(m1->name[r*nc+c], m2->name[r*nc+c]); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
|
||||
|
||||
MJMODEL_POINTERS
|
||||
#undef X
|
||||
MJMODEL_POINTERS
|
||||
#undef X
|
||||
|
||||
// compare scalars in mjOption
|
||||
#define X(type, name) \
|
||||
dif = _compare(m1->opt.name, m2->opt.name); \
|
||||
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);}
|
||||
// compare scalars in mjOption
|
||||
#define X(type, name) \
|
||||
dif = _compare(m1->opt.name, m2->opt.name); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);}
|
||||
|
||||
MJOPTION_SCALARS
|
||||
#undef X
|
||||
MJOPTION_SCALARS
|
||||
#undef X
|
||||
|
||||
// compare arrays in mjOption
|
||||
#define X(name, n) \
|
||||
for( c=0; c<n; c++ ) { \
|
||||
dif = _compare(m1->opt.name[c], m2->opt.name[c]); \
|
||||
if(dif>maxdif) {maxdif=dif; strcpy(field, #name);} }
|
||||
// compare arrays in mjOption
|
||||
#define X(name, n) \
|
||||
for( c=0; c<n; c++ ) { \
|
||||
dif = _compare(m1->opt.name[c], m2->opt.name[c]); \
|
||||
if(dif>maxdif) {maxdif=dif; mju::strcpy_arr(field, #name);} }
|
||||
|
||||
MJOPTION_VECTORS
|
||||
#undef X
|
||||
MJOPTION_VECTORS
|
||||
#undef X
|
||||
|
||||
// mjVisual and mjStatistics ignored for now
|
||||
// mjVisual and mjStatistics ignored for now
|
||||
|
||||
return maxdif;
|
||||
return maxdif;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// main function
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
// print help if arguments are missing
|
||||
if( argc<2 )
|
||||
return finish(helpstring);
|
||||
int main(int argc, const char** argv) {
|
||||
// print help if arguments are missing
|
||||
if (argc<2) {
|
||||
return finish(helpstring);
|
||||
}
|
||||
|
||||
// get filename, check file type
|
||||
std::string filename(argv[1]);
|
||||
if( filename.find(".xml")==std::string::npos )
|
||||
return finish("xml model file is required");
|
||||
// get filename, check file type
|
||||
std::string filename(argv[1]);
|
||||
if (filename.find(".xml")==std::string::npos) {
|
||||
return finish("xml model file is required");
|
||||
}
|
||||
|
||||
// load model
|
||||
char error[1000];
|
||||
mjModel* m = mj_loadXML(argv[1], 0, error, 1000);
|
||||
if( !m )
|
||||
return finish(error);
|
||||
// load model
|
||||
char error[1000];
|
||||
mjModel* m = mj_loadXML(argv[1], 0, error, 1000);
|
||||
if (!m) {
|
||||
return finish(error);
|
||||
}
|
||||
|
||||
// make data
|
||||
mjData* d = mj_makeData(m);
|
||||
if( !d )
|
||||
return finish("Could not allocate mjData", m);
|
||||
// make data
|
||||
mjData* d = mj_makeData(m);
|
||||
if (!d) {
|
||||
return finish("Could not allocate mjData", m);
|
||||
}
|
||||
|
||||
// prepare temp filename in the same directory as original (for asset loading)
|
||||
std::string tempfile;
|
||||
size_t lastpath = filename.find_last_of("/\\");
|
||||
if( lastpath==std::string::npos )
|
||||
tempfile = "_tempfile_.xml";
|
||||
else
|
||||
tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml";
|
||||
// prepare temp filename in the same directory as original (for asset loading)
|
||||
std::string tempfile;
|
||||
std::size_t lastpath = filename.find_last_of("/\\");
|
||||
if (lastpath==std::string::npos) {
|
||||
tempfile = "_tempfile_.xml";
|
||||
} else {
|
||||
tempfile = filename.substr(0, lastpath+1) + "_tempfile_.xml";
|
||||
}
|
||||
|
||||
// save
|
||||
if( !mj_saveLastXML(tempfile.c_str(), m, error, 1000) )
|
||||
return finish(error, m, d);
|
||||
// save
|
||||
if (!mj_saveLastXML(tempfile.c_str(), m, error, 1000)) {
|
||||
return finish(error, m, d);
|
||||
}
|
||||
|
||||
// load back
|
||||
mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100);
|
||||
if( !mtemp )
|
||||
return finish(error, m, d);
|
||||
// load back
|
||||
mjModel* mtemp = mj_loadXML(tempfile.c_str(), 0, error, 100);
|
||||
if (!mtemp) {
|
||||
return finish(error, m, d);
|
||||
}
|
||||
|
||||
// compare
|
||||
char field[500] = "";
|
||||
mjtNum result = compareModel(m, mtemp, field);
|
||||
printf("\nComparison of original and saved model\n");
|
||||
printf(" Max difference : %.3g\n", result);
|
||||
printf(" Field name : %s\n", field);
|
||||
// compare
|
||||
char field[kFieldSize] = "";
|
||||
mjtNum result = compareModel(m, mtemp, field);
|
||||
std::printf("\nComparison of original and saved model\n");
|
||||
std::printf(" Max difference : %.3g\n", result);
|
||||
std::printf(" Field name : %s\n", field);
|
||||
|
||||
// delete temp model and file
|
||||
mj_deleteModel(mtemp);
|
||||
remove(tempfile.c_str());
|
||||
// delete temp model and file
|
||||
mj_deleteModel(mtemp);
|
||||
remove(tempfile.c_str());
|
||||
|
||||
// finalize
|
||||
return finish();
|
||||
// finalize
|
||||
return finish();
|
||||
}
|
||||
|
||||
Executable → Regular
+205
-214
@@ -13,221 +13,216 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "uitools.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//-------------------------------- Internal GLFW callbacks ------------------------------
|
||||
|
||||
// update state
|
||||
static void uiUpdateState(GLFWwindow* wnd)
|
||||
{
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
static void uiUpdateState(GLFWwindow* wnd) {
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// mouse buttons
|
||||
state->left = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
state->right = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
state->middle = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
// mouse buttons
|
||||
state->left = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_LEFT)==GLFW_PRESS);
|
||||
state->right = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_RIGHT)==GLFW_PRESS);
|
||||
state->middle = (glfwGetMouseButton(wnd, GLFW_MOUSE_BUTTON_MIDDLE)==GLFW_PRESS);
|
||||
|
||||
// keyboard modifiers
|
||||
state->control = (glfwGetKey(wnd, GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_CONTROL)==GLFW_PRESS);
|
||||
state->shift = (glfwGetKey(wnd, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
state->alt = (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS);
|
||||
// keyboard modifiers
|
||||
state->control = (glfwGetKey(wnd, GLFW_KEY_LEFT_CONTROL)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_CONTROL)==GLFW_PRESS);
|
||||
state->shift = (glfwGetKey(wnd, GLFW_KEY_LEFT_SHIFT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_SHIFT)==GLFW_PRESS);
|
||||
state->alt = (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS);
|
||||
|
||||
// swap left and right if Alt
|
||||
if( state->alt )
|
||||
{
|
||||
int tmp = state->left;
|
||||
state->left = state->right;
|
||||
state->right = tmp;
|
||||
}
|
||||
// swap left and right if Alt
|
||||
if (state->alt) {
|
||||
int tmp = state->left;
|
||||
state->left = state->right;
|
||||
state->right = tmp;
|
||||
}
|
||||
|
||||
// get mouse position, scale by buffer-to-window ratio
|
||||
double x, y;
|
||||
glfwGetCursorPos(wnd, &x, &y);
|
||||
x *= ptr->buffer2window;
|
||||
y *= ptr->buffer2window;
|
||||
// get mouse position, scale by buffer-to-window ratio
|
||||
double x, y;
|
||||
glfwGetCursorPos(wnd, &x, &y);
|
||||
x *= ptr->buffer2window;
|
||||
y *= ptr->buffer2window;
|
||||
|
||||
// invert y to match OpenGL convention
|
||||
y = state->rect[0].height - y;
|
||||
// invert y to match OpenGL convention
|
||||
y = state->rect[0].height - y;
|
||||
|
||||
// save
|
||||
state->dx = x - state->x;
|
||||
state->dy = y - state->y;
|
||||
state->x = x;
|
||||
state->y = y;
|
||||
// save
|
||||
state->dx = x - state->x;
|
||||
state->dy = y - state->y;
|
||||
state->x = x;
|
||||
state->y = y;
|
||||
|
||||
// find mouse rectangle
|
||||
state->mouserect = mjr_findRect(mju_round(x), mju_round(y),
|
||||
state->nrect-1, state->rect+1) + 1;
|
||||
// find mouse rectangle
|
||||
state->mouserect = mjr_findRect(mju_round(x), mju_round(y), state->nrect-1, state->rect+1) + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// keyboard
|
||||
static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods)
|
||||
{
|
||||
// release: nothing to do
|
||||
if( act==GLFW_RELEASE )
|
||||
return;
|
||||
static void uiKeyboard(GLFWwindow* wnd, int key, int scancode, int act, int mods) {
|
||||
// release: nothing to do
|
||||
if (act==GLFW_RELEASE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
|
||||
// set key info
|
||||
state->type = mjEVENT_KEY;
|
||||
state->key = key;
|
||||
state->keytime = glfwGetTime();
|
||||
// set key info
|
||||
state->type = mjEVENT_KEY;
|
||||
state->key = key;
|
||||
state->keytime = glfwGetTime();
|
||||
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// mouse button
|
||||
static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods)
|
||||
{
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
static void uiMouseButton(GLFWwindow* wnd, int button, int act, int mods) {
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
|
||||
// translate button
|
||||
if( button==GLFW_MOUSE_BUTTON_LEFT )
|
||||
button = mjBUTTON_LEFT;
|
||||
else if( button==GLFW_MOUSE_BUTTON_RIGHT )
|
||||
button = mjBUTTON_RIGHT;
|
||||
else
|
||||
button = mjBUTTON_MIDDLE;
|
||||
// translate button
|
||||
if (button==GLFW_MOUSE_BUTTON_LEFT) {
|
||||
button = mjBUTTON_LEFT;
|
||||
} else if (button==GLFW_MOUSE_BUTTON_RIGHT) {
|
||||
button = mjBUTTON_RIGHT;
|
||||
} else {
|
||||
button = mjBUTTON_MIDDLE;
|
||||
}
|
||||
|
||||
// swap left and right if Alt
|
||||
if( glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS )
|
||||
{
|
||||
if( button==mjBUTTON_LEFT )
|
||||
button = mjBUTTON_RIGHT;
|
||||
else if( button==mjBUTTON_RIGHT )
|
||||
button = mjBUTTON_LEFT;
|
||||
// swap left and right if Alt
|
||||
if (glfwGetKey(wnd, GLFW_KEY_LEFT_ALT)==GLFW_PRESS ||
|
||||
glfwGetKey(wnd, GLFW_KEY_RIGHT_ALT)==GLFW_PRESS) {
|
||||
if (button==mjBUTTON_LEFT) {
|
||||
button = mjBUTTON_RIGHT;
|
||||
} else if (button==mjBUTTON_RIGHT) {
|
||||
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
|
||||
if( act==GLFW_PRESS )
|
||||
{
|
||||
// detect doubleclick: 250 ms
|
||||
if( button==state->button && glfwGetTime()-state->buttontime<0.25 )
|
||||
state->doubleclick = 1;
|
||||
else
|
||||
state->doubleclick = 0;
|
||||
// set info
|
||||
state->type = mjEVENT_PRESS;
|
||||
state->button = button;
|
||||
state->buttontime = glfwGetTime();
|
||||
|
||||
// set info
|
||||
state->type = mjEVENT_PRESS;
|
||||
state->button = button;
|
||||
state->buttontime = glfwGetTime();
|
||||
|
||||
// start dragging
|
||||
if( state->mouserect )
|
||||
{
|
||||
state->dragbutton = state->button;
|
||||
state->dragrect = state->mouserect;
|
||||
}
|
||||
// start dragging
|
||||
if (state->mouserect) {
|
||||
state->dragbutton = state->button;
|
||||
state->dragrect = state->mouserect;
|
||||
}
|
||||
}
|
||||
|
||||
// release
|
||||
else
|
||||
state->type = mjEVENT_RELEASE;
|
||||
// release
|
||||
else {
|
||||
state->type = mjEVENT_RELEASE;
|
||||
}
|
||||
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
|
||||
// stop dragging after application processing
|
||||
if( state->type==mjEVENT_RELEASE )
|
||||
{
|
||||
state->dragrect = 0;
|
||||
state->dragbutton = 0;
|
||||
}
|
||||
// stop dragging after application processing
|
||||
if (state->type==mjEVENT_RELEASE) {
|
||||
state->dragrect = 0;
|
||||
state->dragbutton = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// mouse move
|
||||
static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos)
|
||||
{
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
static void uiMouseMove(GLFWwindow* wnd, double xpos, double ypos) {
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// no buttons down: nothing to do
|
||||
if( !state->left && !state->right && !state->middle )
|
||||
return;
|
||||
// no buttons down: nothing to do
|
||||
if (!state->left && !state->right && !state->middle) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
|
||||
// set move info
|
||||
state->type = mjEVENT_MOVE;
|
||||
// set move info
|
||||
state->type = mjEVENT_MOVE;
|
||||
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// scroll
|
||||
static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset)
|
||||
{
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
static void uiScroll(GLFWwindow* wnd, double xoffset, double yoffset) {
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
|
||||
// set scroll info, scale by buffer-to-window ratio
|
||||
state->type = mjEVENT_SCROLL;
|
||||
state->sx = xoffset * ptr->buffer2window;
|
||||
state->sy = yoffset * ptr->buffer2window;
|
||||
// set scroll info, scale by buffer-to-window ratio
|
||||
state->type = mjEVENT_SCROLL;
|
||||
state->sx = xoffset * ptr->buffer2window;
|
||||
state->sy = yoffset * ptr->buffer2window;
|
||||
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
// application-specific processing
|
||||
ptr->uiEvent(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// resize
|
||||
static void uiResize(GLFWwindow* wnd, int width, int height)
|
||||
{
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
static void uiResize(GLFWwindow* wnd, int width, int height) {
|
||||
// extract data from user pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*)glfwGetWindowUserPointer(wnd);
|
||||
mjuiState* state = ptr->state;
|
||||
|
||||
// set layout
|
||||
ptr->uiLayout(state);
|
||||
// set layout
|
||||
ptr->uiLayout(state);
|
||||
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
// update state
|
||||
uiUpdateState(wnd);
|
||||
|
||||
// set resize info
|
||||
state->type = mjEVENT_RESIZE;
|
||||
// set resize info
|
||||
state->type = mjEVENT_RESIZE;
|
||||
|
||||
// stop dragging
|
||||
state->dragbutton = 0;
|
||||
state->dragrect = 0;
|
||||
// stop dragging
|
||||
state->dragbutton = 0;
|
||||
state->dragrect = 0;
|
||||
|
||||
// application-specific processing (unless called with 0,0 from uiModify)
|
||||
if( width && height )
|
||||
ptr->uiEvent(state);
|
||||
// application-specific processing (unless called with 0,0 from uiModify)
|
||||
if (width && height) {
|
||||
ptr->uiEvent(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,88 +230,84 @@ static void uiResize(GLFWwindow* wnd, int width, int height)
|
||||
//----------------------------------- Public API ----------------------------------------
|
||||
|
||||
// Compute suitable font scale.
|
||||
int uiFontScale(GLFWwindow* wnd)
|
||||
{
|
||||
// compute framebuffer-to-window ratio
|
||||
int width_win, width_buf, height;
|
||||
glfwGetWindowSize(wnd, &width_win, &height);
|
||||
glfwGetFramebufferSize(wnd, &width_buf, &height);
|
||||
double b2w = (double)width_buf / (double)width_win;
|
||||
int uiFontScale(GLFWwindow* wnd) {
|
||||
// compute framebuffer-to-window ratio
|
||||
int width_win, width_buf, height;
|
||||
glfwGetWindowSize(wnd, &width_win, &height);
|
||||
glfwGetFramebufferSize(wnd, &width_buf, &height);
|
||||
double b2w = (double)width_buf / (double)width_win;
|
||||
|
||||
// compute PPI
|
||||
int width_MM, height_MM;
|
||||
glfwGetMonitorPhysicalSize(glfwGetPrimaryMonitor(), &width_MM, &height_MM);
|
||||
int width_vmode = glfwGetVideoMode(glfwGetPrimaryMonitor())->width;
|
||||
double PPI = 25.4 * b2w * (double)width_vmode / (double)width_MM;
|
||||
// compute PPI
|
||||
int width_MM, height_MM;
|
||||
glfwGetMonitorPhysicalSize(glfwGetPrimaryMonitor(), &width_MM, &height_MM);
|
||||
int width_vmode = glfwGetVideoMode(glfwGetPrimaryMonitor())->width;
|
||||
double PPI = 25.4 * b2w * (double)width_vmode / (double)width_MM;
|
||||
|
||||
// estimate font scaling, guard against unrealistic PPI
|
||||
int fs;
|
||||
if( width_buf>width_win )
|
||||
fs = mju_round(b2w * 100);
|
||||
else if( PPI>50 && PPI<350 )
|
||||
fs = mju_round(PPI);
|
||||
else
|
||||
fs = 150;
|
||||
fs = mju_round(fs * 0.02) * 50;
|
||||
fs = mjMIN(300, mjMAX(100, fs));
|
||||
// estimate font scaling, guard against unrealistic PPI
|
||||
int fs;
|
||||
if (width_buf>width_win) {
|
||||
fs = mju_round(b2w * 100);
|
||||
} else if (PPI>50 && PPI<350) {
|
||||
fs = mju_round(PPI);
|
||||
} else {
|
||||
fs = 150;
|
||||
}
|
||||
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.
|
||||
void uiSetCallback(GLFWwindow* wnd, mjuiState* state,
|
||||
uiEventFn uiEvent, uiLayoutFn uiLayout)
|
||||
{
|
||||
// make container with user-supplied objects and set window pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*) mju_malloc(sizeof(uiUserPointer));
|
||||
ptr->state = state;
|
||||
ptr->uiEvent = uiEvent;
|
||||
ptr->uiLayout = uiLayout;
|
||||
glfwSetWindowUserPointer(wnd, ptr);
|
||||
uiEventFn uiEvent, uiLayoutFn uiLayout) {
|
||||
// make container with user-supplied objects and set window pointer
|
||||
uiUserPointer* ptr = (uiUserPointer*) mju_malloc(sizeof(uiUserPointer));
|
||||
ptr->state = state;
|
||||
ptr->uiEvent = uiEvent;
|
||||
ptr->uiLayout = uiLayout;
|
||||
glfwSetWindowUserPointer(wnd, ptr);
|
||||
|
||||
// compute framebuffer-to-window pixel ratio
|
||||
int width_win, width_buf, height;
|
||||
glfwGetWindowSize(wnd, &width_win, &height);
|
||||
glfwGetFramebufferSize(wnd, &width_buf, &height);
|
||||
ptr->buffer2window = (double)width_buf / (double)width_win;
|
||||
// compute framebuffer-to-window pixel ratio
|
||||
int width_win, width_buf, height;
|
||||
glfwGetWindowSize(wnd, &width_win, &height);
|
||||
glfwGetFramebufferSize(wnd, &width_buf, &height);
|
||||
ptr->buffer2window = (double)width_buf / (double)width_win;
|
||||
|
||||
// set internal callbacks
|
||||
glfwSetKeyCallback(wnd, uiKeyboard);
|
||||
glfwSetCursorPosCallback(wnd, uiMouseMove);
|
||||
glfwSetMouseButtonCallback(wnd, uiMouseButton);
|
||||
glfwSetScrollCallback(wnd, uiScroll);
|
||||
glfwSetWindowSizeCallback(wnd, uiResize);
|
||||
// set internal callbacks
|
||||
glfwSetKeyCallback(wnd, uiKeyboard);
|
||||
glfwSetCursorPosCallback(wnd, uiMouseMove);
|
||||
glfwSetMouseButtonCallback(wnd, uiMouseButton);
|
||||
glfwSetScrollCallback(wnd, uiScroll);
|
||||
glfwSetWindowSizeCallback(wnd, uiResize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Clear UI callbacks in GLFW window.
|
||||
void uiClearCallback(GLFWwindow* wnd)
|
||||
{
|
||||
// clear container
|
||||
if( glfwGetWindowUserPointer(wnd) )
|
||||
{
|
||||
mju_free(glfwGetWindowUserPointer(wnd));
|
||||
glfwSetWindowUserPointer(wnd, NULL);
|
||||
}
|
||||
void uiClearCallback(GLFWwindow* wnd) {
|
||||
// clear container
|
||||
if (glfwGetWindowUserPointer(wnd)) {
|
||||
mju_free(glfwGetWindowUserPointer(wnd));
|
||||
glfwSetWindowUserPointer(wnd, NULL);
|
||||
}
|
||||
|
||||
// clear internal callbacks
|
||||
glfwSetKeyCallback(wnd, NULL);
|
||||
glfwSetCursorPosCallback(wnd, NULL);
|
||||
glfwSetMouseButtonCallback(wnd, NULL);
|
||||
glfwSetScrollCallback(wnd, NULL);
|
||||
glfwSetWindowSizeCallback(wnd, NULL);
|
||||
// clear internal callbacks
|
||||
glfwSetKeyCallback(wnd, NULL);
|
||||
glfwSetCursorPosCallback(wnd, NULL);
|
||||
glfwSetMouseButtonCallback(wnd, NULL);
|
||||
glfwSetScrollCallback(wnd, NULL);
|
||||
glfwSetWindowSizeCallback(wnd, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Modify UI structure.
|
||||
void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con)
|
||||
{
|
||||
mjui_resize(ui, con);
|
||||
mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con);
|
||||
uiResize(wnd, 0, 0);
|
||||
mjui_update(-1, -1, ui, state, con);
|
||||
void uiModify(GLFWwindow* wnd, mjUI* ui, mjuiState* state, mjrContext* con) {
|
||||
mjui_resize(ui, con);
|
||||
mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con);
|
||||
uiResize(wnd, 0, 0);
|
||||
mjui_update(-1, -1, ui, state, con);
|
||||
}
|
||||
|
||||
Executable → Regular
+7
-10
@@ -16,14 +16,12 @@
|
||||
#define MUJOCO_UITOOLS_H_
|
||||
|
||||
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "mujoco.h"
|
||||
#include "glfw3.h"
|
||||
|
||||
|
||||
// this is a C-API
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
@@ -32,12 +30,11 @@ typedef void (*uiEventFn)(mjuiState* state);
|
||||
typedef void (*uiLayoutFn)(mjuiState* state);
|
||||
|
||||
// Container for GLFW window pointer.
|
||||
struct _uiUserPointer
|
||||
{
|
||||
mjuiState* state;
|
||||
uiEventFn uiEvent;
|
||||
uiLayoutFn uiLayout;
|
||||
double buffer2window;
|
||||
struct _uiUserPointer {
|
||||
mjuiState* state;
|
||||
uiEventFn uiEvent;
|
||||
uiLayoutFn uiLayout;
|
||||
double buffer2window;
|
||||
};
|
||||
typedef struct _uiUserPointer uiUserPointer;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user