Merge remote-tracking branch 'upstream/main' into tendons
This commit is contained in:
@@ -148,6 +148,7 @@ jobs:
|
|||||||
cd build &&
|
cd build &&
|
||||||
cmake ..
|
cmake ..
|
||||||
-DCMAKE_BUILD_TYPE:STRING=Release
|
-DCMAKE_BUILD_TYPE:STRING=Release
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
|
||||||
-DCMAKE_INSTALL_PREFIX:STRING=${{ matrix.tmpdir }}/mujoco_install
|
-DCMAKE_INSTALL_PREFIX:STRING=${{ matrix.tmpdir }}/mujoco_install
|
||||||
-DMUJOCO_BUILD_EXAMPLES:BOOL=OFF
|
-DMUJOCO_BUILD_EXAMPLES:BOOL=OFF
|
||||||
${{ matrix.cmake_args }}
|
${{ matrix.cmake_args }}
|
||||||
@@ -192,6 +193,7 @@ jobs:
|
|||||||
cd build &&
|
cd build &&
|
||||||
cmake ..
|
cmake ..
|
||||||
-DCMAKE_BUILD_TYPE:STRING=Release
|
-DCMAKE_BUILD_TYPE:STRING=Release
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
|
||||||
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
|
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
|
||||||
${{ matrix.cmake_args }}
|
${{ matrix.cmake_args }}
|
||||||
- name: Build samples
|
- name: Build samples
|
||||||
@@ -204,6 +206,7 @@ jobs:
|
|||||||
cd build &&
|
cd build &&
|
||||||
cmake ..
|
cmake ..
|
||||||
-DCMAKE_BUILD_TYPE:STRING=Release
|
-DCMAKE_BUILD_TYPE:STRING=Release
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION:BOOL=OFF
|
||||||
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
|
-Dmujoco_ROOT:STRING=${{ matrix.tmpdir }}/mujoco_install
|
||||||
${{ matrix.cmake_args }}
|
${{ matrix.cmake_args }}
|
||||||
- name: Build simulate
|
- name: Build simulate
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ release can be found in the [changelog] in the latest branch.
|
|||||||
There are two easy ways to get started with MuJoCo:
|
There are two easy ways to get started with MuJoCo:
|
||||||
|
|
||||||
1. **Run `simulate` on your machine.**
|
1. **Run `simulate` on your machine.**
|
||||||
[This video](https://www.youtube.com/watch?v=0ORsj_E17B0) shows a screen capture
|
[This video](https://www.youtube.com/watch?v=P83tKA1iz2Y) shows a screen capture
|
||||||
of `simulate`, MuJoCo's native interactive viewer. Follow the steps described in
|
of `simulate`, MuJoCo's native interactive viewer. Follow the steps described in
|
||||||
the [Getting Started] section of the documentation to get `simulate` running on
|
the [Getting Started] section of the documentation to get `simulate` running on
|
||||||
your machine.
|
your machine.
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_INTERPROCEDURAL_OPTIMIZATION AND (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(MujocoHarden)
|
include(MujocoHarden)
|
||||||
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
||||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
||||||
|
|||||||
@@ -414,12 +414,6 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
|
|||||||
- 50
|
- 50
|
||||||
- The maximum depth of each body and mesh bounding volume hierarchy. If this large limit is exceeded, a warning
|
- The maximum depth of each body and mesh bounding volume hierarchy. If this large limit is exceeded, a warning
|
||||||
is raised and ray casting may not be possible. For a balanced hierarchy, this implies 1E15 bounding volumes.
|
is raised and ray casting may not be possible. For a balanced hierarchy, this implies 1E15 bounding volumes.
|
||||||
* - ``mjMAXVFS``
|
|
||||||
- 200
|
|
||||||
- The maximal number of characters in the name of each file in the virtual file system.
|
|
||||||
* - ``mjMAXVFSNAME``
|
|
||||||
- 100
|
|
||||||
- The maximal number of characters in the name of each file in the virtual file system.
|
|
||||||
* - ``mjNEQDATA``
|
* - ``mjNEQDATA``
|
||||||
- 11
|
- 11
|
||||||
- The maximal number of real-valued parameters used to define each equality constraint. Determines the size of
|
- The maximal number of real-valued parameters used to define each equality constraint. Determines the size of
|
||||||
@@ -534,6 +528,14 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
|
|||||||
Macros
|
Macros
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
.. _mjUSESINGLE:
|
||||||
|
|
||||||
|
mjUSESINGLE
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Compile-time flag, see :ref:`mjtNum`.
|
||||||
|
|
||||||
.. _mjDISABLED:
|
.. _mjDISABLED:
|
||||||
|
|
||||||
mjDISABLED
|
mjDISABLED
|
||||||
|
|||||||
@@ -54,24 +54,28 @@ The two types below are defined in `mjtnum.h <https://github.com/google-deepmind
|
|||||||
mjtNum
|
mjtNum
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
This is the floating-point type used throughout the simulator. If the symbol ``mjUSEDOUBLE`` is defined in
|
This is the floating-point type used throughout the simulator. When using the default build configuration, ``mjtNum`` is
|
||||||
``mjmodel.h``, this type is defined as ``double``, otherwise it is defined as ``float``. Currently only the
|
defined as ``double``. If the symbol ``mjUSESINGLE`` is defined, ``mjtNum`` is defined as ``float``.
|
||||||
double-precision version of MuJoCo is distributed, although the entire code base works with single-precision as well.
|
|
||||||
We may release the single-precision version in the future for efficiency reasons, but the double-precision version
|
|
||||||
will always be available. Thus it is safe to write user code assuming double precision. However, our preference is to
|
|
||||||
write code that works with either single or double precision. To this end we provide math utility functions that are
|
|
||||||
always defined with the correct floating-point type.
|
|
||||||
|
|
||||||
Note that changing ``mjUSEDOUBLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
|
Currently only the double-precision version of MuJoCo is distributed, although the entire code base works with
|
||||||
|
single-precision as well. We may release the single-precision version in the future, but the
|
||||||
|
double-precision version will always be available. Thus it is safe to write user code assuming double precision.
|
||||||
|
However, our preference is to write code that works with either single or double precision. To this end we provide math
|
||||||
|
utility functions that are always defined with the correct floating-point type.
|
||||||
|
|
||||||
|
Note that changing ``mjUSESINGLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
|
||||||
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
|
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
|
||||||
changed by the user.
|
changed by the user.
|
||||||
|
|
||||||
.. code-block:: C
|
.. code-block:: C
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
// floating point data type and minval
|
||||||
typedef double mjtNum;
|
#ifndef mjUSESINGLE
|
||||||
|
typedef double mjtNum;
|
||||||
|
#define mjMINVAL 1E-15 // minimum value in any denominator
|
||||||
#else
|
#else
|
||||||
typedef float mjtNum;
|
typedef float mjtNum;
|
||||||
|
#define mjMINVAL 1E-15f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -578,6 +582,18 @@ Item types used in the UI framework.
|
|||||||
|
|
||||||
.. mujoco-include:: mjtItem
|
.. mujoco-include:: mjtItem
|
||||||
|
|
||||||
|
|
||||||
|
.. _mjtSection:
|
||||||
|
|
||||||
|
mjtSection
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
State of a UI section.
|
||||||
|
|
||||||
|
.. mujoco-include:: mjtSection
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _tySpecEnums:
|
.. _tySpecEnums:
|
||||||
|
|
||||||
Spec
|
Spec
|
||||||
|
|||||||
+236
-29
@@ -1203,7 +1203,7 @@ mj_defaultVFS
|
|||||||
|
|
||||||
.. mujoco-include:: mj_defaultVFS
|
.. mujoco-include:: mj_defaultVFS
|
||||||
|
|
||||||
Initialize VFS to empty (no deallocation).
|
Initialize an empty VFS, mj_deleteVFS must be called to deallocate the VFS.
|
||||||
|
|
||||||
.. _mj_addFileVFS:
|
.. _mj_addFileVFS:
|
||||||
|
|
||||||
@@ -1224,15 +1224,6 @@ mj_addBufferVFS
|
|||||||
|
|
||||||
Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
||||||
|
|
||||||
.. _mj_findFileVFS:
|
|
||||||
|
|
||||||
mj_findFileVFS
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. mujoco-include:: mj_findFileVFS
|
|
||||||
|
|
||||||
Return file index in VFS, or -1 if not found in VFS.
|
|
||||||
|
|
||||||
.. _mj_deleteFileVFS:
|
.. _mj_deleteFileVFS:
|
||||||
|
|
||||||
mj_deleteFileVFS
|
mj_deleteFileVFS
|
||||||
@@ -1249,16 +1240,7 @@ mj_deleteVFS
|
|||||||
|
|
||||||
.. mujoco-include:: mj_deleteVFS
|
.. mujoco-include:: mj_deleteVFS
|
||||||
|
|
||||||
Delete all files from VFS.
|
Delete all files from VFS and deallocates VFS internal memory.
|
||||||
|
|
||||||
.. _mj_makeEmptyFileVFS:
|
|
||||||
|
|
||||||
mj_makeEmptyFileVFS
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. mujoco-include:: mj_makeEmptyFileVFS
|
|
||||||
|
|
||||||
deprecated: use mj_copyBufferVFS.
|
|
||||||
|
|
||||||
.. _Initialization:
|
.. _Initialization:
|
||||||
|
|
||||||
@@ -4131,6 +4113,15 @@ mjs_findFrame
|
|||||||
|
|
||||||
Find frame by name.
|
Find frame by name.
|
||||||
|
|
||||||
|
.. _mjs_findKeyframe:
|
||||||
|
|
||||||
|
mjs_findKeyframe
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_findKeyframe
|
||||||
|
|
||||||
|
Find keyframe by name.
|
||||||
|
|
||||||
.. _mjs_getDefault:
|
.. _mjs_getDefault:
|
||||||
|
|
||||||
mjs_getDefault
|
mjs_getDefault
|
||||||
@@ -4185,6 +4176,231 @@ mjs_nextChild
|
|||||||
|
|
||||||
Return body's next child of the same type; return NULL if child is last.
|
Return body's next child of the same type; return NULL if child is last.
|
||||||
|
|
||||||
|
.. _mjs_firstElement:
|
||||||
|
|
||||||
|
mjs_firstElement
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_firstElement
|
||||||
|
|
||||||
|
Return spec's first element of selected type.
|
||||||
|
|
||||||
|
.. _mjs_nextElement:
|
||||||
|
|
||||||
|
mjs_nextElement
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_nextElement
|
||||||
|
|
||||||
|
Return spec's next element; return NULL if element is last.
|
||||||
|
|
||||||
|
.. _mjs_asBody:
|
||||||
|
|
||||||
|
mjs_asBody
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asBody
|
||||||
|
|
||||||
|
Safely cast an element as mjsBody, or return NULL if the element is not an mjsBody.
|
||||||
|
|
||||||
|
.. _mjs_asGeom:
|
||||||
|
|
||||||
|
mjs_asGeom
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asGeom
|
||||||
|
|
||||||
|
Safely cast an element as mjsGeom, or return NULL if the element is not an mjsGeom.
|
||||||
|
|
||||||
|
.. _mjs_asJoint:
|
||||||
|
|
||||||
|
mjs_asJoint
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asJoint
|
||||||
|
|
||||||
|
Safely cast an element as mjsJoint, or return NULL if the element is not an mjsJoint.
|
||||||
|
|
||||||
|
.. _mjs_asSite:
|
||||||
|
|
||||||
|
mjs_asSite
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asSite
|
||||||
|
|
||||||
|
Safely cast an element as mjsSite, or return NULL if the element is not an mjsSite.
|
||||||
|
|
||||||
|
.. _mjs_asCamera:
|
||||||
|
|
||||||
|
mjs_asCamera
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asCamera
|
||||||
|
|
||||||
|
Safely cast an element as mjsCamera, or return NULL if the element is not an mjsCamera.
|
||||||
|
|
||||||
|
.. _mjs_asLight:
|
||||||
|
|
||||||
|
mjs_asLight
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asLight
|
||||||
|
|
||||||
|
Safely cast an element as mjsLight, or return NULL if the element is not an mjsLight.
|
||||||
|
|
||||||
|
.. _mjs_asFrame:
|
||||||
|
|
||||||
|
mjs_asFrame
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asFrame
|
||||||
|
|
||||||
|
Safely cast an element as mjsFrame, or return NULL if the element is not an mjsFrame.
|
||||||
|
|
||||||
|
.. _mjs_asActuator:
|
||||||
|
|
||||||
|
mjs_asActuator
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asActuator
|
||||||
|
|
||||||
|
Safely cast an element as mjsActuator, or return NULL if the element is not an mjsActuator.
|
||||||
|
|
||||||
|
.. _mjs_asSensor:
|
||||||
|
|
||||||
|
mjs_asSensor
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asSensor
|
||||||
|
|
||||||
|
Safely cast an element as mjsSensor, or return NULL if the element is not an mjsSensor.
|
||||||
|
|
||||||
|
.. _mjs_asFlex:
|
||||||
|
|
||||||
|
mjs_asFlex
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asFlex
|
||||||
|
|
||||||
|
Safely cast an element as mjsFlex, or return NULL if the element is not an mjsFlex.
|
||||||
|
|
||||||
|
.. _mjs_asPair:
|
||||||
|
|
||||||
|
mjs_asPair
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asPair
|
||||||
|
|
||||||
|
Safely cast an element as mjsPair, or return NULL if the element is not an mjsPair.
|
||||||
|
|
||||||
|
.. _mjs_asEquality:
|
||||||
|
|
||||||
|
mjs_asEquality
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asEquality
|
||||||
|
|
||||||
|
Safely cast an element as mjsEquality, or return NULL if the element is not an mjsEquality.
|
||||||
|
|
||||||
|
.. _mjs_asExclude:
|
||||||
|
|
||||||
|
mjs_asExclude
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asExclude
|
||||||
|
|
||||||
|
Safely cast an element as mjsExclude, or return NULL if the element is not an mjsExclude.
|
||||||
|
|
||||||
|
.. _mjs_asTendon:
|
||||||
|
|
||||||
|
mjs_asTendon
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asTendon
|
||||||
|
|
||||||
|
Safely cast an element as mjsTendon, or return NULL if the element is not an mjsTendon.
|
||||||
|
|
||||||
|
.. _mjs_asNumeric:
|
||||||
|
|
||||||
|
mjs_asNumeric
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asNumeric
|
||||||
|
|
||||||
|
Safely cast an element as mjsNumeric, or return NULL if the element is not an mjsNumeric.
|
||||||
|
|
||||||
|
.. _mjs_asText:
|
||||||
|
|
||||||
|
mjs_asText
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asText
|
||||||
|
|
||||||
|
Safely cast an element as mjsText, or return NULL if the element is not an mjsText.
|
||||||
|
|
||||||
|
.. _mjs_asTuple:
|
||||||
|
|
||||||
|
mjs_asTuple
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asTuple
|
||||||
|
|
||||||
|
Safely cast an element as mjsTuple, or return NULL if the element is not an mjsTuple.
|
||||||
|
|
||||||
|
.. _mjs_asKey:
|
||||||
|
|
||||||
|
mjs_asKey
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asKey
|
||||||
|
|
||||||
|
Safely cast an element as mjsKey, or return NULL if the element is not an mjsKey.
|
||||||
|
|
||||||
|
.. _mjs_asMesh:
|
||||||
|
|
||||||
|
mjs_asMesh
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asMesh
|
||||||
|
|
||||||
|
Safely cast an element as mjsMesh, or return NULL if the element is not an mjsMesh.
|
||||||
|
|
||||||
|
.. _mjs_asHField:
|
||||||
|
|
||||||
|
mjs_asHField
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asHField
|
||||||
|
|
||||||
|
Safely cast an element as mjsHField, or return NULL if the element is not an mjsHField.
|
||||||
|
|
||||||
|
.. _mjs_asSkin:
|
||||||
|
|
||||||
|
mjs_asSkin
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asSkin
|
||||||
|
|
||||||
|
Safely cast an element as mjsSkin, or return NULL if the element is not an mjsSkin.
|
||||||
|
|
||||||
|
.. _mjs_asTexture:
|
||||||
|
|
||||||
|
mjs_asTexture
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asTexture
|
||||||
|
|
||||||
|
Safely cast an element as mjsTexture, or return NULL if the element is not an mjsTexture.
|
||||||
|
|
||||||
|
.. _mjs_asMaterial:
|
||||||
|
|
||||||
|
mjs_asMaterial
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mjs_asMaterial
|
||||||
|
|
||||||
|
Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
|
|
||||||
.. _AttributeSetters:
|
.. _AttributeSetters:
|
||||||
|
|
||||||
Attribute setters
|
Attribute setters
|
||||||
@@ -4341,15 +4557,6 @@ mjs_resolveOrientation
|
|||||||
|
|
||||||
Resolve alternative orientations to quat, return error if any.
|
Resolve alternative orientations to quat, return error if any.
|
||||||
|
|
||||||
.. _mjs_fullInertia:
|
|
||||||
|
|
||||||
mjs_fullInertia
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. mujoco-include:: mjs_fullInertia
|
|
||||||
|
|
||||||
Compute quat and diag inertia from full inertia matrix, return error if any.
|
|
||||||
|
|
||||||
.. _ElementInitialization:
|
.. _ElementInitialization:
|
||||||
|
|
||||||
Element initialization
|
Element initialization
|
||||||
|
|||||||
+21
-15
@@ -1564,17 +1564,21 @@ still be specified here but this functionality is now deprecated and will be rem
|
|||||||
This and the remaining attributes control the generation of procedural textures. If the value of this attribute is
|
This and the remaining attributes control the generation of procedural textures. If the value of this attribute is
|
||||||
different from "none", the texture is treated as procedural and any file names are ignored. The keywords have the
|
different from "none", the texture is treated as procedural and any file names are ignored. The keywords have the
|
||||||
following meaning:
|
following meaning:
|
||||||
The **gradient** type generates a color gradient from rgb1 to rgb2. The interpolation in color space is done through
|
|
||||||
a sigmoid function. For cube and skybox textures the gradient is along the +Y axis, i.e., from top to bottom for
|
|
||||||
skybox rendering.
|
|
||||||
|
|
||||||
The **checker** type generates a 2-by-2 checker pattern with alternating colors given by rgb1 to rgb2. This is
|
**gradient**
|
||||||
suitable for rendering ground planes and also for marking objects with rotational symmetries. Note that 2d textures
|
Generates a color gradient from rgb1 to rgb2. The interpolation in color space is done through
|
||||||
can be scaled so as to repeat the pattern as many times as necessary. For cube and skybox textures, the checker
|
a sigmoid function. For cube and skybox textures the gradient is along the +Y axis, i.e., from top to bottom for
|
||||||
pattern is painted on each side of the cube.
|
skybox rendering.
|
||||||
|
|
||||||
The **flat** type fills the entire texture with rgb1, except for the bottom face of cube and skybox textures which is
|
**checker**
|
||||||
filled with rgb2.
|
Generates a 2-by-2 checker pattern with alternating colors given by rgb1 and rgb2. This is suitable for rendering
|
||||||
|
ground planes and also for marking objects with rotational symmetries. Note that 2d textures can be scaled so as
|
||||||
|
to repeat the pattern as many times as necessary. For cube and skybox textures, the checker pattern is painted on
|
||||||
|
each side of the cube.
|
||||||
|
|
||||||
|
**flat**
|
||||||
|
Fills the entire texture with rgb1, except for the bottom face of cube and skybox textures which is
|
||||||
|
filled with rgb2.
|
||||||
|
|
||||||
.. _asset-texture-rgb1:
|
.. _asset-texture-rgb1:
|
||||||
|
|
||||||
@@ -1604,21 +1608,23 @@ still be specified here but this functionality is now deprecated and will be rem
|
|||||||
|
|
||||||
:at:`random`: :at-val:`real, "0.01"`
|
:at:`random`: :at-val:`real, "0.01"`
|
||||||
When the mark attribute is set to "random", this attribute determines the probability of turning on each pixel. Note
|
When the mark attribute is set to "random", this attribute determines the probability of turning on each pixel. Note
|
||||||
that larger textures have more pixels, and the probability here is applied independently to each pixel - thus the
|
that larger textures have more pixels, and the probability here is applied independently to each pixel -- thus the
|
||||||
texture size and probability need to be adjusted jointly. Together with a gradient skybox texture, this can create
|
texture size and probability need to be adjusted jointly. Together with a gradient skybox texture, this can create
|
||||||
the appearance of a night sky with stars.
|
the appearance of a night sky with stars. The random number generator is initialized with a fixed seed.
|
||||||
|
|
||||||
.. _asset-texture-width:
|
.. _asset-texture-width:
|
||||||
|
|
||||||
:at:`width`: :at-val:`int, "0"`
|
:at:`width`: :at-val:`int, "0"`
|
||||||
The width of the procedural texture, i.e., the number of columns in the image. For cube and skybox procedural
|
The width of a procedural texture, i.e., the number of columns in the image. Larger values usually result in higher
|
||||||
textures the width and height must be equal. Larger values usually result in higher quality images, although in some
|
quality images, although in some cases (e.g. checker patterns) small values are sufficient. For textures loaded from
|
||||||
cases (e.g. checker patterns) small values are sufficient.
|
files, this attribute is ignored.
|
||||||
|
|
||||||
.. _asset-texture-height:
|
.. _asset-texture-height:
|
||||||
|
|
||||||
:at:`height`: :at-val:`int, "0"`
|
:at:`height`: :at-val:`int, "0"`
|
||||||
The height of the procedural texture, i.e., the number of rows in the image.
|
The height of the procedural texture, i.e., the number of rows in the image. For cube and skybox textures, this
|
||||||
|
attribute is ignored and the height is set to 6 times the width. For textures loaded from files, this attribute is
|
||||||
|
ignored.
|
||||||
|
|
||||||
.. _asset-texture-hflip:
|
.. _asset-texture-hflip:
|
||||||
|
|
||||||
|
|||||||
+53
-13
@@ -7,30 +7,70 @@ Upcoming version (not yet released)
|
|||||||
|
|
||||||
General
|
General
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
1. Added a new API for :doc:`procedural model manipulation<programming/modeledit>`. Fixes :github:issue:`364`.
|
.. admonition:: Breaking API changes
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
1. Removed deprecated ``mj_makeEmptyFileVFS`` and ``mj_findFileVFS`` functions. The constants ``mjMAXVFS`` and
|
||||||
|
``mjMAXVFSNAME`` are also removed as they are no longer needed.
|
||||||
|
|
||||||
|
**Migration:** Use :ref:`mj_addBufferVFS` to copy a buffer into a VFS file directly.
|
||||||
|
|
||||||
|
2. Calls to :ref:`mj_defaultVFS` may allocate memory inside VFS, and the corresponding
|
||||||
|
:ref:`mj_deleteVFS` must be called to deallocate any internal allocated memory.
|
||||||
|
|
||||||
|
3. Deprecated :ref:`mju_rotVecMat` and :ref:`mju_rotVecMatT` in favor of :ref:`mju_mulMatVec3` and
|
||||||
|
:ref:`mju_mulMatTVec3`. These function names and argument order are more consistent with the rest of the API.
|
||||||
|
The older functions have been removed from the Python bindings and will be removed from the C API in the next
|
||||||
|
release.
|
||||||
|
|
||||||
|
4. The :ref:`VFS<Virtualfilesystem>` implementation has been rewritten in C++ and is now considerably more efficient in
|
||||||
|
speed and memory footprint.
|
||||||
|
5. Added a new API for :doc:`procedural model manipulation<programming/modeledit>`. Fixes :github:issue:`364`.
|
||||||
Still missing:
|
Still missing:
|
||||||
|
|
||||||
- Detailed documentation.
|
- Detailed documentation.
|
||||||
- Python bindings.
|
|
||||||
|
|
||||||
.. youtube:: ZXBTEIDWHhs
|
.. youtube:: ZXBTEIDWHhs
|
||||||
:align: right
|
:align: right
|
||||||
:width: 240px
|
:width: 240px
|
||||||
|
|
||||||
2. Added support for orthographic cameras. This is available for both fixed cameras and the free camera, using the
|
6. Added support for orthographic cameras. This is available for both fixed cameras and the free camera, using the
|
||||||
:ref:`camera/orthographic<body-camera-orthographic>` and :ref:`global/orthographic<visual-global-orthographic>`
|
:ref:`camera/orthographic<body-camera-orthographic>` and :ref:`global/orthographic<visual-global-orthographic>`
|
||||||
attributes, respectively.
|
attributes, respectively.
|
||||||
3. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
|
7. Added :ref:`maxhullvert<asset-mesh-maxhullvert>`, the maximum number of vertices in a mesh's convex hull.
|
||||||
4. Added :ref:`mj_setKeyframe` for saving the current state into a model keyframe.
|
8. Added :ref:`mj_setKeyframe` for saving the current state into a model keyframe.
|
||||||
5. Added support for ``ball`` joints in the URDF parser ("spherical" in URDF).
|
9. Added support for ``ball`` joints in the URDF parser ("spherical" in URDF).
|
||||||
6. Deprecated :ref:`mju_rotVecMat` and :ref:`mju_rotVecMatT` in favor of :ref:`mju_mulMatVec3` and
|
10. Replaced ``mjUSEDOUBLE`` which was previously hard-coded in
|
||||||
:ref:`mju_mulMatTVec3`. These functions names and argument ordering are more consistent with the rest of the API.
|
`mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/mjtnum.h>`__
|
||||||
|
with the build-time flag ``mjUSESINGLE``. If this symbol is not defined, MuJoCo will use double-precision floating
|
||||||
|
point, as usual. If ``mjUSESINGLE`` is defined, MuJoCo will use single-precision floating point. See :ref:`mjtNum`.
|
||||||
|
|
||||||
|
Relatedly, fixed various type errors that prevented building with single-precision.
|
||||||
|
11. Quaternions in ``mjData->qpos`` and ``mjData->mocap_quat`` are no longer normalized in-place by
|
||||||
|
:ref:`mj_kinematics`. Instead they are normalized when they are used. After the first step, quaternions in
|
||||||
|
``mjData->qpos`` will be normalized.
|
||||||
|
|
||||||
MJX
|
MJX
|
||||||
~~~
|
~~~
|
||||||
7. Added support for :ref:`elliptic friction cones<option-cone>`.
|
12. Added support for :ref:`elliptic friction cones<option-cone>`.
|
||||||
8. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings.
|
13. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings.
|
||||||
9. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients.
|
14. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients.
|
||||||
|
|
||||||
|
|
||||||
|
.. youtube:: P83tKA1iz2Y
|
||||||
|
:align: right
|
||||||
|
:width: 360px
|
||||||
|
|
||||||
|
Simulate
|
||||||
|
^^^^^^^^
|
||||||
|
15. Added improved tutorial video.
|
||||||
|
16. Improved the Brownian noise generator.
|
||||||
|
|
||||||
|
|br| |br| |br| |br|
|
||||||
|
|
||||||
|
Python bindings
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
17. Fixed a memory leak when using ``copy.deepcopy()`` on a ``mujoco.MjData`` instance (:github:issue:`1572`).
|
||||||
|
|
||||||
Version 3.1.6 (Jun 3, 2024)
|
Version 3.1.6 (Jun 3, 2024)
|
||||||
---------------------------
|
---------------------------
|
||||||
@@ -199,10 +239,10 @@ General
|
|||||||
:at:`ctrlrange` or :at:`actrange` (respectively), according to the range of the transmission
|
:at:`ctrlrange` or :at:`actrange` (respectively), according to the range of the transmission
|
||||||
target (joint or tendon). See :ref:`position/inheritrange<actuator-position-inheritrange>` for
|
target (joint or tendon). See :ref:`position/inheritrange<actuator-position-inheritrange>` for
|
||||||
details.
|
details.
|
||||||
2. Deprecated :ref:`mj_makeEmptyFileVFS` in favor of :ref:`mj_addBufferVFS`. :ref:`mjVFS` now computes checksums of
|
2. Deprecated ``mj_makeEmptyFileVFS`` in favor of :ref:`mj_addBufferVFS`. :ref:`mjVFS` now computes checksums of
|
||||||
its internal file buffers. :ref:`mj_addBufferVFS` allocates an empty buffer with a given name in an mjVFS and
|
its internal file buffers. :ref:`mj_addBufferVFS` allocates an empty buffer with a given name in an mjVFS and
|
||||||
copies the data buffer into it, combining and replacing the deprecated two-step process of calling
|
copies the data buffer into it, combining and replacing the deprecated two-step process of calling
|
||||||
:ref:`mj_makeEmptyFileVFS` followed by a direct copy into the given mjVFS internal file buffer.
|
``mj_makeEmptyFileVFS`` followed by a direct copy into the given mjVFS internal file buffer.
|
||||||
3. Added :ref:`mj_angmomMat` which computes the ``3 x nv`` angular momentum matrix :math:`H(q)`, providing the linear
|
3. Added :ref:`mj_angmomMat` which computes the ``3 x nv`` angular momentum matrix :math:`H(q)`, providing the linear
|
||||||
mapping from generalized velocities to subtree angular momentum :math:`h = H \dot q`. Contribution by
|
mapping from generalized velocities to subtree angular momentum :math:`h = H \dot q`. Contribution by
|
||||||
:github:user:`v-r-a`.
|
:github:user:`v-r-a`.
|
||||||
|
|||||||
+144
-115
@@ -139,29 +139,29 @@ struct mjData_ {
|
|||||||
int nplugin; // number of plugin instances
|
int nplugin; // number of plugin instances
|
||||||
|
|
||||||
// stack pointer
|
// stack pointer
|
||||||
size_t pstack; // first available mjtNum address in stack
|
size_t pstack; // first available byte in stack
|
||||||
size_t pbase; // value of pstack when mj_markStack was last called
|
size_t pbase; // value of pstack when mj_markStack was last called
|
||||||
|
|
||||||
// arena pointer
|
// arena pointer
|
||||||
size_t parena; // first available byte in arena
|
size_t parena; // first available byte in arena
|
||||||
|
|
||||||
// memory utilization stats
|
// memory utilization statistics
|
||||||
size_t maxuse_stack; // maximum stack allocation in bytes
|
size_t maxuse_stack; // maximum stack allocation in bytes
|
||||||
size_t maxuse_threadstack[mjMAXTHREAD]; // maximum stack allocation per thread in bytes
|
size_t maxuse_threadstack[mjMAXTHREAD]; // maximum stack allocation per thread in bytes
|
||||||
size_t maxuse_arena; // maximum arena allocation in bytes
|
size_t maxuse_arena; // maximum arena allocation in bytes
|
||||||
int maxuse_con; // maximum number of contacts
|
int maxuse_con; // maximum number of contacts
|
||||||
int maxuse_efc; // maximum number of scalar constraints
|
int maxuse_efc; // maximum number of scalar constraints
|
||||||
|
|
||||||
// diagnostics
|
|
||||||
mjWarningStat warning[mjNWARNING]; // warning statistics
|
|
||||||
mjTimerStat timer[mjNTIMER]; // timer statistics
|
|
||||||
|
|
||||||
// solver statistics
|
// solver statistics
|
||||||
mjSolverStat solver[mjNISLAND*mjNSOLVER]; // solver statistics per island, per iteration
|
mjSolverStat solver[mjNISLAND*mjNSOLVER]; // solver statistics per island, per iteration
|
||||||
int solver_nisland; // number of islands processed by solver
|
int solver_nisland; // number of islands processed by solver
|
||||||
int solver_niter[mjNISLAND]; // number of solver iterations, per island
|
int solver_niter[mjNISLAND]; // number of solver iterations, per island
|
||||||
int solver_nnz[mjNISLAND]; // number of non-zeros in Hessian or efc_AR, per island
|
int solver_nnz[mjNISLAND]; // number of nonzeros in Hessian or efc_AR, per island
|
||||||
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
||||||
|
|
||||||
|
// diagnostics
|
||||||
|
mjWarningStat warning[mjNWARNING]; // warning statistics
|
||||||
|
mjTimerStat timer[mjNTIMER]; // timer statistics
|
||||||
|
|
||||||
// variable sizes
|
// variable sizes
|
||||||
int ne; // number of equality constraints
|
int ne; // number of equality constraints
|
||||||
@@ -179,8 +179,8 @@ struct mjData_ {
|
|||||||
//-------------------- end of info header
|
//-------------------- end of info header
|
||||||
|
|
||||||
// buffers
|
// buffers
|
||||||
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
||||||
void* arena; // arena+stack buffer (nstack*sizeof(mjtNum) bytes)
|
void* arena; // arena+stack buffer (narena bytes)
|
||||||
|
|
||||||
//-------------------- main inputs and outputs of the computation
|
//-------------------- main inputs and outputs of the computation
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ struct mjData_ {
|
|||||||
|
|
||||||
// computed by mj_collisionTree
|
// computed by mj_collisionTree
|
||||||
mjtNum* bvh_aabb_dyn; // global bounding box (center, size) (nbvhdynamic x 6)
|
mjtNum* bvh_aabb_dyn; // global bounding box (center, size) (nbvhdynamic x 6)
|
||||||
mjtByte* bvh_active; // volume has been added to collisions (nbvh x 1)
|
mjtByte* bvh_active; // was bounding volume checked for collision (nbvh x 1)
|
||||||
|
|
||||||
//-------------------- POSITION, VELOCITY dependent
|
//-------------------- POSITION, VELOCITY dependent
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ struct mjData_ {
|
|||||||
//-------------------- arena-allocated: POSITION dependent
|
//-------------------- arena-allocated: POSITION dependent
|
||||||
|
|
||||||
// computed by mj_collision
|
// computed by mj_collision
|
||||||
mjContact* contact; // list of all detected contacts (ncon x 1)
|
mjContact* contact; // array of all detected contacts (ncon x 1)
|
||||||
|
|
||||||
// computed by mj_makeConstraint
|
// computed by mj_makeConstraint
|
||||||
int* efc_type; // constraint type (mjtConstraint) (nefc x 1)
|
int* efc_type; // constraint type (mjtConstraint) (nefc x 1)
|
||||||
@@ -394,11 +394,11 @@ struct mjData_ {
|
|||||||
//-------------------- arena-allocated: POSITION, VELOCITY, CONTROL/ACCELERATION dependent
|
//-------------------- arena-allocated: POSITION, VELOCITY, CONTROL/ACCELERATION dependent
|
||||||
|
|
||||||
// computed by mj_fwdConstraint/mj_inverse
|
// computed by mj_fwdConstraint/mj_inverse
|
||||||
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (nefc x 1)
|
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (nefc x 1)
|
||||||
mjtNum* efc_force; // constraint force in constraint space (nefc x 1)
|
mjtNum* efc_force; // constraint force in constraint space (nefc x 1)
|
||||||
int* efc_state; // constraint state (mjtConstraintState) (nefc x 1)
|
int* efc_state; // constraint state (mjtConstraintState) (nefc x 1)
|
||||||
|
|
||||||
// ThreadPool for multithreaded operations
|
// thread pool pointer
|
||||||
uintptr_t threadpool;
|
uintptr_t threadpool;
|
||||||
};
|
};
|
||||||
typedef struct mjData_ mjData;
|
typedef struct mjData_ mjData;
|
||||||
@@ -699,11 +699,7 @@ struct mjLROpt_ { // options for mj_setLengthRange()
|
|||||||
};
|
};
|
||||||
typedef struct mjLROpt_ mjLROpt;
|
typedef struct mjLROpt_ mjLROpt;
|
||||||
struct mjVFS_ { // virtual file system for loading from memory
|
struct mjVFS_ { // virtual file system for loading from memory
|
||||||
int nfile; // number of files present
|
void* impl_; // internal pointer to VFS memory
|
||||||
char filename[mjMAXVFS][mjMAXVFSNAME]; // file name without path
|
|
||||||
size_t filesize[mjMAXVFS]; // file size in bytes
|
|
||||||
void* filedata[mjMAXVFS]; // buffer with file data
|
|
||||||
uint64_t filestamp[mjMAXVFS]; // checksum of the file data
|
|
||||||
};
|
};
|
||||||
typedef struct mjVFS_ mjVFS;
|
typedef struct mjVFS_ mjVFS;
|
||||||
struct mjOption_ { // physics options
|
struct mjOption_ { // physics options
|
||||||
@@ -1220,7 +1216,7 @@ struct mjModel_ {
|
|||||||
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
|
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
|
||||||
|
|
||||||
// materials
|
// materials
|
||||||
int* mat_texid; // texture id; -1: none (nmat x 1)
|
int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXMAT)
|
||||||
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
|
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
|
||||||
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
|
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
|
||||||
float* mat_emission; // emission (x rgb) (nmat x 1)
|
float* mat_emission; // emission (x rgb) (nmat x 1)
|
||||||
@@ -1512,92 +1508,97 @@ struct mjrRect_ { // OpenGL rectangle
|
|||||||
int height; // height (usually buffer height)
|
int height; // height (usually buffer height)
|
||||||
};
|
};
|
||||||
typedef struct mjrRect_ mjrRect;
|
typedef struct mjrRect_ mjrRect;
|
||||||
struct mjrContext_ { // custom OpenGL context
|
struct mjrContext_ { // custom OpenGL context
|
||||||
// parameters copied from mjVisual
|
// parameters copied from mjVisual
|
||||||
float lineWidth; // line width for wireframe rendering
|
float lineWidth; // line width for wireframe rendering
|
||||||
float shadowClip; // clipping radius for directional lights
|
float shadowClip; // clipping radius for directional lights
|
||||||
float shadowScale; // fraction of light cutoff for spot lights
|
float shadowScale; // fraction of light cutoff for spot lights
|
||||||
float fogStart; // fog start = stat.extent * vis.map.fogstart
|
float fogStart; // fog start = stat.extent * vis.map.fogstart
|
||||||
float fogEnd; // fog end = stat.extent * vis.map.fogend
|
float fogEnd; // fog end = stat.extent * vis.map.fogend
|
||||||
float fogRGBA[4]; // fog rgba
|
float fogRGBA[4]; // fog rgba
|
||||||
int shadowSize; // size of shadow map texture
|
int shadowSize; // size of shadow map texture
|
||||||
int offWidth; // width of offscreen buffer
|
int offWidth; // width of offscreen buffer
|
||||||
int offHeight; // height of offscreen buffer
|
int offHeight; // height of offscreen buffer
|
||||||
int offSamples; // number of offscreen buffer multisamples
|
int offSamples; // number of offscreen buffer multisamples
|
||||||
|
|
||||||
// parameters specified at creation
|
// parameters specified at creation
|
||||||
int fontScale; // font scale
|
int fontScale; // font scale
|
||||||
int auxWidth[mjNAUX]; // auxiliary buffer width
|
int auxWidth[mjNAUX]; // auxiliary buffer width
|
||||||
int auxHeight[mjNAUX]; // auxiliary buffer height
|
int auxHeight[mjNAUX]; // auxiliary buffer height
|
||||||
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
||||||
|
|
||||||
// offscreen rendering objects
|
// offscreen rendering objects
|
||||||
unsigned int offFBO; // offscreen framebuffer object
|
unsigned int offFBO; // offscreen framebuffer object
|
||||||
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
|
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
|
||||||
unsigned int offColor; // offscreen color buffer
|
unsigned int offColor; // offscreen color buffer
|
||||||
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
|
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
|
||||||
unsigned int offDepthStencil; // offscreen depth and stencil buffer
|
unsigned int offDepthStencil; // offscreen depth and stencil buffer
|
||||||
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for resolving multisamples
|
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for multisamples
|
||||||
|
|
||||||
// shadow rendering objects
|
// shadow rendering objects
|
||||||
unsigned int shadowFBO; // shadow map framebuffer object
|
unsigned int shadowFBO; // shadow map framebuffer object
|
||||||
unsigned int shadowTex; // shadow map texture
|
unsigned int shadowTex; // shadow map texture
|
||||||
|
|
||||||
// auxiliary buffers
|
// auxiliary buffers
|
||||||
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
||||||
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
||||||
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
||||||
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
|
unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving
|
||||||
|
|
||||||
|
// materials with textures
|
||||||
|
int mat_texid[mjMAXMATERIAL*mjNTEXMAT]; // material texture ids (-1: no texture)
|
||||||
|
int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping
|
||||||
|
int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping
|
||||||
|
|
||||||
// texture objects and info
|
// texture objects and info
|
||||||
int ntexture; // number of allocated textures
|
int ntexture; // number of allocated textures
|
||||||
int textureType[100]; // type of texture (mjtTexture) (ntexture)
|
int textureType[mjMAXTEXTURE]; // type of texture (mjtTexture) (ntexture)
|
||||||
unsigned int texture[100]; // texture names
|
unsigned int texture[mjMAXTEXTURE]; // texture names
|
||||||
|
|
||||||
// displaylist starting positions
|
// displaylist starting positions
|
||||||
unsigned int basePlane; // all planes from model
|
unsigned int basePlane; // all planes from model
|
||||||
unsigned int baseMesh; // all meshes from model
|
unsigned int baseMesh; // all meshes from model
|
||||||
unsigned int baseHField; // all hfields from model
|
unsigned int baseHField; // all height fields from model
|
||||||
unsigned int baseBuiltin; // all buildin geoms, with quality from model
|
unsigned int baseBuiltin; // all builtin geoms, with quality from model
|
||||||
unsigned int baseFontNormal; // normal font
|
unsigned int baseFontNormal; // normal font
|
||||||
unsigned int baseFontShadow; // shadow font
|
unsigned int baseFontShadow; // shadow font
|
||||||
unsigned int baseFontBig; // big font
|
unsigned int baseFontBig; // big font
|
||||||
|
|
||||||
// displaylist ranges
|
// displaylist ranges
|
||||||
int rangePlane; // all planes from model
|
int rangePlane; // all planes from model
|
||||||
int rangeMesh; // all meshes from model
|
int rangeMesh; // all meshes from model
|
||||||
int rangeHField; // all hfields from model
|
int rangeHField; // all hfields from model
|
||||||
int rangeBuiltin; // all builtin geoms, with quality from model
|
int rangeBuiltin; // all builtin geoms, with quality from model
|
||||||
int rangeFont; // all characters in font
|
int rangeFont; // all characters in font
|
||||||
|
|
||||||
// skin VBOs
|
// skin VBOs
|
||||||
int nskin; // number of skins
|
int nskin; // number of skins
|
||||||
unsigned int* skinvertVBO; // skin vertex position VBOs (nskin)
|
unsigned int* skinvertVBO; // skin vertex position VBOs (nskin)
|
||||||
unsigned int* skinnormalVBO; // skin vertex normal VBOs (nskin)
|
unsigned int* skinnormalVBO; // skin vertex normal VBOs (nskin)
|
||||||
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs (nskin)
|
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs (nskin)
|
||||||
unsigned int* skinfaceVBO; // skin face index VBOs (nskin)
|
unsigned int* skinfaceVBO; // skin face index VBOs (nskin)
|
||||||
|
|
||||||
// character info
|
// character info
|
||||||
int charWidth[127]; // character widths: normal and shadow
|
int charWidth[127]; // character widths: normal and shadow
|
||||||
int charWidthBig[127]; // chacarter widths: big
|
int charWidthBig[127]; // chacarter widths: big
|
||||||
int charHeight; // character heights: normal and shadow
|
int charHeight; // character heights: normal and shadow
|
||||||
int charHeightBig; // character heights: big
|
int charHeightBig; // character heights: big
|
||||||
|
|
||||||
// capabilities
|
// capabilities
|
||||||
int glInitialized; // is OpenGL initialized
|
int glInitialized; // is OpenGL initialized
|
||||||
int windowAvailable; // is default/window framebuffer available
|
int windowAvailable; // is default/window framebuffer available
|
||||||
int windowSamples; // number of samples for default/window framebuffer
|
int windowSamples; // number of samples for default/window framebuffer
|
||||||
int windowStereo; // is stereo available for default/window framebuffer
|
int windowStereo; // is stereo available for default/window framebuffer
|
||||||
int windowDoublebuffer; // is default/window framebuffer double buffered
|
int windowDoublebuffer; // is default/window framebuffer double buffered
|
||||||
|
|
||||||
// framebuffer
|
// framebuffer
|
||||||
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
|
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
|
||||||
|
|
||||||
// pixel output format
|
// pixel output format
|
||||||
int readPixelFormat; // default color pixel format for mjr_readPixels
|
int readPixelFormat; // default color pixel format for mjr_readPixels
|
||||||
|
|
||||||
// depth output format
|
// depth output format
|
||||||
int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR
|
int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR
|
||||||
};
|
};
|
||||||
typedef struct mjrContext_ mjrContext;
|
typedef struct mjrContext_ mjrContext;
|
||||||
typedef enum mjtGeomInertia_ { // type of inertia inference
|
typedef enum mjtGeomInertia_ { // type of inertia inference
|
||||||
@@ -1649,7 +1650,7 @@ typedef struct mjSpec_ { // model specification
|
|||||||
mjtByte strippath; // automatically strip paths from mesh files
|
mjtByte strippath; // automatically strip paths from mesh files
|
||||||
mjtByte fitaabb; // meshfit to aabb instead of inertia box
|
mjtByte fitaabb; // meshfit to aabb instead of inertia box
|
||||||
mjtByte degree; // angles in radians or degrees
|
mjtByte degree; // angles in radians or degrees
|
||||||
char euler[3]; // sequence for euler rotations
|
char eulerseq[3]; // sequence for euler rotations
|
||||||
mjString* meshdir; // mesh and hfield directory
|
mjString* meshdir; // mesh and hfield directory
|
||||||
mjString* texturedir; // texture directory
|
mjString* texturedir; // texture directory
|
||||||
mjtByte discardvisual; // discard visual geoms in parser
|
mjtByte discardvisual; // discard visual geoms in parser
|
||||||
@@ -1743,7 +1744,6 @@ typedef struct mjsFrame_ { // frame specification
|
|||||||
typedef struct mjsJoint_ { // joint specification
|
typedef struct mjsJoint_ { // joint specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtJoint type; // joint type
|
mjtJoint type; // joint type
|
||||||
|
|
||||||
// kinematics
|
// kinematics
|
||||||
@@ -1781,7 +1781,6 @@ typedef struct mjsJoint_ { // joint specification
|
|||||||
typedef struct mjsGeom_ { // geom specification
|
typedef struct mjsGeom_ { // geom specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // classname
|
|
||||||
mjtGeom type; // geom type
|
mjtGeom type; // geom type
|
||||||
|
|
||||||
// frame, size
|
// frame, size
|
||||||
@@ -1828,7 +1827,6 @@ typedef struct mjsGeom_ { // geom specification
|
|||||||
typedef struct mjsSite_ { // site specification
|
typedef struct mjsSite_ { // site specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// frame, size
|
// frame, size
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -1850,7 +1848,6 @@ typedef struct mjsSite_ { // site specification
|
|||||||
typedef struct mjsCamera_ { // camera specification
|
typedef struct mjsCamera_ { // camera specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// extrinsics
|
// extrinsics
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -1878,7 +1875,6 @@ typedef struct mjsCamera_ { // camera specification
|
|||||||
typedef struct mjsLight_ { // light specification
|
typedef struct mjsLight_ { // light specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// frame
|
// frame
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -1904,7 +1900,6 @@ typedef struct mjsLight_ { // light specification
|
|||||||
typedef struct mjsFlex_ { // flex specification
|
typedef struct mjsFlex_ { // flex specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// contact properties
|
// contact properties
|
||||||
int contype; // contact type
|
int contype; // contact type
|
||||||
@@ -1943,7 +1938,6 @@ typedef struct mjsFlex_ { // flex specification
|
|||||||
typedef struct mjsMesh_ { // mesh specification
|
typedef struct mjsMesh_ { // mesh specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* content_type; // content type of file
|
mjString* content_type; // content type of file
|
||||||
mjString* file; // mesh file
|
mjString* file; // mesh file
|
||||||
double refpos[3]; // reference position
|
double refpos[3]; // reference position
|
||||||
@@ -1974,7 +1968,6 @@ typedef struct mjsHField_ { // height field specification
|
|||||||
typedef struct mjsSkin_ { // skin specification
|
typedef struct mjsSkin_ { // skin specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* file; // skin file
|
mjString* file; // skin file
|
||||||
mjString* material; // name of material used for rendering
|
mjString* material; // name of material used for rendering
|
||||||
float rgba[4]; // rgba when material is omitted
|
float rgba[4]; // rgba when material is omitted
|
||||||
@@ -1999,7 +1992,6 @@ typedef struct mjsSkin_ { // skin specification
|
|||||||
typedef struct mjsTexture_ { // texture specification
|
typedef struct mjsTexture_ { // texture specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtTexture type; // texture type
|
mjtTexture type; // texture type
|
||||||
|
|
||||||
// method 1: builtin
|
// method 1: builtin
|
||||||
@@ -2031,7 +2023,6 @@ typedef struct mjsTexture_ { // texture specification
|
|||||||
typedef struct mjsMaterial_ { // material specification
|
typedef struct mjsMaterial_ { // material specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* texture; // name of texture (empty: none)
|
mjString* texture; // name of texture (empty: none)
|
||||||
mjtByte texuniform; // make texture cube uniform
|
mjtByte texuniform; // make texture cube uniform
|
||||||
float texrepeat[2]; // texture repetition for 2D mapping
|
float texrepeat[2]; // texture repetition for 2D mapping
|
||||||
@@ -2047,7 +2038,6 @@ typedef struct mjsMaterial_ { // material specification
|
|||||||
typedef struct mjsPair_ { // pair specification
|
typedef struct mjsPair_ { // pair specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* geomname1; // name of geom 1
|
mjString* geomname1; // name of geom 1
|
||||||
mjString* geomname2; // name of geom 2
|
mjString* geomname2; // name of geom 2
|
||||||
|
|
||||||
@@ -2071,7 +2061,6 @@ typedef struct mjsExclude_ { // exclude specification
|
|||||||
typedef struct mjsEquality_ { // equality specification
|
typedef struct mjsEquality_ { // equality specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtEq type; // constraint type
|
mjtEq type; // constraint type
|
||||||
double data[mjNEQDATA]; // type-dependent data
|
double data[mjNEQDATA]; // type-dependent data
|
||||||
mjtByte active; // is equality initially active
|
mjtByte active; // is equality initially active
|
||||||
@@ -2084,7 +2073,6 @@ typedef struct mjsEquality_ { // equality specification
|
|||||||
typedef struct mjsTendon_ { // tendon specification
|
typedef struct mjsTendon_ { // tendon specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// stiffness, damping, friction
|
// stiffness, damping, friction
|
||||||
double stiffness; // stiffness coefficient
|
double stiffness; // stiffness coefficient
|
||||||
@@ -2118,7 +2106,6 @@ typedef struct mjsWrap_ { // wrapping object specification
|
|||||||
typedef struct mjsActuator_ { // actuator specification
|
typedef struct mjsActuator_ { // actuator specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// gain, bias
|
// gain, bias
|
||||||
mjtGain gaintype; // gain type
|
mjtGain gaintype; // gain type
|
||||||
@@ -2160,7 +2147,6 @@ typedef struct mjsActuator_ { // actuator specification
|
|||||||
typedef struct mjsSensor_ { // sensor specification
|
typedef struct mjsSensor_ { // sensor specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// sensor definition
|
// sensor definition
|
||||||
mjtSensor type; // type of sensor
|
mjtSensor type; // type of sensor
|
||||||
@@ -2286,6 +2272,11 @@ typedef enum mjtItem_ { // UI item type
|
|||||||
|
|
||||||
mjNITEM // number of item types
|
mjNITEM // number of item types
|
||||||
} mjtItem;
|
} mjtItem;
|
||||||
|
typedef enum mjtSection_ { // UI section state
|
||||||
|
mjSECT_CLOSED = 0, // closed state (regular section)
|
||||||
|
mjSECT_OPEN, // open state (regular section)
|
||||||
|
mjSECT_FIXED // fixed section: always open, no title
|
||||||
|
} mjtSection;
|
||||||
struct mjuiState_ { // mouse and keyboard state
|
struct mjuiState_ { // mouse and keyboard state
|
||||||
// constants set by user
|
// constants set by user
|
||||||
int nrect; // number of rectangles used
|
int nrect; // number of rectangles used
|
||||||
@@ -2333,6 +2324,8 @@ struct mjuiThemeSpacing_ { // UI visualization theme spacing
|
|||||||
int scroll; // scrollbar width
|
int scroll; // scrollbar width
|
||||||
int label; // label width
|
int label; // label width
|
||||||
int section; // section gap
|
int section; // section gap
|
||||||
|
int cornersect; // corner radius for section
|
||||||
|
int cornersep; // corner radius for separator
|
||||||
int itemside; // item side gap
|
int itemside; // item side gap
|
||||||
int itemmid; // item middle gap
|
int itemmid; // item middle gap
|
||||||
int itemver; // item vertical gap
|
int itemver; // item vertical gap
|
||||||
@@ -2346,9 +2339,14 @@ struct mjuiThemeColor_ { // UI visualization theme color
|
|||||||
float master[3]; // master background
|
float master[3]; // master background
|
||||||
float thumb[3]; // scrollbar thumb
|
float thumb[3]; // scrollbar thumb
|
||||||
float secttitle[3]; // section title
|
float secttitle[3]; // section title
|
||||||
|
float secttitle2[3]; // section title: bottom color
|
||||||
|
float secttitlecheck[3]; // section title with checkbox
|
||||||
|
float secttitlecheck2[3]; // section title with checkbox: bottom color
|
||||||
float sectfont[3]; // section font
|
float sectfont[3]; // section font
|
||||||
float sectsymbol[3]; // section symbol
|
float sectsymbol[3]; // section symbol
|
||||||
float sectpane[3]; // section pane
|
float sectpane[3]; // section pane
|
||||||
|
float separator[3]; // separator title
|
||||||
|
float separator2[3]; // separator title: bottom color
|
||||||
float shortcut[3]; // shortcut background
|
float shortcut[3]; // shortcut background
|
||||||
float fontactive[3]; // font active
|
float fontactive[3]; // font active
|
||||||
float fontinactive[3]; // font inactive
|
float fontinactive[3]; // font inactive
|
||||||
@@ -2398,6 +2396,7 @@ struct mjuiItem_ { // UI item
|
|||||||
void *pdata; // data pointer (type-specific)
|
void *pdata; // data pointer (type-specific)
|
||||||
int sectionid; // id of section containing item
|
int sectionid; // id of section containing item
|
||||||
int itemid; // id of item within section
|
int itemid; // id of item within section
|
||||||
|
int userid; // user-supplied id (for event handling)
|
||||||
|
|
||||||
// type-specific properties
|
// type-specific properties
|
||||||
union {
|
union {
|
||||||
@@ -2409,20 +2408,23 @@ struct mjuiItem_ { // UI item
|
|||||||
|
|
||||||
// internal
|
// internal
|
||||||
mjrRect rect; // rectangle occupied by item
|
mjrRect rect; // rectangle occupied by item
|
||||||
|
int skip; // item skipped due to closed separator
|
||||||
};
|
};
|
||||||
typedef struct mjuiItem_ mjuiItem;
|
typedef struct mjuiItem_ mjuiItem;
|
||||||
struct mjuiSection_ { // UI section
|
struct mjuiSection_ { // UI section
|
||||||
// properties
|
// properties
|
||||||
char name[mjMAXUINAME]; // name
|
char name[mjMAXUINAME]; // name
|
||||||
int state; // 0: closed, 1: open
|
int state; // section state (mjtSection)
|
||||||
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
||||||
int shortcut; // shortcut key; 0: undefined
|
int shortcut; // shortcut key; 0: undefined
|
||||||
|
int checkbox; // 0: none, 1: hidden, 2: unchecked, 2: checked
|
||||||
int nitem; // number of items in use
|
int nitem; // number of items in use
|
||||||
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
|
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
mjrRect rtitle; // rectangle occupied by title
|
mjrRect rtitle; // rectangle occupied by title
|
||||||
mjrRect rcontent; // rectangle occupied by content
|
mjrRect rcontent; // rectangle occupied by content
|
||||||
|
int lastclick; // last mouse click over this section
|
||||||
};
|
};
|
||||||
typedef struct mjuiSection_ mjuiSection;
|
typedef struct mjuiSection_ mjuiSection;
|
||||||
struct mjUI_ { // entire UI
|
struct mjUI_ { // entire UI
|
||||||
@@ -2441,10 +2443,12 @@ struct mjUI_ { // entire UI
|
|||||||
int maxheight; // height when all sections open
|
int maxheight; // height when all sections open
|
||||||
int scroll; // scroll from top of UI
|
int scroll; // scroll from top of UI
|
||||||
|
|
||||||
// mouse focus
|
// mouse focus and count
|
||||||
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
||||||
int mouseitem; // item within section
|
int mouseitem; // item within section
|
||||||
int mousehelp; // help button down: print shortcuts
|
int mousehelp; // help button down: print shortcuts
|
||||||
|
int mouseclicks; // number of mouse clicks over UI
|
||||||
|
int mousesectcheck; // 0: none, otherwise 1+section
|
||||||
|
|
||||||
// keyboard focus and edit
|
// keyboard focus and edit
|
||||||
int editsect; // 0: none, otherwise 1+section
|
int editsect; // 0: none, otherwise 1+section
|
||||||
@@ -2465,6 +2469,7 @@ struct mjuiDef_ { // table passed to mjui_add()
|
|||||||
int state; // state
|
int state; // state
|
||||||
void* pdata; // pointer to data
|
void* pdata; // pointer to data
|
||||||
char other[mjMAXUITEXT]; // string with type-specific properties
|
char other[mjMAXUITEXT]; // string with type-specific properties
|
||||||
|
int otherint; // int with type-specific properties
|
||||||
};
|
};
|
||||||
typedef struct mjuiDef_ mjuiDef;
|
typedef struct mjuiDef_ mjuiDef;
|
||||||
typedef enum mjtCatBit_ { // bitflags for mjvGeom category
|
typedef enum mjtCatBit_ { // bitflags for mjvGeom category
|
||||||
@@ -2635,21 +2640,22 @@ struct mjvGeom_ { // abstract geom
|
|||||||
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
|
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
|
||||||
int objid; // mujoco object id; -1 for decor
|
int objid; // mujoco object id; -1 for decor
|
||||||
int category; // visual category
|
int category; // visual category
|
||||||
int texid; // texture id; -1: no texture
|
int matid; // material id; -1: no textured material
|
||||||
int texuniform; // uniform cube mapping
|
|
||||||
int texcoord; // mesh or flex geom has texture coordinates
|
int texcoord; // mesh or flex geom has texture coordinates
|
||||||
int segid; // segmentation id; -1: not shown
|
int segid; // segmentation id; -1: not shown
|
||||||
|
|
||||||
// OpenGL info
|
// spatial transform
|
||||||
float texrepeat[2]; // texture repetition for 2D mapping
|
|
||||||
float size[3]; // size parameters
|
float size[3]; // size parameters
|
||||||
float pos[3]; // Cartesian position
|
float pos[3]; // Cartesian position
|
||||||
float mat[9]; // Cartesian orientation
|
float mat[9]; // Cartesian orientation
|
||||||
|
|
||||||
|
// material properties
|
||||||
float rgba[4]; // color and transparency
|
float rgba[4]; // color and transparency
|
||||||
float emission; // emission coef
|
float emission; // emission coef
|
||||||
float specular; // specular coef
|
float specular; // specular coef
|
||||||
float shininess; // shininess coef
|
float shininess; // shininess coef
|
||||||
float reflectance; // reflectance coef
|
float reflectance; // reflectance coef
|
||||||
|
|
||||||
char label[100]; // text label
|
char label[100]; // text label
|
||||||
|
|
||||||
// transparency rendering (set internally)
|
// transparency rendering (set internally)
|
||||||
@@ -2782,7 +2788,7 @@ struct mjvFigure_ { // abstract 2D figure passed to OpenGL rendere
|
|||||||
|
|
||||||
// line data
|
// line data
|
||||||
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
||||||
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
||||||
|
|
||||||
// output from renderer
|
// output from renderer
|
||||||
int xaxispixel[2]; // range of x-axis in pixels
|
int xaxispixel[2]; // range of x-axis in pixels
|
||||||
@@ -3068,10 +3074,8 @@ typedef struct mjvSceneState_ mjvSceneState;
|
|||||||
void mj_defaultVFS(mjVFS* vfs);
|
void mj_defaultVFS(mjVFS* vfs);
|
||||||
int mj_addFileVFS(mjVFS* vfs, const char* directory, const char* filename);
|
int mj_addFileVFS(mjVFS* vfs, const char* directory, const char* filename);
|
||||||
int mj_addBufferVFS(mjVFS* vfs, const char* name, const void* buffer, int nbuffer);
|
int mj_addBufferVFS(mjVFS* vfs, const char* name, const void* buffer, int nbuffer);
|
||||||
int mj_findFileVFS(const mjVFS* vfs, const char* filename);
|
|
||||||
int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
|
int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
|
||||||
void mj_deleteVFS(mjVFS* vfs);
|
void mj_deleteVFS(mjVFS* vfs);
|
||||||
int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize);
|
|
||||||
mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
||||||
mjSpec* mj_parseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
mjSpec* mj_parseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
|
||||||
mjSpec* mj_parseXMLString(const char* xml, const mjVFS* vfs, char* error, int error_sz);
|
mjSpec* mj_parseXMLString(const char* xml, const mjVFS* vfs, char* error, int error_sz);
|
||||||
@@ -3525,7 +3529,7 @@ mjsText* mjs_addText(mjSpec* s);
|
|||||||
mjsTuple* mjs_addTuple(mjSpec* s);
|
mjsTuple* mjs_addTuple(mjSpec* s);
|
||||||
mjsKey* mjs_addKey(mjSpec* s);
|
mjsKey* mjs_addKey(mjSpec* s);
|
||||||
mjsPlugin* mjs_addPlugin(mjSpec* s);
|
mjsPlugin* mjs_addPlugin(mjSpec* s);
|
||||||
mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id);
|
mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, const mjsDefault* parent);
|
||||||
mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def);
|
mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def);
|
||||||
mjsHField* mjs_addHField(mjSpec* s);
|
mjsHField* mjs_addHField(mjSpec* s);
|
||||||
mjsSkin* mjs_addSkin(mjSpec* s);
|
mjsSkin* mjs_addSkin(mjSpec* s);
|
||||||
@@ -3536,12 +3540,38 @@ mjsBody* mjs_findBody(mjSpec* s, const char* name);
|
|||||||
mjsBody* mjs_findChild(mjsBody* body, const char* name);
|
mjsBody* mjs_findChild(mjsBody* body, const char* name);
|
||||||
mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
|
mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
|
||||||
mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
||||||
|
mjsKey* mjs_findKeyframe(mjSpec* s, const char* name);
|
||||||
mjsDefault* mjs_getDefault(mjsElement* element);
|
mjsDefault* mjs_getDefault(mjsElement* element);
|
||||||
mjsDefault* mjs_findDefault(mjSpec* s, const char* classname);
|
mjsDefault* mjs_findDefault(mjSpec* s, const char* classname);
|
||||||
mjsDefault* mjs_getSpecDefault(mjSpec* s);
|
mjsDefault* mjs_getSpecDefault(mjSpec* s);
|
||||||
int mjs_getId(mjsElement* element);
|
int mjs_getId(mjsElement* element);
|
||||||
mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
||||||
mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
||||||
|
mjsElement* mjs_firstElement(mjSpec* s, mjtObj type);
|
||||||
|
mjsElement* mjs_nextElement(mjSpec* s, mjsElement* element);
|
||||||
|
mjsBody* mjs_asBody(mjsElement* element);
|
||||||
|
mjsGeom* mjs_asGeom(mjsElement* element);
|
||||||
|
mjsJoint* mjs_asJoint(mjsElement* element);
|
||||||
|
mjsSite* mjs_asSite(mjsElement* element);
|
||||||
|
mjsCamera* mjs_asCamera(mjsElement* element);
|
||||||
|
mjsLight* mjs_asLight(mjsElement* element);
|
||||||
|
mjsFrame* mjs_asFrame(mjsElement* element);
|
||||||
|
mjsActuator* mjs_asActuator(mjsElement* element);
|
||||||
|
mjsSensor* mjs_asSensor(mjsElement* element);
|
||||||
|
mjsFlex* mjs_asFlex(mjsElement* element);
|
||||||
|
mjsPair* mjs_asPair(mjsElement* element);
|
||||||
|
mjsEquality* mjs_asEquality(mjsElement* element);
|
||||||
|
mjsExclude* mjs_asExclude(mjsElement* element);
|
||||||
|
mjsTendon* mjs_asTendon(mjsElement* element);
|
||||||
|
mjsNumeric* mjs_asNumeric(mjsElement* element);
|
||||||
|
mjsText* mjs_asText(mjsElement* element);
|
||||||
|
mjsTuple* mjs_asTuple(mjsElement* element);
|
||||||
|
mjsKey* mjs_asKey(mjsElement* element);
|
||||||
|
mjsMesh* mjs_asMesh(mjsElement* element);
|
||||||
|
mjsHField* mjs_asHField(mjsElement* element);
|
||||||
|
mjsSkin* mjs_asSkin(mjsElement* element);
|
||||||
|
mjsTexture* mjs_asTexture(mjsElement* element);
|
||||||
|
mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
void mjs_setString(mjString* dest, const char* text);
|
void mjs_setString(mjString* dest, const char* text);
|
||||||
void mjs_setStringVec(mjStringVec* dest, const char* text);
|
void mjs_setStringVec(mjStringVec* dest, const char* text);
|
||||||
mjtByte mjs_setInStringVec(mjStringVec* dest, int i, const char* text);
|
mjtByte mjs_setInStringVec(mjStringVec* dest, int i, const char* text);
|
||||||
@@ -3559,7 +3589,6 @@ void mjs_setDefault(mjsElement* element, mjsDefault* def);
|
|||||||
void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
||||||
const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
||||||
const mjsOrientation* orientation);
|
const mjsOrientation* orientation);
|
||||||
const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]);
|
|
||||||
void mjs_defaultSpec(mjSpec* spec);
|
void mjs_defaultSpec(mjSpec* spec);
|
||||||
void mjs_defaultOrientation(mjsOrientation* orient);
|
void mjs_defaultOrientation(mjsOrientation* orient);
|
||||||
void mjs_defaultBody(mjsBody* body);
|
void mjs_defaultBody(mjsBody* body);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ data plots. The model file can be specified as a command-line argument, or loade
|
|||||||
functionality. This code sample uses the native UI to render various controls, and provides an
|
functionality. This code sample uses the native UI to render various controls, and provides an
|
||||||
illustration of how the new UI framework is intended to be used. Below is a screen-capture of ``simulate`` in action:
|
illustration of how the new UI framework is intended to be used. Below is a screen-capture of ``simulate`` in action:
|
||||||
|
|
||||||
.. youtube:: 0ORsj_E17B0
|
.. youtube:: P83tKA1iz2Y
|
||||||
:width: 95%
|
:width: 95%
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ selected object by holding Ctrl and dragging the mouse. Dragging the mouse alone
|
|||||||
are keyboard shortcuts for pausing the simulation, resetting, and re-loading the model file. The latter functionality is
|
are keyboard shortcuts for pausing the simulation, resetting, and re-loading the model file. The latter functionality is
|
||||||
very useful while editing the model in an XML editor.
|
very useful while editing the model in an XML editor.
|
||||||
|
|
||||||
The code is quite long yet reasonably commented, so it is best to just read it. Here we provide a high-level overview.
|
The code is long yet reasonably commented, so it is best to just read it. Here we provide a high-level overview.
|
||||||
The ``main()`` function initializes both MuJoCo and GLFW, opens a window, and install GLFW callbacks for mouse and
|
The ``main()`` function initializes both MuJoCo and GLFW, opens a window, and install GLFW callbacks for mouse and
|
||||||
keyboard handling. Note that there is no render callback; GLFW puts the user in charge, instead of running a rendering
|
keyboard handling. Note that there is no render callback; GLFW puts the user in charge, instead of running a rendering
|
||||||
loop behind the scenes. The main loop handles UI events and rendering. The simulation is handled in a background
|
loop behind the scenes. The main loop handles UI events and rendering. The simulation is handled in a background
|
||||||
|
|||||||
+23
-23
@@ -167,29 +167,29 @@ struct mjData_ {
|
|||||||
int nplugin; // number of plugin instances
|
int nplugin; // number of plugin instances
|
||||||
|
|
||||||
// stack pointer
|
// stack pointer
|
||||||
size_t pstack; // first available mjtNum address in stack
|
size_t pstack; // first available byte in stack
|
||||||
size_t pbase; // value of pstack when mj_markStack was last called
|
size_t pbase; // value of pstack when mj_markStack was last called
|
||||||
|
|
||||||
// arena pointer
|
// arena pointer
|
||||||
size_t parena; // first available byte in arena
|
size_t parena; // first available byte in arena
|
||||||
|
|
||||||
// memory utilization stats
|
// memory utilization statistics
|
||||||
size_t maxuse_stack; // maximum stack allocation in bytes
|
size_t maxuse_stack; // maximum stack allocation in bytes
|
||||||
size_t maxuse_threadstack[mjMAXTHREAD]; // maximum stack allocation per thread in bytes
|
size_t maxuse_threadstack[mjMAXTHREAD]; // maximum stack allocation per thread in bytes
|
||||||
size_t maxuse_arena; // maximum arena allocation in bytes
|
size_t maxuse_arena; // maximum arena allocation in bytes
|
||||||
int maxuse_con; // maximum number of contacts
|
int maxuse_con; // maximum number of contacts
|
||||||
int maxuse_efc; // maximum number of scalar constraints
|
int maxuse_efc; // maximum number of scalar constraints
|
||||||
|
|
||||||
// diagnostics
|
|
||||||
mjWarningStat warning[mjNWARNING]; // warning statistics
|
|
||||||
mjTimerStat timer[mjNTIMER]; // timer statistics
|
|
||||||
|
|
||||||
// solver statistics
|
// solver statistics
|
||||||
mjSolverStat solver[mjNISLAND*mjNSOLVER]; // solver statistics per island, per iteration
|
mjSolverStat solver[mjNISLAND*mjNSOLVER]; // solver statistics per island, per iteration
|
||||||
int solver_nisland; // number of islands processed by solver
|
int solver_nisland; // number of islands processed by solver
|
||||||
int solver_niter[mjNISLAND]; // number of solver iterations, per island
|
int solver_niter[mjNISLAND]; // number of solver iterations, per island
|
||||||
int solver_nnz[mjNISLAND]; // number of non-zeros in Hessian or efc_AR, per island
|
int solver_nnz[mjNISLAND]; // number of nonzeros in Hessian or efc_AR, per island
|
||||||
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
mjtNum solver_fwdinv[2]; // forward-inverse comparison: qfrc, efc
|
||||||
|
|
||||||
|
// diagnostics
|
||||||
|
mjWarningStat warning[mjNWARNING]; // warning statistics
|
||||||
|
mjTimerStat timer[mjNTIMER]; // timer statistics
|
||||||
|
|
||||||
// variable sizes
|
// variable sizes
|
||||||
int ne; // number of equality constraints
|
int ne; // number of equality constraints
|
||||||
@@ -207,8 +207,8 @@ struct mjData_ {
|
|||||||
//-------------------- end of info header
|
//-------------------- end of info header
|
||||||
|
|
||||||
// buffers
|
// buffers
|
||||||
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
void* buffer; // main buffer; all pointers point in it (nbuffer bytes)
|
||||||
void* arena; // arena+stack buffer (nstack*sizeof(mjtNum) bytes)
|
void* arena; // arena+stack buffer (narena bytes)
|
||||||
|
|
||||||
//-------------------- main inputs and outputs of the computation
|
//-------------------- main inputs and outputs of the computation
|
||||||
|
|
||||||
@@ -302,7 +302,7 @@ struct mjData_ {
|
|||||||
|
|
||||||
// computed by mj_collisionTree
|
// computed by mj_collisionTree
|
||||||
mjtNum* bvh_aabb_dyn; // global bounding box (center, size) (nbvhdynamic x 6)
|
mjtNum* bvh_aabb_dyn; // global bounding box (center, size) (nbvhdynamic x 6)
|
||||||
mjtByte* bvh_active; // volume has been added to collisions (nbvh x 1)
|
mjtByte* bvh_active; // was bounding volume checked for collision (nbvh x 1)
|
||||||
|
|
||||||
//-------------------- POSITION, VELOCITY dependent
|
//-------------------- POSITION, VELOCITY dependent
|
||||||
|
|
||||||
@@ -372,7 +372,7 @@ struct mjData_ {
|
|||||||
//-------------------- arena-allocated: POSITION dependent
|
//-------------------- arena-allocated: POSITION dependent
|
||||||
|
|
||||||
// computed by mj_collision
|
// computed by mj_collision
|
||||||
mjContact* contact; // list of all detected contacts (ncon x 1)
|
mjContact* contact; // array of all detected contacts (ncon x 1)
|
||||||
|
|
||||||
// computed by mj_makeConstraint
|
// computed by mj_makeConstraint
|
||||||
int* efc_type; // constraint type (mjtConstraint) (nefc x 1)
|
int* efc_type; // constraint type (mjtConstraint) (nefc x 1)
|
||||||
@@ -422,11 +422,11 @@ struct mjData_ {
|
|||||||
//-------------------- arena-allocated: POSITION, VELOCITY, CONTROL/ACCELERATION dependent
|
//-------------------- arena-allocated: POSITION, VELOCITY, CONTROL/ACCELERATION dependent
|
||||||
|
|
||||||
// computed by mj_fwdConstraint/mj_inverse
|
// computed by mj_fwdConstraint/mj_inverse
|
||||||
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (nefc x 1)
|
mjtNum* efc_b; // linear cost term: J*qacc_smooth - aref (nefc x 1)
|
||||||
mjtNum* efc_force; // constraint force in constraint space (nefc x 1)
|
mjtNum* efc_force; // constraint force in constraint space (nefc x 1)
|
||||||
int* efc_state; // constraint state (mjtConstraintState) (nefc x 1)
|
int* efc_state; // constraint state (mjtConstraintState) (nefc x 1)
|
||||||
|
|
||||||
// ThreadPool for multithreaded operations
|
// thread pool pointer
|
||||||
uintptr_t threadpool;
|
uintptr_t threadpool;
|
||||||
};
|
};
|
||||||
typedef struct mjData_ mjData;
|
typedef struct mjData_ mjData;
|
||||||
|
|||||||
@@ -29,8 +29,6 @@
|
|||||||
#define mjMAXIMP 0.9999 // maximum constraint impedance
|
#define mjMAXIMP 0.9999 // maximum constraint impedance
|
||||||
#define mjMAXCONPAIR 50 // maximum number of contacts per geom pair
|
#define mjMAXCONPAIR 50 // maximum number of contacts per geom pair
|
||||||
#define mjMAXTREEDEPTH 50 // maximum bounding volume hierarchy depth
|
#define mjMAXTREEDEPTH 50 // maximum bounding volume hierarchy depth
|
||||||
#define mjMAXVFS 2000 // maximum number of files in virtual file system
|
|
||||||
#define mjMAXVFSNAME 1000 // maximum filename size in virtual file system
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- sizes ---------------------------------------------------------
|
//---------------------------------- sizes ---------------------------------------------------------
|
||||||
@@ -44,7 +42,7 @@
|
|||||||
#define mjNIMP 5 // number of solver impedance parameters
|
#define mjNIMP 5 // number of solver impedance parameters
|
||||||
#define mjNSOLVER 200 // size of one mjData.solver array
|
#define mjNSOLVER 200 // size of one mjData.solver array
|
||||||
#define mjNISLAND 20 // number of mjData.solver arrays
|
#define mjNISLAND 20 // number of mjData.solver arrays
|
||||||
|
#define mjNTEXMAT 6 // number of textures per material
|
||||||
|
|
||||||
//---------------------------------- enum types (mjt) ----------------------------------------------
|
//---------------------------------- enum types (mjt) ----------------------------------------------
|
||||||
|
|
||||||
@@ -399,11 +397,7 @@ typedef struct mjLROpt_ mjLROpt;
|
|||||||
//---------------------------------- mjVFS ---------------------------------------------------------
|
//---------------------------------- mjVFS ---------------------------------------------------------
|
||||||
|
|
||||||
struct mjVFS_ { // virtual file system for loading from memory
|
struct mjVFS_ { // virtual file system for loading from memory
|
||||||
int nfile; // number of files present
|
void* impl_; // internal pointer to VFS memory
|
||||||
char filename[mjMAXVFS][mjMAXVFSNAME]; // file name without path
|
|
||||||
size_t filesize[mjMAXVFS]; // file size in bytes
|
|
||||||
void* filedata[mjMAXVFS]; // buffer with file data
|
|
||||||
uint64_t filestamp[mjMAXVFS]; // checksum of the file data
|
|
||||||
};
|
};
|
||||||
typedef struct mjVFS_ mjVFS;
|
typedef struct mjVFS_ mjVFS;
|
||||||
|
|
||||||
@@ -935,7 +929,7 @@ struct mjModel_ {
|
|||||||
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
|
int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1)
|
||||||
|
|
||||||
// materials
|
// materials
|
||||||
int* mat_texid; // texture id; -1: none (nmat x 1)
|
int* mat_texid; // indices of textures; -1: none (nmat x mjNTEXMAT)
|
||||||
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
|
mjtByte* mat_texuniform; // make texture cube uniform (nmat x 1)
|
||||||
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
|
float* mat_texrepeat; // texture repetition for 2d mapping (nmat x 2)
|
||||||
float* mat_emission; // emission (x rgb) (nmat x 1)
|
float* mat_emission; // emission (x rgb) (nmat x 1)
|
||||||
|
|||||||
+67
-61
@@ -15,14 +15,15 @@
|
|||||||
#ifndef MUJOCO_MJRENDER_H_
|
#ifndef MUJOCO_MJRENDER_H_
|
||||||
#define MUJOCO_MJRENDER_H_
|
#define MUJOCO_MJRENDER_H_
|
||||||
|
|
||||||
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define mjNAUX 10 // number of auxiliary buffers
|
#define mjNAUX 10 // number of auxiliary buffers
|
||||||
#define mjMAXTEXTURE 1000 // maximum number of textures
|
#define mjMAXTEXTURE 100 // maximum number of textures
|
||||||
|
#define mjMAXMATERIAL 100 // maximum number of materials with textures
|
||||||
|
|
||||||
//---------------------------------- primitive types (mjt) -----------------------------------------
|
//---------------------------------- primitive types (mjt) -----------------------------------------
|
||||||
|
|
||||||
@@ -76,92 +77,97 @@ typedef struct mjrRect_ mjrRect;
|
|||||||
|
|
||||||
//---------------------------------- mjrContext ----------------------------------------------------
|
//---------------------------------- mjrContext ----------------------------------------------------
|
||||||
|
|
||||||
struct mjrContext_ { // custom OpenGL context
|
struct mjrContext_ { // custom OpenGL context
|
||||||
// parameters copied from mjVisual
|
// parameters copied from mjVisual
|
||||||
float lineWidth; // line width for wireframe rendering
|
float lineWidth; // line width for wireframe rendering
|
||||||
float shadowClip; // clipping radius for directional lights
|
float shadowClip; // clipping radius for directional lights
|
||||||
float shadowScale; // fraction of light cutoff for spot lights
|
float shadowScale; // fraction of light cutoff for spot lights
|
||||||
float fogStart; // fog start = stat.extent * vis.map.fogstart
|
float fogStart; // fog start = stat.extent * vis.map.fogstart
|
||||||
float fogEnd; // fog end = stat.extent * vis.map.fogend
|
float fogEnd; // fog end = stat.extent * vis.map.fogend
|
||||||
float fogRGBA[4]; // fog rgba
|
float fogRGBA[4]; // fog rgba
|
||||||
int shadowSize; // size of shadow map texture
|
int shadowSize; // size of shadow map texture
|
||||||
int offWidth; // width of offscreen buffer
|
int offWidth; // width of offscreen buffer
|
||||||
int offHeight; // height of offscreen buffer
|
int offHeight; // height of offscreen buffer
|
||||||
int offSamples; // number of offscreen buffer multisamples
|
int offSamples; // number of offscreen buffer multisamples
|
||||||
|
|
||||||
// parameters specified at creation
|
// parameters specified at creation
|
||||||
int fontScale; // font scale
|
int fontScale; // font scale
|
||||||
int auxWidth[mjNAUX]; // auxiliary buffer width
|
int auxWidth[mjNAUX]; // auxiliary buffer width
|
||||||
int auxHeight[mjNAUX]; // auxiliary buffer height
|
int auxHeight[mjNAUX]; // auxiliary buffer height
|
||||||
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
int auxSamples[mjNAUX]; // auxiliary buffer multisamples
|
||||||
|
|
||||||
// offscreen rendering objects
|
// offscreen rendering objects
|
||||||
unsigned int offFBO; // offscreen framebuffer object
|
unsigned int offFBO; // offscreen framebuffer object
|
||||||
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
|
unsigned int offFBO_r; // offscreen framebuffer for resolving multisamples
|
||||||
unsigned int offColor; // offscreen color buffer
|
unsigned int offColor; // offscreen color buffer
|
||||||
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
|
unsigned int offColor_r; // offscreen color buffer for resolving multisamples
|
||||||
unsigned int offDepthStencil; // offscreen depth and stencil buffer
|
unsigned int offDepthStencil; // offscreen depth and stencil buffer
|
||||||
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for resolving multisamples
|
unsigned int offDepthStencil_r; // offscreen depth and stencil buffer for multisamples
|
||||||
|
|
||||||
// shadow rendering objects
|
// shadow rendering objects
|
||||||
unsigned int shadowFBO; // shadow map framebuffer object
|
unsigned int shadowFBO; // shadow map framebuffer object
|
||||||
unsigned int shadowTex; // shadow map texture
|
unsigned int shadowTex; // shadow map texture
|
||||||
|
|
||||||
// auxiliary buffers
|
// auxiliary buffers
|
||||||
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
unsigned int auxFBO[mjNAUX]; // auxiliary framebuffer object
|
||||||
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
unsigned int auxFBO_r[mjNAUX]; // auxiliary framebuffer object for resolving
|
||||||
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
unsigned int auxColor[mjNAUX]; // auxiliary color buffer
|
||||||
unsigned int auxColor_r[mjNAUX];// auxiliary color buffer for resolving
|
unsigned int auxColor_r[mjNAUX]; // auxiliary color buffer for resolving
|
||||||
|
|
||||||
|
// materials with textures
|
||||||
|
int mat_texid[mjMAXMATERIAL*mjNTEXMAT]; // material texture ids (-1: no texture)
|
||||||
|
int mat_texuniform[mjMAXMATERIAL]; // texture repetition for 2d mapping
|
||||||
|
int mat_texrepeat[mjMAXMATERIAL*2]; // texture repetition for 2d mapping
|
||||||
|
|
||||||
// texture objects and info
|
// texture objects and info
|
||||||
int ntexture; // number of allocated textures
|
int ntexture; // number of allocated textures
|
||||||
int textureType[100]; // type of texture (mjtTexture) (ntexture)
|
int textureType[mjMAXTEXTURE]; // type of texture (mjtTexture) (ntexture)
|
||||||
unsigned int texture[100]; // texture names
|
unsigned int texture[mjMAXTEXTURE]; // texture names
|
||||||
|
|
||||||
// displaylist starting positions
|
// displaylist starting positions
|
||||||
unsigned int basePlane; // all planes from model
|
unsigned int basePlane; // all planes from model
|
||||||
unsigned int baseMesh; // all meshes from model
|
unsigned int baseMesh; // all meshes from model
|
||||||
unsigned int baseHField; // all hfields from model
|
unsigned int baseHField; // all height fields from model
|
||||||
unsigned int baseBuiltin; // all buildin geoms, with quality from model
|
unsigned int baseBuiltin; // all builtin geoms, with quality from model
|
||||||
unsigned int baseFontNormal; // normal font
|
unsigned int baseFontNormal; // normal font
|
||||||
unsigned int baseFontShadow; // shadow font
|
unsigned int baseFontShadow; // shadow font
|
||||||
unsigned int baseFontBig; // big font
|
unsigned int baseFontBig; // big font
|
||||||
|
|
||||||
// displaylist ranges
|
// displaylist ranges
|
||||||
int rangePlane; // all planes from model
|
int rangePlane; // all planes from model
|
||||||
int rangeMesh; // all meshes from model
|
int rangeMesh; // all meshes from model
|
||||||
int rangeHField; // all hfields from model
|
int rangeHField; // all hfields from model
|
||||||
int rangeBuiltin; // all builtin geoms, with quality from model
|
int rangeBuiltin; // all builtin geoms, with quality from model
|
||||||
int rangeFont; // all characters in font
|
int rangeFont; // all characters in font
|
||||||
|
|
||||||
// skin VBOs
|
// skin VBOs
|
||||||
int nskin; // number of skins
|
int nskin; // number of skins
|
||||||
unsigned int* skinvertVBO; // skin vertex position VBOs (nskin)
|
unsigned int* skinvertVBO; // skin vertex position VBOs (nskin)
|
||||||
unsigned int* skinnormalVBO; // skin vertex normal VBOs (nskin)
|
unsigned int* skinnormalVBO; // skin vertex normal VBOs (nskin)
|
||||||
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs (nskin)
|
unsigned int* skintexcoordVBO; // skin vertex texture coordinate VBOs (nskin)
|
||||||
unsigned int* skinfaceVBO; // skin face index VBOs (nskin)
|
unsigned int* skinfaceVBO; // skin face index VBOs (nskin)
|
||||||
|
|
||||||
// character info
|
// character info
|
||||||
int charWidth[127]; // character widths: normal and shadow
|
int charWidth[127]; // character widths: normal and shadow
|
||||||
int charWidthBig[127]; // chacarter widths: big
|
int charWidthBig[127]; // chacarter widths: big
|
||||||
int charHeight; // character heights: normal and shadow
|
int charHeight; // character heights: normal and shadow
|
||||||
int charHeightBig; // character heights: big
|
int charHeightBig; // character heights: big
|
||||||
|
|
||||||
// capabilities
|
// capabilities
|
||||||
int glInitialized; // is OpenGL initialized
|
int glInitialized; // is OpenGL initialized
|
||||||
int windowAvailable; // is default/window framebuffer available
|
int windowAvailable; // is default/window framebuffer available
|
||||||
int windowSamples; // number of samples for default/window framebuffer
|
int windowSamples; // number of samples for default/window framebuffer
|
||||||
int windowStereo; // is stereo available for default/window framebuffer
|
int windowStereo; // is stereo available for default/window framebuffer
|
||||||
int windowDoublebuffer; // is default/window framebuffer double buffered
|
int windowDoublebuffer; // is default/window framebuffer double buffered
|
||||||
|
|
||||||
// framebuffer
|
// framebuffer
|
||||||
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
|
int currentBuffer; // currently active framebuffer: mjFB_WINDOW or mjFB_OFFSCREEN
|
||||||
|
|
||||||
// pixel output format
|
// pixel output format
|
||||||
int readPixelFormat; // default color pixel format for mjr_readPixels
|
int readPixelFormat; // default color pixel format for mjr_readPixels
|
||||||
|
|
||||||
// depth output format
|
// depth output format
|
||||||
int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR
|
int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR
|
||||||
};
|
};
|
||||||
typedef struct mjrContext_ mjrContext;
|
typedef struct mjrContext_ mjrContext;
|
||||||
|
|
||||||
|
|||||||
+1
-16
@@ -118,7 +118,7 @@ typedef struct mjSpec_ { // model specification
|
|||||||
mjtByte strippath; // automatically strip paths from mesh files
|
mjtByte strippath; // automatically strip paths from mesh files
|
||||||
mjtByte fitaabb; // meshfit to aabb instead of inertia box
|
mjtByte fitaabb; // meshfit to aabb instead of inertia box
|
||||||
mjtByte degree; // angles in radians or degrees
|
mjtByte degree; // angles in radians or degrees
|
||||||
char euler[3]; // sequence for euler rotations
|
char eulerseq[3]; // sequence for euler rotations
|
||||||
mjString* meshdir; // mesh and hfield directory
|
mjString* meshdir; // mesh and hfield directory
|
||||||
mjString* texturedir; // texture directory
|
mjString* texturedir; // texture directory
|
||||||
mjtByte discardvisual; // discard visual geoms in parser
|
mjtByte discardvisual; // discard visual geoms in parser
|
||||||
@@ -222,7 +222,6 @@ typedef struct mjsFrame_ { // frame specification
|
|||||||
typedef struct mjsJoint_ { // joint specification
|
typedef struct mjsJoint_ { // joint specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtJoint type; // joint type
|
mjtJoint type; // joint type
|
||||||
|
|
||||||
// kinematics
|
// kinematics
|
||||||
@@ -262,7 +261,6 @@ typedef struct mjsJoint_ { // joint specification
|
|||||||
typedef struct mjsGeom_ { // geom specification
|
typedef struct mjsGeom_ { // geom specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // classname
|
|
||||||
mjtGeom type; // geom type
|
mjtGeom type; // geom type
|
||||||
|
|
||||||
// frame, size
|
// frame, size
|
||||||
@@ -311,7 +309,6 @@ typedef struct mjsGeom_ { // geom specification
|
|||||||
typedef struct mjsSite_ { // site specification
|
typedef struct mjsSite_ { // site specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// frame, size
|
// frame, size
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -335,7 +332,6 @@ typedef struct mjsSite_ { // site specification
|
|||||||
typedef struct mjsCamera_ { // camera specification
|
typedef struct mjsCamera_ { // camera specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// extrinsics
|
// extrinsics
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -365,7 +361,6 @@ typedef struct mjsCamera_ { // camera specification
|
|||||||
typedef struct mjsLight_ { // light specification
|
typedef struct mjsLight_ { // light specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// frame
|
// frame
|
||||||
double pos[3]; // position
|
double pos[3]; // position
|
||||||
@@ -393,7 +388,6 @@ typedef struct mjsLight_ { // light specification
|
|||||||
typedef struct mjsFlex_ { // flex specification
|
typedef struct mjsFlex_ { // flex specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// contact properties
|
// contact properties
|
||||||
int contype; // contact type
|
int contype; // contact type
|
||||||
@@ -434,7 +428,6 @@ typedef struct mjsFlex_ { // flex specification
|
|||||||
typedef struct mjsMesh_ { // mesh specification
|
typedef struct mjsMesh_ { // mesh specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* content_type; // content type of file
|
mjString* content_type; // content type of file
|
||||||
mjString* file; // mesh file
|
mjString* file; // mesh file
|
||||||
double refpos[3]; // reference position
|
double refpos[3]; // reference position
|
||||||
@@ -470,7 +463,6 @@ typedef struct mjsHField_ { // height field specification
|
|||||||
typedef struct mjsSkin_ { // skin specification
|
typedef struct mjsSkin_ { // skin specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* file; // skin file
|
mjString* file; // skin file
|
||||||
mjString* material; // name of material used for rendering
|
mjString* material; // name of material used for rendering
|
||||||
float rgba[4]; // rgba when material is omitted
|
float rgba[4]; // rgba when material is omitted
|
||||||
@@ -497,7 +489,6 @@ typedef struct mjsSkin_ { // skin specification
|
|||||||
typedef struct mjsTexture_ { // texture specification
|
typedef struct mjsTexture_ { // texture specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtTexture type; // texture type
|
mjtTexture type; // texture type
|
||||||
|
|
||||||
// method 1: builtin
|
// method 1: builtin
|
||||||
@@ -531,7 +522,6 @@ typedef struct mjsTexture_ { // texture specification
|
|||||||
typedef struct mjsMaterial_ { // material specification
|
typedef struct mjsMaterial_ { // material specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* texture; // name of texture (empty: none)
|
mjString* texture; // name of texture (empty: none)
|
||||||
mjtByte texuniform; // make texture cube uniform
|
mjtByte texuniform; // make texture cube uniform
|
||||||
float texrepeat[2]; // texture repetition for 2D mapping
|
float texrepeat[2]; // texture repetition for 2D mapping
|
||||||
@@ -549,7 +539,6 @@ typedef struct mjsMaterial_ { // material specification
|
|||||||
typedef struct mjsPair_ { // pair specification
|
typedef struct mjsPair_ { // pair specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjString* geomname1; // name of geom 1
|
mjString* geomname1; // name of geom 1
|
||||||
mjString* geomname2; // name of geom 2
|
mjString* geomname2; // name of geom 2
|
||||||
|
|
||||||
@@ -577,7 +566,6 @@ typedef struct mjsExclude_ { // exclude specification
|
|||||||
typedef struct mjsEquality_ { // equality specification
|
typedef struct mjsEquality_ { // equality specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
mjtEq type; // constraint type
|
mjtEq type; // constraint type
|
||||||
double data[mjNEQDATA]; // type-dependent data
|
double data[mjNEQDATA]; // type-dependent data
|
||||||
mjtByte active; // is equality initially active
|
mjtByte active; // is equality initially active
|
||||||
@@ -592,7 +580,6 @@ typedef struct mjsEquality_ { // equality specification
|
|||||||
typedef struct mjsTendon_ { // tendon specification
|
typedef struct mjsTendon_ { // tendon specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// stiffness, damping, friction
|
// stiffness, damping, friction
|
||||||
double stiffness; // stiffness coefficient
|
double stiffness; // stiffness coefficient
|
||||||
@@ -630,7 +617,6 @@ typedef struct mjsWrap_ { // wrapping object specification
|
|||||||
typedef struct mjsActuator_ { // actuator specification
|
typedef struct mjsActuator_ { // actuator specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// gain, bias
|
// gain, bias
|
||||||
mjtGain gaintype; // gain type
|
mjtGain gaintype; // gain type
|
||||||
@@ -674,7 +660,6 @@ typedef struct mjsActuator_ { // actuator specification
|
|||||||
typedef struct mjsSensor_ { // sensor specification
|
typedef struct mjsSensor_ { // sensor specification
|
||||||
mjsElement* element; // element type
|
mjsElement* element; // element type
|
||||||
mjString* name; // name
|
mjString* name; // name
|
||||||
mjString* classname; // class name
|
|
||||||
|
|
||||||
// sensor definition
|
// sensor definition
|
||||||
mjtSensor type; // type of sensor
|
mjtSensor type; // type of sensor
|
||||||
|
|||||||
@@ -17,12 +17,8 @@
|
|||||||
|
|
||||||
//---------------------------------- floating-point definition -------------------------------------
|
//---------------------------------- floating-point definition -------------------------------------
|
||||||
|
|
||||||
// compile-time configuration options
|
|
||||||
#define mjUSEDOUBLE // single or double precision for mjtNum
|
|
||||||
|
|
||||||
|
|
||||||
// floating point data type and minval
|
// floating point data type and minval
|
||||||
#ifdef mjUSEDOUBLE
|
#ifndef mjUSESINGLE
|
||||||
typedef double mjtNum;
|
typedef double mjtNum;
|
||||||
#define mjMINVAL 1E-15 // minimum value in any denominator
|
#define mjMINVAL 1E-15 // minimum value in any denominator
|
||||||
#else
|
#else
|
||||||
|
|||||||
+24
-2
@@ -26,6 +26,7 @@
|
|||||||
#define mjMAXUIRECT 25 // maximum number of rectangles
|
#define mjMAXUIRECT 25 // maximum number of rectangles
|
||||||
|
|
||||||
#define mjSEPCLOSED 1000 // closed state of adjustable separator
|
#define mjSEPCLOSED 1000 // closed state of adjustable separator
|
||||||
|
#define mjPRESERVE 2000 // preserve section or separator state
|
||||||
|
|
||||||
|
|
||||||
// key codes matching GLFW (user must remap for other frameworks)
|
// key codes matching GLFW (user must remap for other frameworks)
|
||||||
@@ -106,6 +107,13 @@ typedef enum mjtItem_ { // UI item type
|
|||||||
} mjtItem;
|
} mjtItem;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum mjtSection_ { // UI section state
|
||||||
|
mjSECT_CLOSED = 0, // closed state (regular section)
|
||||||
|
mjSECT_OPEN, // open state (regular section)
|
||||||
|
mjSECT_FIXED // fixed section: always open, no title
|
||||||
|
} mjtSection;
|
||||||
|
|
||||||
|
|
||||||
// predicate function: set enable/disable based on item category
|
// predicate function: set enable/disable based on item category
|
||||||
typedef int (*mjfItemEnable)(int category, void* data);
|
typedef int (*mjfItemEnable)(int category, void* data);
|
||||||
|
|
||||||
@@ -163,6 +171,8 @@ struct mjuiThemeSpacing_ { // UI visualization theme spacing
|
|||||||
int scroll; // scrollbar width
|
int scroll; // scrollbar width
|
||||||
int label; // label width
|
int label; // label width
|
||||||
int section; // section gap
|
int section; // section gap
|
||||||
|
int cornersect; // corner radius for section
|
||||||
|
int cornersep; // corner radius for separator
|
||||||
int itemside; // item side gap
|
int itemside; // item side gap
|
||||||
int itemmid; // item middle gap
|
int itemmid; // item middle gap
|
||||||
int itemver; // item vertical gap
|
int itemver; // item vertical gap
|
||||||
@@ -180,9 +190,14 @@ struct mjuiThemeColor_ { // UI visualization theme color
|
|||||||
float master[3]; // master background
|
float master[3]; // master background
|
||||||
float thumb[3]; // scrollbar thumb
|
float thumb[3]; // scrollbar thumb
|
||||||
float secttitle[3]; // section title
|
float secttitle[3]; // section title
|
||||||
|
float secttitle2[3]; // section title: bottom color
|
||||||
|
float secttitlecheck[3]; // section title with checkbox
|
||||||
|
float secttitlecheck2[3]; // section title with checkbox: bottom color
|
||||||
float sectfont[3]; // section font
|
float sectfont[3]; // section font
|
||||||
float sectsymbol[3]; // section symbol
|
float sectsymbol[3]; // section symbol
|
||||||
float sectpane[3]; // section pane
|
float sectpane[3]; // section pane
|
||||||
|
float separator[3]; // separator title
|
||||||
|
float separator2[3]; // separator title: bottom color
|
||||||
float shortcut[3]; // shortcut background
|
float shortcut[3]; // shortcut background
|
||||||
float fontactive[3]; // font active
|
float fontactive[3]; // font active
|
||||||
float fontinactive[3]; // font inactive
|
float fontinactive[3]; // font inactive
|
||||||
@@ -236,6 +251,7 @@ struct mjuiItem_ { // UI item
|
|||||||
void *pdata; // data pointer (type-specific)
|
void *pdata; // data pointer (type-specific)
|
||||||
int sectionid; // id of section containing item
|
int sectionid; // id of section containing item
|
||||||
int itemid; // id of item within section
|
int itemid; // id of item within section
|
||||||
|
int userid; // user-supplied id (for event handling)
|
||||||
|
|
||||||
// type-specific properties
|
// type-specific properties
|
||||||
union {
|
union {
|
||||||
@@ -247,6 +263,7 @@ struct mjuiItem_ { // UI item
|
|||||||
|
|
||||||
// internal
|
// internal
|
||||||
mjrRect rect; // rectangle occupied by item
|
mjrRect rect; // rectangle occupied by item
|
||||||
|
int skip; // item skipped due to closed separator
|
||||||
};
|
};
|
||||||
typedef struct mjuiItem_ mjuiItem;
|
typedef struct mjuiItem_ mjuiItem;
|
||||||
|
|
||||||
@@ -256,15 +273,17 @@ typedef struct mjuiItem_ mjuiItem;
|
|||||||
struct mjuiSection_ { // UI section
|
struct mjuiSection_ { // UI section
|
||||||
// properties
|
// properties
|
||||||
char name[mjMAXUINAME]; // name
|
char name[mjMAXUINAME]; // name
|
||||||
int state; // 0: closed, 1: open
|
int state; // section state (mjtSection)
|
||||||
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
int modifier; // 0: none, 1: control, 2: shift; 4: alt
|
||||||
int shortcut; // shortcut key; 0: undefined
|
int shortcut; // shortcut key; 0: undefined
|
||||||
|
int checkbox; // 0: none, 1: hidden, 2: unchecked, 2: checked
|
||||||
int nitem; // number of items in use
|
int nitem; // number of items in use
|
||||||
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
|
mjuiItem item[mjMAXUIITEM]; // preallocated array of items
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
mjrRect rtitle; // rectangle occupied by title
|
mjrRect rtitle; // rectangle occupied by title
|
||||||
mjrRect rcontent; // rectangle occupied by content
|
mjrRect rcontent; // rectangle occupied by content
|
||||||
|
int lastclick; // last mouse click over this section
|
||||||
};
|
};
|
||||||
typedef struct mjuiSection_ mjuiSection;
|
typedef struct mjuiSection_ mjuiSection;
|
||||||
|
|
||||||
@@ -287,10 +306,12 @@ struct mjUI_ { // entire UI
|
|||||||
int maxheight; // height when all sections open
|
int maxheight; // height when all sections open
|
||||||
int scroll; // scroll from top of UI
|
int scroll; // scroll from top of UI
|
||||||
|
|
||||||
// mouse focus
|
// mouse focus and count
|
||||||
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
int mousesect; // 0: none, -1: scroll, otherwise 1+section
|
||||||
int mouseitem; // item within section
|
int mouseitem; // item within section
|
||||||
int mousehelp; // help button down: print shortcuts
|
int mousehelp; // help button down: print shortcuts
|
||||||
|
int mouseclicks; // number of mouse clicks over UI
|
||||||
|
int mousesectcheck; // 0: none, otherwise 1+section
|
||||||
|
|
||||||
// keyboard focus and edit
|
// keyboard focus and edit
|
||||||
int editsect; // 0: none, otherwise 1+section
|
int editsect; // 0: none, otherwise 1+section
|
||||||
@@ -315,6 +336,7 @@ struct mjuiDef_ { // table passed to mjui_add()
|
|||||||
int state; // state
|
int state; // state
|
||||||
void* pdata; // pointer to data
|
void* pdata; // pointer to data
|
||||||
char other[mjMAXUITEXT]; // string with type-specific properties
|
char other[mjMAXUITEXT]; // string with type-specific properties
|
||||||
|
int otherint; // int with type-specific properties
|
||||||
};
|
};
|
||||||
typedef struct mjuiDef_ mjuiDef;
|
typedef struct mjuiDef_ mjuiDef;
|
||||||
|
|
||||||
|
|||||||
@@ -230,21 +230,22 @@ struct mjvGeom_ { // abstract geom
|
|||||||
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
|
int objtype; // mujoco object type; mjOBJ_UNKNOWN for decor
|
||||||
int objid; // mujoco object id; -1 for decor
|
int objid; // mujoco object id; -1 for decor
|
||||||
int category; // visual category
|
int category; // visual category
|
||||||
int texid; // texture id; -1: no texture
|
int matid; // material id; -1: no textured material
|
||||||
int texuniform; // uniform cube mapping
|
|
||||||
int texcoord; // mesh or flex geom has texture coordinates
|
int texcoord; // mesh or flex geom has texture coordinates
|
||||||
int segid; // segmentation id; -1: not shown
|
int segid; // segmentation id; -1: not shown
|
||||||
|
|
||||||
// OpenGL info
|
// spatial transform
|
||||||
float texrepeat[2]; // texture repetition for 2D mapping
|
|
||||||
float size[3]; // size parameters
|
float size[3]; // size parameters
|
||||||
float pos[3]; // Cartesian position
|
float pos[3]; // Cartesian position
|
||||||
float mat[9]; // Cartesian orientation
|
float mat[9]; // Cartesian orientation
|
||||||
|
|
||||||
|
// material properties
|
||||||
float rgba[4]; // color and transparency
|
float rgba[4]; // color and transparency
|
||||||
float emission; // emission coef
|
float emission; // emission coef
|
||||||
float specular; // specular coef
|
float specular; // specular coef
|
||||||
float shininess; // shininess coef
|
float shininess; // shininess coef
|
||||||
float reflectance; // reflectance coef
|
float reflectance; // reflectance coef
|
||||||
|
|
||||||
char label[100]; // text label
|
char label[100]; // text label
|
||||||
|
|
||||||
// transparency rendering (set internally)
|
// transparency rendering (set internally)
|
||||||
@@ -393,7 +394,7 @@ struct mjvFigure_ { // abstract 2D figure passed to OpenGL rendere
|
|||||||
|
|
||||||
// line data
|
// line data
|
||||||
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
int linepnt[mjMAXLINE]; // number of points in line; (0) disable
|
||||||
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
float linedata[mjMAXLINE][2*mjMAXLINEPNT]; // line data (x,y)
|
||||||
|
|
||||||
// output from renderer
|
// output from renderer
|
||||||
int xaxispixel[2]; // range of x-axis in pixels
|
int xaxispixel[2]; // range of x-axis in pixels
|
||||||
|
|||||||
@@ -413,7 +413,7 @@
|
|||||||
X ( int, tex_adr, ntex, 1 ) \
|
X ( int, tex_adr, ntex, 1 ) \
|
||||||
X ( mjtByte, tex_rgb, ntexdata, 1 ) \
|
X ( mjtByte, tex_rgb, ntexdata, 1 ) \
|
||||||
XMJV( int, tex_pathadr, ntex, 1 ) \
|
XMJV( int, tex_pathadr, ntex, 1 ) \
|
||||||
XMJV( int, mat_texid, nmat, 1 ) \
|
XMJV( int, mat_texid, nmat, mjNTEXMAT ) \
|
||||||
XMJV( mjtByte, mat_texuniform, nmat, 1 ) \
|
XMJV( mjtByte, mat_texuniform, nmat, 1 ) \
|
||||||
XMJV( float, mat_texrepeat, nmat, 2 ) \
|
XMJV( float, mat_texrepeat, nmat, 2 ) \
|
||||||
XMJV( float, mat_emission, nmat, 1 ) \
|
XMJV( float, mat_emission, nmat, 1 ) \
|
||||||
|
|||||||
+82
-13
@@ -74,7 +74,7 @@ MJAPI extern const char* mjRNDSTRING[mjNRNDFLAG][3];
|
|||||||
|
|
||||||
//---------------------------------- Virtual file system -------------------------------------------
|
//---------------------------------- Virtual file system -------------------------------------------
|
||||||
|
|
||||||
// Initialize VFS to empty (no deallocation).
|
// Initialize an empty VFS, mj_deleteVFS must be called to deallocate the VFS.
|
||||||
MJAPI void mj_defaultVFS(mjVFS* vfs);
|
MJAPI void mj_defaultVFS(mjVFS* vfs);
|
||||||
|
|
||||||
// Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
// Add file to VFS, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
||||||
@@ -83,18 +83,12 @@ MJAPI int mj_addFileVFS(mjVFS* vfs, const char* directory, const char* filename)
|
|||||||
// Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
// Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.
|
||||||
MJAPI int mj_addBufferVFS(mjVFS* vfs, const char* name, const void* buffer, int nbuffer);
|
MJAPI int mj_addBufferVFS(mjVFS* vfs, const char* name, const void* buffer, int nbuffer);
|
||||||
|
|
||||||
// Return file index in VFS, or -1 if not found in VFS.
|
|
||||||
MJAPI int mj_findFileVFS(const mjVFS* vfs, const char* filename);
|
|
||||||
|
|
||||||
// Delete file from VFS, return 0: success, -1: not found in VFS.
|
// Delete file from VFS, return 0: success, -1: not found in VFS.
|
||||||
MJAPI int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
|
MJAPI int mj_deleteFileVFS(mjVFS* vfs, const char* filename);
|
||||||
|
|
||||||
// Delete all files from VFS.
|
// Delete all files from VFS and deallocates VFS internal memory.
|
||||||
MJAPI void mj_deleteVFS(mjVFS* vfs);
|
MJAPI void mj_deleteVFS(mjVFS* vfs);
|
||||||
|
|
||||||
// deprecated: use mj_copyBufferVFS.
|
|
||||||
MJAPI int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Parse and compile ---------------------------------------------
|
//---------------------------------- Parse and compile ---------------------------------------------
|
||||||
|
|
||||||
@@ -893,7 +887,7 @@ MJAPI int mjs_isWarning(mjSpec* s);
|
|||||||
|
|
||||||
//---------------------------------- Standard math -------------------------------------------------
|
//---------------------------------- Standard math -------------------------------------------------
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
#if !defined(mjUSESINGLE)
|
||||||
#define mju_sqrt sqrt
|
#define mju_sqrt sqrt
|
||||||
#define mju_exp exp
|
#define mju_exp exp
|
||||||
#define mju_sin sin
|
#define mju_sin sin
|
||||||
@@ -1498,7 +1492,7 @@ MJAPI mjsKey* mjs_addKey(mjSpec* s);
|
|||||||
MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s);
|
MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s);
|
||||||
|
|
||||||
// Add default.
|
// Add default.
|
||||||
MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id);
|
MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, const mjsDefault* parent);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Assets --------------------------------------------------------
|
//---------------------------------- Assets --------------------------------------------------------
|
||||||
@@ -1536,6 +1530,9 @@ MJAPI mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
|
|||||||
// Find frame by name.
|
// Find frame by name.
|
||||||
MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
||||||
|
|
||||||
|
// Find keyframe by name.
|
||||||
|
MJAPI mjsKey* mjs_findKeyframe(mjSpec* s, const char* name);
|
||||||
|
|
||||||
// Get default corresponding to an element.
|
// Get default corresponding to an element.
|
||||||
MJAPI mjsDefault* mjs_getDefault(mjsElement* element);
|
MJAPI mjsDefault* mjs_getDefault(mjsElement* element);
|
||||||
|
|
||||||
@@ -1554,6 +1551,81 @@ MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
|||||||
// Return body's next child of the same type; return NULL if child is last.
|
// Return body's next child of the same type; return NULL if child is last.
|
||||||
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
||||||
|
|
||||||
|
// Return spec's first element of selected type.
|
||||||
|
MJAPI mjsElement* mjs_firstElement(mjSpec* s, mjtObj type);
|
||||||
|
|
||||||
|
// Return spec's next element; return NULL if element is last.
|
||||||
|
MJAPI mjsElement* mjs_nextElement(mjSpec* s, mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsBody, or return NULL if the element is not an mjsBody.
|
||||||
|
MJAPI mjsBody* mjs_asBody(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsGeom, or return NULL if the element is not an mjsGeom.
|
||||||
|
MJAPI mjsGeom* mjs_asGeom(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsJoint, or return NULL if the element is not an mjsJoint.
|
||||||
|
MJAPI mjsJoint* mjs_asJoint(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSite, or return NULL if the element is not an mjsSite.
|
||||||
|
MJAPI mjsSite* mjs_asSite(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsCamera, or return NULL if the element is not an mjsCamera.
|
||||||
|
MJAPI mjsCamera* mjs_asCamera(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsLight, or return NULL if the element is not an mjsLight.
|
||||||
|
MJAPI mjsLight* mjs_asLight(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsFrame, or return NULL if the element is not an mjsFrame.
|
||||||
|
MJAPI mjsFrame* mjs_asFrame(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsActuator, or return NULL if the element is not an mjsActuator.
|
||||||
|
MJAPI mjsActuator* mjs_asActuator(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSensor, or return NULL if the element is not an mjsSensor.
|
||||||
|
MJAPI mjsSensor* mjs_asSensor(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsFlex, or return NULL if the element is not an mjsFlex.
|
||||||
|
MJAPI mjsFlex* mjs_asFlex(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsPair, or return NULL if the element is not an mjsPair.
|
||||||
|
MJAPI mjsPair* mjs_asPair(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsEquality, or return NULL if the element is not an mjsEquality.
|
||||||
|
MJAPI mjsEquality* mjs_asEquality(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsExclude, or return NULL if the element is not an mjsExclude.
|
||||||
|
MJAPI mjsExclude* mjs_asExclude(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTendon, or return NULL if the element is not an mjsTendon.
|
||||||
|
MJAPI mjsTendon* mjs_asTendon(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsNumeric, or return NULL if the element is not an mjsNumeric.
|
||||||
|
MJAPI mjsNumeric* mjs_asNumeric(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsText, or return NULL if the element is not an mjsText.
|
||||||
|
MJAPI mjsText* mjs_asText(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTuple, or return NULL if the element is not an mjsTuple.
|
||||||
|
MJAPI mjsTuple* mjs_asTuple(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsKey, or return NULL if the element is not an mjsKey.
|
||||||
|
MJAPI mjsKey* mjs_asKey(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsMesh, or return NULL if the element is not an mjsMesh.
|
||||||
|
MJAPI mjsMesh* mjs_asMesh(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsHField, or return NULL if the element is not an mjsHField.
|
||||||
|
MJAPI mjsHField* mjs_asHField(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSkin, or return NULL if the element is not an mjsSkin.
|
||||||
|
MJAPI mjsSkin* mjs_asSkin(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTexture, or return NULL if the element is not an mjsTexture.
|
||||||
|
MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
|
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Attribute setters ---------------------------------------------
|
//---------------------------------- Attribute setters ---------------------------------------------
|
||||||
|
|
||||||
@@ -1612,9 +1684,6 @@ MJAPI void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
|||||||
MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
||||||
const mjsOrientation* orientation);
|
const mjsOrientation* orientation);
|
||||||
|
|
||||||
// Compute quat and diag inertia from full inertia matrix, return error if any.
|
|
||||||
MJAPI const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Element initialization ---------------------------------------
|
//---------------------------------- Element initialization ---------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -166,9 +166,15 @@ class MjStructVisitor:
|
|||||||
elif (node.get('kind') == 'TypedefDecl' and
|
elif (node.get('kind') == 'TypedefDecl' and
|
||||||
node['type']['qualType'].startswith('struct mj') and
|
node['type']['qualType'].startswith('struct mj') and
|
||||||
node['name'] not in _EXCLUDED):
|
node['name'] not in _EXCLUDED):
|
||||||
struct = self._structs[node['type']['qualType']]
|
declname = node['type']['qualType']
|
||||||
self._typedefs[node['name']] = ast_nodes.StructDecl(
|
try:
|
||||||
name=node['name'], declname=struct.declname, fields=struct.fields)
|
struct = self._structs[declname]
|
||||||
|
except KeyError:
|
||||||
|
self._typedefs[node['name']] = ast_nodes.StructDecl(
|
||||||
|
name=node['name'], declname=declname, fields=())
|
||||||
|
else:
|
||||||
|
self._typedefs[node['name']] = ast_nodes.StructDecl(
|
||||||
|
name=node['name'], declname=struct.declname, fields=struct.fields)
|
||||||
|
|
||||||
def resolve_all_anonymous(self) -> None:
|
def resolve_all_anonymous(self) -> None:
|
||||||
"""Replaces anonymous struct placeholders with corresponding decl."""
|
"""Replaces anonymous struct placeholders with corresponding decl."""
|
||||||
|
|||||||
@@ -800,4 +800,14 @@ ENUMS: Mapping[str, EnumDecl] = dict([
|
|||||||
('mjNITEM', 14),
|
('mjNITEM', 14),
|
||||||
]),
|
]),
|
||||||
)),
|
)),
|
||||||
|
('mjtSection',
|
||||||
|
EnumDecl(
|
||||||
|
name='mjtSection',
|
||||||
|
declname='enum mjtSection_',
|
||||||
|
values=dict([
|
||||||
|
('mjSECT_CLOSED', 0),
|
||||||
|
('mjSECT_OPEN', 1),
|
||||||
|
('mjSECT_FIXED', 2),
|
||||||
|
]),
|
||||||
|
)),
|
||||||
])
|
])
|
||||||
|
|||||||
+436
-83
@@ -38,7 +38,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Initialize VFS to empty (no deallocation).',
|
doc='Initialize an empty VFS, mj_deleteVFS must be called to deallocate the VFS.', # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
('mj_addFileVFS',
|
('mj_addFileVFS',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -96,26 +96,6 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.', # pylint: disable=line-too-long
|
doc='Add file to VFS from buffer, return 0: success, 1: full, 2: repeated name, -1: failed to load.', # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
('mj_findFileVFS',
|
|
||||||
FunctionDecl(
|
|
||||||
name='mj_findFileVFS',
|
|
||||||
return_type=ValueType(name='int'),
|
|
||||||
parameters=(
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='vfs',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjVFS', is_const=True),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='filename',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='char', is_const=True),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
doc='Return file index in VFS, or -1 if not found in VFS.',
|
|
||||||
)),
|
|
||||||
('mj_deleteFileVFS',
|
('mj_deleteFileVFS',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mj_deleteFileVFS',
|
name='mj_deleteFileVFS',
|
||||||
@@ -148,31 +128,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
doc='Delete all files from VFS.',
|
doc='Delete all files from VFS and deallocates VFS internal memory.',
|
||||||
)),
|
|
||||||
('mj_makeEmptyFileVFS',
|
|
||||||
FunctionDecl(
|
|
||||||
name='mj_makeEmptyFileVFS',
|
|
||||||
return_type=ValueType(name='int'),
|
|
||||||
parameters=(
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='vfs',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjVFS'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='filename',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='char', is_const=True),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='filesize',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
doc='deprecated: use mj_copyBufferVFS.',
|
|
||||||
)),
|
)),
|
||||||
('mj_loadXML',
|
('mj_loadXML',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
@@ -9543,13 +9499,9 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
FunctionParameterDecl(
|
FunctionParameterDecl(
|
||||||
name='parentid',
|
name='parent',
|
||||||
type=ValueType(name='int'),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='id',
|
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='int'),
|
inner_type=ValueType(name='mjsDefault', is_const=True),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -9751,6 +9703,28 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Find frame by name.',
|
doc='Find frame by name.',
|
||||||
)),
|
)),
|
||||||
|
('mjs_findKeyframe',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_findKeyframe',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsKey'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='s',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjSpec'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='name',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='char', is_const=True),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Find keyframe by name.',
|
||||||
|
)),
|
||||||
('mjs_getDefault',
|
('mjs_getDefault',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_getDefault',
|
name='mjs_getDefault',
|
||||||
@@ -9861,6 +9835,416 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc="Return body's next child of the same type; return NULL if child is last.", # pylint: disable=line-too-long
|
doc="Return body's next child of the same type; return NULL if child is last.", # pylint: disable=line-too-long
|
||||||
)),
|
)),
|
||||||
|
('mjs_firstElement',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_firstElement',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='s',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjSpec'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='type',
|
||||||
|
type=ValueType(name='mjtObj'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc="Return spec's first element of selected type.",
|
||||||
|
)),
|
||||||
|
('mjs_nextElement',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_nextElement',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='s',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjSpec'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc="Return spec's next element; return NULL if element is last.",
|
||||||
|
)),
|
||||||
|
('mjs_asBody',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asBody',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsBody'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsBody, or return NULL if the element is not an mjsBody.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asGeom',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asGeom',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsGeom'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsGeom, or return NULL if the element is not an mjsGeom.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asJoint',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asJoint',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsJoint'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsJoint, or return NULL if the element is not an mjsJoint.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asSite',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asSite',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsSite'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsSite, or return NULL if the element is not an mjsSite.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asCamera',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asCamera',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsCamera'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsCamera, or return NULL if the element is not an mjsCamera.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asLight',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asLight',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsLight'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsLight, or return NULL if the element is not an mjsLight.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asFrame',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asFrame',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsFrame'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsFrame, or return NULL if the element is not an mjsFrame.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asActuator',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asActuator',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsActuator'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsActuator, or return NULL if the element is not an mjsActuator.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asSensor',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asSensor',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsSensor'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsSensor, or return NULL if the element is not an mjsSensor.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asFlex',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asFlex',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsFlex'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsFlex, or return NULL if the element is not an mjsFlex.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asPair',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asPair',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsPair'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsPair, or return NULL if the element is not an mjsPair.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asEquality',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asEquality',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsEquality'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsEquality, or return NULL if the element is not an mjsEquality.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asExclude',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asExclude',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsExclude'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsExclude, or return NULL if the element is not an mjsExclude.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asTendon',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asTendon',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsTendon'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsTendon, or return NULL if the element is not an mjsTendon.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asNumeric',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asNumeric',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsNumeric'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsNumeric, or return NULL if the element is not an mjsNumeric.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asText',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asText',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsText'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsText, or return NULL if the element is not an mjsText.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asTuple',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asTuple',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsTuple'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsTuple, or return NULL if the element is not an mjsTuple.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asKey',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asKey',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsKey'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsKey, or return NULL if the element is not an mjsKey.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asMesh',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asMesh',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsMesh'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsMesh, or return NULL if the element is not an mjsMesh.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asHField',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asHField',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsHField'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsHField, or return NULL if the element is not an mjsHField.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asSkin',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asSkin',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsSkin'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsSkin, or return NULL if the element is not an mjsSkin.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asTexture',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asTexture',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsTexture'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsTexture, or return NULL if the element is not an mjsTexture.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
|
('mjs_asMaterial',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mjs_asMaterial',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsMaterial'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='element',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjsElement'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
('mjs_setString',
|
('mjs_setString',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_setString',
|
name='mjs_setString',
|
||||||
@@ -10216,37 +10600,6 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Resolve alternative orientations to quat, return error if any.',
|
doc='Resolve alternative orientations to quat, return error if any.',
|
||||||
)),
|
)),
|
||||||
('mjs_fullInertia',
|
|
||||||
FunctionDecl(
|
|
||||||
name='mjs_fullInertia',
|
|
||||||
return_type=PointerType(
|
|
||||||
inner_type=ValueType(name='char', is_const=True),
|
|
||||||
),
|
|
||||||
parameters=(
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='quat',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='double'),
|
|
||||||
extents=(4,),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='inertia',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='double'),
|
|
||||||
extents=(3,),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FunctionParameterDecl(
|
|
||||||
name='fullinertia',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='double', is_const=True),
|
|
||||||
extents=(6,),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
doc='Compute quat and diag inertia from full inertia matrix, return error if any.', # pylint: disable=line-too-long
|
|
||||||
)),
|
|
||||||
('mjs_defaultSpec',
|
('mjs_defaultSpec',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mjs_defaultSpec',
|
name='mjs_defaultSpec',
|
||||||
|
|||||||
+147
-188
@@ -91,43 +91,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
declname='struct mjVFS_',
|
declname='struct mjVFS_',
|
||||||
fields=(
|
fields=(
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='nfile',
|
name='impl_',
|
||||||
type=ValueType(name='int'),
|
type=PointerType(
|
||||||
doc='number of files present',
|
inner_type=ValueType(name='void'),
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='filename',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='char'),
|
|
||||||
extents=(2000, 1000),
|
|
||||||
),
|
),
|
||||||
doc='file name without path',
|
doc='internal pointer to VFS memory',
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='filesize',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='size_t'),
|
|
||||||
extents=(2000,),
|
|
||||||
),
|
|
||||||
doc='file size in bytes',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='filedata',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=PointerType(
|
|
||||||
inner_type=ValueType(name='void'),
|
|
||||||
),
|
|
||||||
extents=(2000,),
|
|
||||||
),
|
|
||||||
doc='buffer with file data',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='filestamp',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='uint64_t'),
|
|
||||||
extents=(2000,),
|
|
||||||
),
|
|
||||||
doc='checksum of the file data',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
@@ -2950,7 +2918,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='int'),
|
inner_type=ValueType(name='int'),
|
||||||
),
|
),
|
||||||
doc='texture id; -1: none (nmat x 1)',
|
doc='indices of textures; -1: none (nmat x mjNTEXMAT)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='mat_texuniform',
|
name='mat_texuniform',
|
||||||
@@ -4183,7 +4151,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='pstack',
|
name='pstack',
|
||||||
type=ValueType(name='size_t'),
|
type=ValueType(name='size_t'),
|
||||||
doc='first available mjtNum address in stack',
|
doc='first available byte in stack',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='pbase',
|
name='pbase',
|
||||||
@@ -4223,22 +4191,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='maximum number of scalar constraints',
|
doc='maximum number of scalar constraints',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='warning',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='mjWarningStat'),
|
|
||||||
extents=(8,),
|
|
||||||
),
|
|
||||||
doc='warning statistics',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='timer',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='mjTimerStat'),
|
|
||||||
extents=(15,),
|
|
||||||
),
|
|
||||||
doc='timer statistics',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='solver',
|
name='solver',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -4266,7 +4218,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
inner_type=ValueType(name='int'),
|
inner_type=ValueType(name='int'),
|
||||||
extents=(20,),
|
extents=(20,),
|
||||||
),
|
),
|
||||||
doc='number of non-zeros in Hessian or efc_AR, per island',
|
doc='number of nonzeros in Hessian or efc_AR, per island',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='solver_fwdinv',
|
name='solver_fwdinv',
|
||||||
@@ -4276,6 +4228,22 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='forward-inverse comparison: qfrc, efc',
|
doc='forward-inverse comparison: qfrc, efc',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='warning',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='mjWarningStat'),
|
||||||
|
extents=(8,),
|
||||||
|
),
|
||||||
|
doc='warning statistics',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='timer',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='mjTimerStat'),
|
||||||
|
extents=(15,),
|
||||||
|
),
|
||||||
|
doc='timer statistics',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='ne',
|
name='ne',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -4329,14 +4297,14 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='void'),
|
inner_type=ValueType(name='void'),
|
||||||
),
|
),
|
||||||
doc='main buffer; all pointers point in it (nbuffer bytes)', # pylint: disable=line-too-long
|
doc='main buffer; all pointers point in it (nbuffer bytes)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='arena',
|
name='arena',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='void'),
|
inner_type=ValueType(name='void'),
|
||||||
),
|
),
|
||||||
doc='arena+stack buffer (nstack*sizeof(mjtNum) bytes)', # pylint: disable=line-too-long
|
doc='arena+stack buffer (narena bytes)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='qpos',
|
name='qpos',
|
||||||
@@ -4756,7 +4724,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjtByte'),
|
inner_type=ValueType(name='mjtByte'),
|
||||||
),
|
),
|
||||||
doc='volume has been added to collisions (nbvh x 1)', # pylint: disable=line-too-long
|
doc='was bounding volume checked for collision (nbvh x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='flexedge_velocity',
|
name='flexedge_velocity',
|
||||||
@@ -4987,7 +4955,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjContact'),
|
inner_type=ValueType(name='mjContact'),
|
||||||
),
|
),
|
||||||
doc='list of all detected contacts (ncon x 1)', # pylint: disable=line-too-long
|
doc='array of all detected contacts (ncon x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='efc_type',
|
name='efc_type',
|
||||||
@@ -5239,26 +5207,26 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjtNum'),
|
inner_type=ValueType(name='mjtNum'),
|
||||||
),
|
),
|
||||||
doc='linear cost term: J*qacc_smooth - aref (nefc x 1)', # pylint: disable=line-too-long
|
doc='linear cost term: J*qacc_smooth - aref (nefc x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='efc_force',
|
name='efc_force',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='mjtNum'),
|
inner_type=ValueType(name='mjtNum'),
|
||||||
),
|
),
|
||||||
doc='constraint force in constraint space (nefc x 1)', # pylint: disable=line-too-long
|
doc='constraint force in constraint space (nefc x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='efc_state',
|
name='efc_state',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
inner_type=ValueType(name='int'),
|
inner_type=ValueType(name='int'),
|
||||||
),
|
),
|
||||||
doc='constraint state (mjtConstraintState) (nefc x 1)', # pylint: disable=line-too-long
|
doc='constraint state (mjtConstraintState) (nefc x 1)', # pylint: disable=line-too-long
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='threadpool',
|
name='threadpool',
|
||||||
type=ValueType(name='uintptr_t'),
|
type=ValueType(name='uintptr_t'),
|
||||||
doc='ThreadPool for multithreaded operations',
|
doc='thread pool pointer',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
@@ -5483,14 +5451,9 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
doc='visual category',
|
doc='visual category',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='texid',
|
name='matid',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='texture id; -1: no texture',
|
doc='material id; -1: no textured material',
|
||||||
),
|
|
||||||
StructFieldDecl(
|
|
||||||
name='texuniform',
|
|
||||||
type=ValueType(name='int'),
|
|
||||||
doc='uniform cube mapping',
|
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='texcoord',
|
name='texcoord',
|
||||||
@@ -5502,14 +5465,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='segmentation id; -1: not shown',
|
doc='segmentation id; -1: not shown',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='texrepeat',
|
|
||||||
type=ArrayType(
|
|
||||||
inner_type=ValueType(name='float'),
|
|
||||||
extents=(2,),
|
|
||||||
),
|
|
||||||
doc='texture repetition for 2D mapping',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='size',
|
name='size',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -7957,7 +7912,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='offDepthStencil_r',
|
name='offDepthStencil_r',
|
||||||
type=ValueType(name='unsigned int'),
|
type=ValueType(name='unsigned int'),
|
||||||
doc='offscreen depth and stencil buffer for resolving multisamples', # pylint: disable=line-too-long
|
doc='offscreen depth and stencil buffer for multisamples',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='shadowFBO',
|
name='shadowFBO',
|
||||||
@@ -8001,6 +7956,30 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='auxiliary color buffer for resolving',
|
doc='auxiliary color buffer for resolving',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mat_texid',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
extents=(600,),
|
||||||
|
),
|
||||||
|
doc='material texture ids (-1: no texture)',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mat_texuniform',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
extents=(100,),
|
||||||
|
),
|
||||||
|
doc='texture repetition for 2d mapping',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mat_texrepeat',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='int'),
|
||||||
|
extents=(200,),
|
||||||
|
),
|
||||||
|
doc='texture repetition for 2d mapping',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='ntexture',
|
name='ntexture',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -8035,12 +8014,12 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='baseHField',
|
name='baseHField',
|
||||||
type=ValueType(name='unsigned int'),
|
type=ValueType(name='unsigned int'),
|
||||||
doc='all hfields from model',
|
doc='all height fields from model',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='baseBuiltin',
|
name='baseBuiltin',
|
||||||
type=ValueType(name='unsigned int'),
|
type=ValueType(name='unsigned int'),
|
||||||
doc='all buildin geoms, with quality from model',
|
doc='all builtin geoms, with quality from model',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='baseFontNormal',
|
name='baseFontNormal',
|
||||||
@@ -8255,7 +8234,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
doc='angles in radians or degrees',
|
doc='angles in radians or degrees',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='euler',
|
name='eulerseq',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
inner_type=ValueType(name='char'),
|
inner_type=ValueType(name='char'),
|
||||||
extents=(3,),
|
extents=(3,),
|
||||||
@@ -8719,13 +8698,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='type',
|
name='type',
|
||||||
type=ValueType(name='mjtJoint'),
|
type=ValueType(name='mjtJoint'),
|
||||||
@@ -8893,13 +8865,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='classname',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='type',
|
name='type',
|
||||||
type=ValueType(name='mjtGeom'),
|
type=ValueType(name='mjtGeom'),
|
||||||
@@ -9108,13 +9073,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='pos',
|
name='pos',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -9212,13 +9170,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='pos',
|
name='pos',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -9358,13 +9309,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='pos',
|
name='pos',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -9483,13 +9427,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='contype',
|
name='contype',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -9665,13 +9602,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='content_type',
|
name='content_type',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -9862,13 +9792,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='file',
|
name='file',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -9985,13 +9908,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='type',
|
name='type',
|
||||||
type=ValueType(name='mjtTexture'),
|
type=ValueType(name='mjtTexture'),
|
||||||
@@ -10121,13 +10037,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='texture',
|
name='texture',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -10214,13 +10123,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='geomname1',
|
name='geomname1',
|
||||||
type=PointerType(
|
type=PointerType(
|
||||||
@@ -10352,13 +10254,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='type',
|
name='type',
|
||||||
type=ValueType(name='mjtEq'),
|
type=ValueType(name='mjtEq'),
|
||||||
@@ -10435,13 +10330,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='stiffness',
|
name='stiffness',
|
||||||
type=ValueType(name='double'),
|
type=ValueType(name='double'),
|
||||||
@@ -10596,13 +10484,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='gaintype',
|
name='gaintype',
|
||||||
type=ValueType(name='mjtGain'),
|
type=ValueType(name='mjtGain'),
|
||||||
@@ -10793,13 +10674,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='name',
|
doc='name',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
|
||||||
name='classname',
|
|
||||||
type=PointerType(
|
|
||||||
inner_type=ValueType(name='mjString'),
|
|
||||||
),
|
|
||||||
doc='class name',
|
|
||||||
),
|
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='type',
|
name='type',
|
||||||
type=ValueType(name='mjtSensor'),
|
type=ValueType(name='mjtSensor'),
|
||||||
@@ -11350,6 +11224,16 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='section gap',
|
doc='section gap',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='cornersect',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='corner radius for section',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='cornersep',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='corner radius for separator',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='itemside',
|
name='itemside',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -11416,6 +11300,30 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='section title',
|
doc='section title',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='secttitle2',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='float'),
|
||||||
|
extents=(3,),
|
||||||
|
),
|
||||||
|
doc='section title: bottom color',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='secttitlecheck',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='float'),
|
||||||
|
extents=(3,),
|
||||||
|
),
|
||||||
|
doc='section title with checkbox',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='secttitlecheck2',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='float'),
|
||||||
|
extents=(3,),
|
||||||
|
),
|
||||||
|
doc='section title with checkbox: bottom color',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='sectfont',
|
name='sectfont',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -11440,6 +11348,22 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='section pane',
|
doc='section pane',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='separator',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='float'),
|
||||||
|
extents=(3,),
|
||||||
|
),
|
||||||
|
doc='separator title',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='separator2',
|
||||||
|
type=ArrayType(
|
||||||
|
inner_type=ValueType(name='float'),
|
||||||
|
extents=(3,),
|
||||||
|
),
|
||||||
|
doc='separator title: bottom color',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='shortcut',
|
name='shortcut',
|
||||||
type=ArrayType(
|
type=ArrayType(
|
||||||
@@ -11602,6 +11526,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='id of item within section',
|
doc='id of item within section',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='userid',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='user-supplied id (for event handling)',
|
||||||
|
),
|
||||||
AnonymousUnionDecl(
|
AnonymousUnionDecl(
|
||||||
fields=(
|
fields=(
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
@@ -11631,6 +11560,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='mjrRect'),
|
type=ValueType(name='mjrRect'),
|
||||||
doc='rectangle occupied by item',
|
doc='rectangle occupied by item',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='skip',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='item skipped due to closed separator',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
('mjuiSection',
|
('mjuiSection',
|
||||||
@@ -11649,7 +11583,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='state',
|
name='state',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='0: closed, 1: open',
|
doc='section state (mjtSection)',
|
||||||
),
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='modifier',
|
name='modifier',
|
||||||
@@ -11661,6 +11595,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='shortcut key; 0: undefined',
|
doc='shortcut key; 0: undefined',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='checkbox',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='0: none, 1: hidden, 2: unchecked, 2: checked',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='nitem',
|
name='nitem',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -11684,6 +11623,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='mjrRect'),
|
type=ValueType(name='mjrRect'),
|
||||||
doc='rectangle occupied by content',
|
doc='rectangle occupied by content',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='lastclick',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='last mouse click over this section',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
('mjUI',
|
('mjUI',
|
||||||
@@ -11763,6 +11707,16 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
doc='help button down: print shortcuts',
|
doc='help button down: print shortcuts',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mouseclicks',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='number of mouse clicks over UI',
|
||||||
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='mousesectcheck',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='0: none, otherwise 1+section',
|
||||||
|
),
|
||||||
StructFieldDecl(
|
StructFieldDecl(
|
||||||
name='editsect',
|
name='editsect',
|
||||||
type=ValueType(name='int'),
|
type=ValueType(name='int'),
|
||||||
@@ -11851,6 +11805,11 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='string with type-specific properties',
|
doc='string with type-specific properties',
|
||||||
),
|
),
|
||||||
|
StructFieldDecl(
|
||||||
|
name='otherint',
|
||||||
|
type=ValueType(name='int'),
|
||||||
|
doc='int with type-specific properties',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ jaxlib==0.4.18; python_version >= '3.9' \
|
|||||||
--hash=sha256:f7787a5531d226d6cc9ec2baa7141260bb713435e1cfc053cb9f5cefa9756ac3 \
|
--hash=sha256:f7787a5531d226d6cc9ec2baa7141260bb713435e1cfc053cb9f5cefa9756ac3 \
|
||||||
--hash=sha256:6cb20bbbdafd90e71ad0deb9295519a0175c108c8c557b84fb9fe94f751daee4 \
|
--hash=sha256:6cb20bbbdafd90e71ad0deb9295519a0175c108c8c557b84fb9fe94f751daee4 \
|
||||||
--hash=sha256:116a0d6aedd3e856b52493d7e392fb1b40952b84fb72448fde1c1ab5687db667 \
|
--hash=sha256:116a0d6aedd3e856b52493d7e392fb1b40952b84fb72448fde1c1ab5687db667 \
|
||||||
--hash=sha256:9593ff69f424947567e206f3e356b2a2df55ca68e6d815d5adc6cae308e8f652 \
|
--hash=sha256:9593ff69f424947567e206f3e356b2a2df55ca68e6d815d5adc6cae308e8f652
|
||||||
--hash=sha256:2b17b3f05b3bbf8e0ddb85fba339525ac03bac21c9f26d0f83dcea1b1654353e \
|
|
||||||
--hash=sha256:b35ec08984e2aa5e96ba3f3f8b88e90dee0283649e037f213dec8e85638fa17d
|
|
||||||
pip==23.3.1 \
|
pip==23.3.1 \
|
||||||
--hash=sha256:55eb67bb6171d37447e82213be585b75fe2b12b359e993773aca4de9247a052b
|
--hash=sha256:55eb67bb6171d37447e82213be585b75fe2b12b359e993773aca4de9247a052b
|
||||||
pytest==7.4.2 \
|
pytest==7.4.2 \
|
||||||
|
|||||||
+118
-33
@@ -1,39 +1,39 @@
|
|||||||
{
|
{
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"id": "MpkYHwCqk7W-"
|
"id": "MpkYHwCqk7W-"
|
||||||
},
|
|
||||||
"source": [
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"# <h1><center>Tutorial <a href=\"https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/mjx/training_apg.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" width=\"140\" align=\"center\"/></a></center></h1>\n",
|
|
||||||
"\n",
|
|
||||||
"This notebook provides a tutorial for differentiable physics for policy learning in [**MuJoCo XLA (MJX)**](https://github.com/google-deepmind/mujoco/blob/main/mjx), a JAX-based implementation of MuJoCo.\n",
|
|
||||||
"\n",
|
|
||||||
"**A Colab runtime with GPU acceleration is required.** If you're using a CPU-only runtime, you can switch using the menu \"Runtime > Change runtime type\".\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"This notebook was written by [Jing Yuan Luo](https://github.com/Andrew-Luo1).\n",
|
|
||||||
"\n",
|
|
||||||
"\u003c!-- Copyright 2021 DeepMind Technologies Limited\n",
|
|
||||||
"\n",
|
|
||||||
" Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
|
||||||
" you may not use this file except in compliance with the License.\n",
|
|
||||||
" You may obtain a copy of the License at\n",
|
|
||||||
"\n",
|
|
||||||
" http://www.apache.org/licenses/LICENSE-2.0\n",
|
|
||||||
"\n",
|
|
||||||
" Unless required by applicable law or agreed to in writing, software\n",
|
|
||||||
" distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
|
||||||
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
|
||||||
" See the License for the specific language governing permissions and\n",
|
|
||||||
" limitations under the License.\n",
|
|
||||||
"--\u003e"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"# <h1><center>Tutorial <a href=\"https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/mjx/training_apg.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" width=\"140\" align=\"center\"/></a></center></h1>\n",
|
||||||
|
"\n",
|
||||||
|
"This notebook provides a tutorial for differentiable physics for policy learning in [**MuJoCo XLA (MJX)**](https://github.com/google-deepmind/mujoco/blob/main/mjx), a JAX-based implementation of MuJoCo.\n",
|
||||||
|
"\n",
|
||||||
|
"**A Colab runtime with GPU acceleration is required.** If you're using a CPU-only runtime, you can switch using the menu \"Runtime > Change runtime type\".\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"This notebook was written by [Jing Yuan Luo](https://github.com/Andrew-Luo1).\n",
|
||||||
|
"\n",
|
||||||
|
"<!-- Copyright 2021 DeepMind Technologies Limited\n",
|
||||||
|
"\n",
|
||||||
|
" Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||||
|
" you may not use this file except in compliance with the License.\n",
|
||||||
|
" You may obtain a copy of the License at\n",
|
||||||
|
"\n",
|
||||||
|
" http://www.apache.org/licenses/LICENSE-2.0\n",
|
||||||
|
"\n",
|
||||||
|
" Unless required by applicable law or agreed to in writing, software\n",
|
||||||
|
" distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
||||||
|
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
||||||
|
" See the License for the specific language governing permissions and\n",
|
||||||
|
" limitations under the License.\n",
|
||||||
|
"-->"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
@@ -106,12 +106,97 @@
|
|||||||
"## Setup: Imports and installations"
|
"## Setup: Imports and installations"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 0,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Install MuJoCo, MJX, and Brax\n",
|
||||||
|
"!pip install mujoco\n",
|
||||||
|
"!pip install mujoco_mjx\n",
|
||||||
|
"!pip install brax"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 0,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"#@title Check if MuJoCo installation was successful\n",
|
||||||
|
"\n",
|
||||||
|
"# Set up GPU rendering.\n",
|
||||||
|
"from google.colab import files\n",
|
||||||
|
"import distutils.util\n",
|
||||||
|
"import os\n",
|
||||||
|
"import subprocess\n",
|
||||||
|
"if subprocess.run('nvidia-smi').returncode:\n",
|
||||||
|
" raise RuntimeError(\n",
|
||||||
|
" 'Cannot communicate with GPU. '\n",
|
||||||
|
" 'Make sure you are using a GPU Colab runtime. '\n",
|
||||||
|
" 'Go to the Runtime menu and select Choose runtime type.')\n",
|
||||||
|
"\n",
|
||||||
|
"# Add an ICD config so that glvnd can pick up the Nvidia EGL driver.\n",
|
||||||
|
"# This is usually installed as part of an Nvidia driver package, but the Colab\n",
|
||||||
|
"# kernel doesn't install its driver via APT, and as a result the ICD is missing.\n",
|
||||||
|
"# (https://github.com/NVIDIA/libglvnd/blob/master/src/EGL/icd_enumeration.md)\n",
|
||||||
|
"NVIDIA_ICD_CONFIG_PATH = '/usr/share/glvnd/egl_vendor.d/10_nvidia.json'\n",
|
||||||
|
"if not os.path.exists(NVIDIA_ICD_CONFIG_PATH):\n",
|
||||||
|
" with open(NVIDIA_ICD_CONFIG_PATH, 'w') as f:\n",
|
||||||
|
" f.write(\"\"\"{\n",
|
||||||
|
" \"file_format_version\" : \"1.0.0\",\n",
|
||||||
|
" \"ICD\" : {\n",
|
||||||
|
" \"library_path\" : \"libEGL_nvidia.so.0\"\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n",
|
||||||
|
"\"\"\")\n",
|
||||||
|
"\n",
|
||||||
|
"# Configure MuJoCo to use the EGL rendering backend (requires GPU)\n",
|
||||||
|
"print('Setting environment variable to use GPU rendering:')\n",
|
||||||
|
"%env MUJOCO_GL=egl\n",
|
||||||
|
"\n",
|
||||||
|
"# Check if installation was succesful.\n",
|
||||||
|
"try:\n",
|
||||||
|
" print('Checking that the installation succeeded:')\n",
|
||||||
|
" import mujoco\n",
|
||||||
|
" mujoco.MjModel.from_xml_string('<mujoco/>')\n",
|
||||||
|
"except Exception as e:\n",
|
||||||
|
" raise e from RuntimeError(\n",
|
||||||
|
" 'Something went wrong during installation. Check the shell output above '\n",
|
||||||
|
" 'for more information.\\n'\n",
|
||||||
|
" 'If using a hosted Colab runtime, make sure you enable GPU acceleration '\n",
|
||||||
|
" 'by going to the Runtime menu and selecting \"Choose runtime type\".')\n",
|
||||||
|
"\n",
|
||||||
|
"print('Installation successful.')\n",
|
||||||
|
"\n",
|
||||||
|
"# Other imports and helper functions\n",
|
||||||
|
"import time\n",
|
||||||
|
"import itertools\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"\n",
|
||||||
|
"# Graphics and plotting.\n",
|
||||||
|
"print('Installing mediapy:')\n",
|
||||||
|
"!command -v ffmpeg >/dev/null || (apt update && apt install -y ffmpeg)\n",
|
||||||
|
"!pip install -q mediapy\n",
|
||||||
|
"import mediapy as media\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"\n",
|
||||||
|
"# More legible printing from numpy.\n",
|
||||||
|
"np.set_printoptions(precision=3, suppress=True, linewidth=100)\n",
|
||||||
|
"\n",
|
||||||
|
"from IPython.display import clear_output\n",
|
||||||
|
"clear_output()"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 1,
|
"execution_count": 1,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"#@title Import MuJoCo, MJX, and Brax\n",
|
||||||
|
"\n",
|
||||||
"import os\n",
|
"import os\n",
|
||||||
"os.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"] = \"0.8\" # 0.9 causes too much lag. \n",
|
"os.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"] = \"0.8\" # 0.9 causes too much lag. \n",
|
||||||
"from datetime import datetime\n",
|
"from datetime import datetime\n",
|
||||||
@@ -162,7 +247,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 0,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<asset>
|
<asset>
|
||||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
<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="128" height="128"
|
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128"
|
||||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
|
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||||
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
<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"/>
|
<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"/>
|
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<asset>
|
<asset>
|
||||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
<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="128" height="128"
|
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128"
|
||||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
|
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||||
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
<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"/>
|
<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"/>
|
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<asset>
|
<asset>
|
||||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="32" height="512"/>
|
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="32" height="512"/>
|
||||||
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128" rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
|
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128" rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||||
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
<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"/>
|
<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"/>
|
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<asset>
|
<asset>
|
||||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
<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="128" height="128"
|
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128"
|
||||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
|
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||||
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
<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"/>
|
<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"/>
|
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
|||||||
+1
-1
@@ -148,7 +148,7 @@ void Bolt::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<Bolt*>(d->plugin_data[instance]);
|
delete reinterpret_cast<Bolt*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
auto sdf = reinterpret_cast<Bolt*>(plugin_data);
|
auto sdf = reinterpret_cast<Bolt*>(plugin_data);
|
||||||
sdf->Reset();
|
sdf->Reset();
|
||||||
|
|||||||
+1
-1
@@ -146,7 +146,7 @@ void Bowl::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<Bowl*>(d->plugin_data[instance]);
|
delete reinterpret_cast<Bowl*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
auto sdf = reinterpret_cast<Bowl*>(plugin_data);
|
auto sdf = reinterpret_cast<Bowl*>(plugin_data);
|
||||||
sdf->Reset();
|
sdf->Reset();
|
||||||
|
|||||||
+1
-1
@@ -232,7 +232,7 @@ void Gear::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<Gear*>(d->plugin_data[instance]);
|
delete reinterpret_cast<Gear*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
auto sdf = reinterpret_cast<Gear*>(plugin_data);
|
auto sdf = reinterpret_cast<Gear*>(plugin_data);
|
||||||
sdf->Reset();
|
sdf->Reset();
|
||||||
|
|||||||
+1
-1
@@ -148,7 +148,7 @@ void Nut::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<Nut*>(d->plugin_data[instance]);
|
delete reinterpret_cast<Nut*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
auto sdf = reinterpret_cast<Nut*>(plugin_data);
|
auto sdf = reinterpret_cast<Nut*>(plugin_data);
|
||||||
sdf->Reset();
|
sdf->Reset();
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ void SdfLib::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<SdfLib*>(d->plugin_data[instance]);
|
delete reinterpret_cast<SdfLib*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
auto sdf = reinterpret_cast<SdfLib*>(plugin_data);
|
auto sdf = reinterpret_cast<SdfLib*>(plugin_data);
|
||||||
sdf->Reset();
|
sdf->Reset();
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ void Torus::RegisterPlugin() {
|
|||||||
delete reinterpret_cast<Torus*>(d->plugin_data[instance]);
|
delete reinterpret_cast<Torus*>(d->plugin_data[instance]);
|
||||||
d->plugin_data[instance] = 0;
|
d->plugin_data[instance] = 0;
|
||||||
};
|
};
|
||||||
plugin.reset = +[](const mjModel* m, double* plugin_state, void* plugin_data,
|
plugin.reset = +[](const mjModel* m, mjtNum* plugin_state, void* plugin_data,
|
||||||
int instance) {
|
int instance) {
|
||||||
// do nothing
|
// do nothing
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
include LICENSE *.md
|
include LICENSE *.md
|
||||||
recursive-include mujoco *.h *.cc *.mm CMakeLists.txt *.cmake
|
recursive-include mujoco *.h *.cc *.cc.inc *.mm CMakeLists.txt *.cmake
|
||||||
recursive-include mujoco/mjpython mjpython.* Info.plist
|
recursive-include mujoco/mjpython mjpython.* Info.plist
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ python "${package_dir}"/mujoco/codegen/generate_enum_traits.py > \
|
|||||||
mujoco/enum_traits.h
|
mujoco/enum_traits.h
|
||||||
python "${package_dir}"/mujoco/codegen/generate_function_traits.py > \
|
python "${package_dir}"/mujoco/codegen/generate_function_traits.py > \
|
||||||
mujoco/function_traits.h
|
mujoco/function_traits.h
|
||||||
|
python "${package_dir}"/mujoco/codegen/generate_spec_bindings.py > \
|
||||||
|
mujoco/specs.cc.inc
|
||||||
export PYTHONPATH="${old_pythonpath}"
|
export PYTHONPATH="${old_pythonpath}"
|
||||||
|
|
||||||
# Copy over the LICENSE file.
|
# Copy over the LICENSE file.
|
||||||
|
|||||||
@@ -405,6 +405,29 @@ target_link_libraries(
|
|||||||
structs_header
|
structs_header
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/specs.cc.inc)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT specs.cc.inc
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${mujoco_SOURCE_DIR}/mujoco ${Python3_EXECUTABLE}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/codegen/generate_spec_bindings.py > specs.cc.inc
|
||||||
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/codegen/generate_spec_bindings.py
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mujoco_pybind11_module(
|
||||||
|
_specs
|
||||||
|
specs.cc
|
||||||
|
specs.cc.inc
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
_specs
|
||||||
|
PRIVATE mujoco
|
||||||
|
Eigen3::Eigen
|
||||||
|
errors_header
|
||||||
|
raw
|
||||||
|
structs_header
|
||||||
|
)
|
||||||
|
|
||||||
mujoco_pybind11_module(_simulate simulate.cc)
|
mujoco_pybind11_module(_simulate simulate.cc)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
_simulate
|
_simulate
|
||||||
@@ -424,6 +447,7 @@ set(LIBRARIES_FOR_WHEEL
|
|||||||
"$<TARGET_FILE:_render>"
|
"$<TARGET_FILE:_render>"
|
||||||
"$<TARGET_FILE:_rollout>"
|
"$<TARGET_FILE:_rollout>"
|
||||||
"$<TARGET_FILE:_simulate>"
|
"$<TARGET_FILE:_simulate>"
|
||||||
|
"$<TARGET_FILE:_specs>"
|
||||||
"$<TARGET_FILE:_structs>"
|
"$<TARGET_FILE:_structs>"
|
||||||
"$<TARGET_FILE:mujoco>"
|
"$<TARGET_FILE:mujoco>"
|
||||||
)
|
)
|
||||||
@@ -459,6 +483,7 @@ if(MUJOCO_PYTHON_MAKE_WHEEL)
|
|||||||
_render
|
_render
|
||||||
_rollout
|
_rollout
|
||||||
_simulate
|
_simulate
|
||||||
|
_specs
|
||||||
_structs
|
_structs
|
||||||
mujoco
|
mujoco
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ from mujoco._enums import *
|
|||||||
from mujoco._errors import *
|
from mujoco._errors import *
|
||||||
from mujoco._functions import *
|
from mujoco._functions import *
|
||||||
from mujoco._render import *
|
from mujoco._render import *
|
||||||
|
from mujoco._specs import *
|
||||||
from mujoco._structs import *
|
from mujoco._structs import *
|
||||||
from mujoco.gl_context import *
|
from mujoco.gl_context import *
|
||||||
from mujoco.renderer import Renderer
|
from mujoco.renderer import Renderer
|
||||||
|
|||||||
@@ -409,19 +409,6 @@ class MuJoCoBindingsTest(parameterized.TestCase):
|
|||||||
np.testing.assert_array_equal(self.model.geom_size[1], [0.5, 0.5, 0.5])
|
np.testing.assert_array_equal(self.model.geom_size[1], [0.5, 0.5, 0.5])
|
||||||
np.testing.assert_array_equal(model_copy.geom_size[1], [0.1, 0.1, 0.1])
|
np.testing.assert_array_equal(model_copy.geom_size[1], [0.1, 0.1, 0.1])
|
||||||
|
|
||||||
def test_assets_array_filename_too_long(self):
|
|
||||||
# Longest allowed filename (excluding null byte)
|
|
||||||
limit = mujoco.mjMAXVFSNAME - 1
|
|
||||||
contents = b'<mujoco/>'
|
|
||||||
valid_filename = 'a' * limit
|
|
||||||
mujoco.MjModel.from_xml_path(valid_filename, {valid_filename: contents})
|
|
||||||
invalid_filename = 'a' * (limit + 1)
|
|
||||||
expected_message = (
|
|
||||||
f'Filename length 1000 exceeds 999 character limit: {invalid_filename}')
|
|
||||||
with self.assertRaisesWithLiteralMatch(ValueError, expected_message):
|
|
||||||
mujoco.MjModel.from_xml_path(invalid_filename,
|
|
||||||
{invalid_filename: contents})
|
|
||||||
|
|
||||||
def test_mjdata_can_copy(self):
|
def test_mjdata_can_copy(self):
|
||||||
self.data.qpos = [0, 0, 0.1*np.sqrt(2) - 0.001,
|
self.data.qpos = [0, 0, 0.1*np.sqrt(2) - 0.001,
|
||||||
np.cos(np.pi/8), np.sin(np.pi/8), 0, 0, 0,
|
np.cos(np.pi/8), np.sin(np.pi/8), 0, 0, 0,
|
||||||
@@ -856,9 +843,6 @@ Return the current version of MuJoCo as a null-terminated string.
|
|||||||
Euler integrator, semi-implicit in velocity.
|
Euler integrator, semi-implicit in velocity.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_int_constant(self):
|
|
||||||
self.assertEqual(mujoco.mjMAXVFSNAME, 1000)
|
|
||||||
|
|
||||||
def test_float_constant(self):
|
def test_float_constant(self):
|
||||||
self.assertEqual(mujoco.mjMAXVAL, 1e10)
|
self.assertEqual(mujoco.mjMAXVAL, 1e10)
|
||||||
self.assertEqual(mujoco.mjMINVAL, 1e-15)
|
self.assertEqual(mujoco.mjMINVAL, 1e-15)
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
# Copyright 2024 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.
|
||||||
|
# ==============================================================================
|
||||||
|
"""Generates the bindings for the MuJoCo specs."""
|
||||||
|
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from absl import app
|
||||||
|
|
||||||
|
from introspect import ast_nodes
|
||||||
|
from introspect import structs
|
||||||
|
|
||||||
|
|
||||||
|
SCALAR_TYPES = {'int', 'double', 'float', 'mjtByte', 'mjtNum'}
|
||||||
|
|
||||||
|
|
||||||
|
def _value_binding_code(
|
||||||
|
field: ast_nodes.ValueType, classname: str = '', varname: str = ''
|
||||||
|
) -> str:
|
||||||
|
"""Creates a string that defines Python bindings for a value type."""
|
||||||
|
fulltype = field.name
|
||||||
|
if field.name not in SCALAR_TYPES:
|
||||||
|
fulltype += '&'
|
||||||
|
fullvarname = varname
|
||||||
|
rawclassname = classname.replace('mjs', 'raw::Mjs')
|
||||||
|
if classname == 'mjSpec': # raw mjSpec has a wrapper
|
||||||
|
rawclassname = classname.replace('mjS', 'MjS')
|
||||||
|
fullvarname = 'ptr->' + varname
|
||||||
|
if field.name.startswith('mjs'): # all other mjs are raw structs
|
||||||
|
fulltype = field.name.replace('mjs', 'raw::Mjs')
|
||||||
|
if field.name != 'mjsPlugin' and field.name != 'mjsOrientation':
|
||||||
|
fulltype = fulltype + '*' # plugin and orientation are pointers
|
||||||
|
|
||||||
|
def_property_args = (
|
||||||
|
f'"{varname}"',
|
||||||
|
f"""[]({rawclassname}& self) -> {fulltype} {{
|
||||||
|
return self.{fullvarname};
|
||||||
|
}}""",
|
||||||
|
f"""[]({rawclassname}& self, {fulltype} {varname}) {{
|
||||||
|
self.{fullvarname} = {varname};
|
||||||
|
}}""",
|
||||||
|
)
|
||||||
|
|
||||||
|
if field.name not in SCALAR_TYPES:
|
||||||
|
def_property_args += ('py::return_value_policy::reference_internal',)
|
||||||
|
|
||||||
|
return f'{classname}.def_property({",".join(def_property_args)});'
|
||||||
|
|
||||||
|
|
||||||
|
def _array_binding_code(
|
||||||
|
field: ast_nodes.ArrayType, classname: str = '', varname: str = ''
|
||||||
|
) -> str:
|
||||||
|
"""Creates a string that declares Python bindings for an array type."""
|
||||||
|
if len(field.extents) > 1:
|
||||||
|
raise NotImplementedError()
|
||||||
|
innertype = field.inner_type.decl()
|
||||||
|
rawclassname = classname.replace('mjs', 'raw::Mjs')
|
||||||
|
fullvarname = varname
|
||||||
|
if classname == 'mjSpec': # raw mjSpec has a wrapper
|
||||||
|
rawclassname = classname.replace('mjS', 'MjS')
|
||||||
|
fullvarname = 'ptr->' + varname
|
||||||
|
if innertype == 'double' or innertype == 'mjtNum':
|
||||||
|
innertype = 'MjDouble' # custom Eigen type
|
||||||
|
elif innertype == 'float':
|
||||||
|
innertype = 'MjFloat' # custom Eigen type
|
||||||
|
elif innertype == 'int':
|
||||||
|
innertype = 'MjInt' # custom Eigen type
|
||||||
|
elif innertype == 'char':
|
||||||
|
# char array special case
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> py::array_t<char> {{
|
||||||
|
return py::array_t<char>({field.extents[0]}, self.{fullvarname});
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, py::object rhs) {{
|
||||||
|
int i = 0;
|
||||||
|
for (auto val : rhs) {{
|
||||||
|
self.{fullvarname}[i++] = py::cast<char>(val);
|
||||||
|
}}
|
||||||
|
}}, py::return_value_policy::reference_internal);"""
|
||||||
|
# all other array types
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> {innertype}{field.extents[0]} {{
|
||||||
|
return {innertype}{field.extents[0]}(self.{fullvarname});
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, {innertype}Ref{field.extents[0]} {varname}) {{
|
||||||
|
{innertype}{field.extents[0]}(self.{fullvarname}) = {varname};
|
||||||
|
}}, py::return_value_policy::reference_internal);"""
|
||||||
|
|
||||||
|
|
||||||
|
def _ptr_binding_code(
|
||||||
|
field: ast_nodes.PointerType, classname: str = '', varname: str = ''
|
||||||
|
) -> str:
|
||||||
|
"""Creates a string that declares Python bindings for a pointer type."""
|
||||||
|
vartype = field.inner_type.decl()
|
||||||
|
rawclassname = classname.replace('mjs', 'raw::Mjs')
|
||||||
|
fullvarname = varname
|
||||||
|
if classname == 'mjSpec': # raw mjSpec has a wrapper
|
||||||
|
rawclassname = classname.replace('mjS', 'MjS')
|
||||||
|
fullvarname = 'ptr->' + varname
|
||||||
|
if vartype == 'mjsElement': # this is ignored by the caller
|
||||||
|
return 'mjsElement'
|
||||||
|
if vartype.startswith('mjs'): # for structs, use the value case
|
||||||
|
return _value_binding_code(field.inner_type, classname, varname)
|
||||||
|
elif vartype == 'mjString': # C++ string -> Python string
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> std::string_view {{
|
||||||
|
return *self.{fullvarname};
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, std::string_view {varname}) {{
|
||||||
|
*(self.{fullvarname}) = {varname};
|
||||||
|
}});"""
|
||||||
|
elif ( # C++ vectors of values -> Python array
|
||||||
|
vartype == 'mjDoubleVec'
|
||||||
|
or vartype == 'mjFloatVec'
|
||||||
|
or vartype == 'mjIntVec'
|
||||||
|
):
|
||||||
|
vartype = vartype.replace('mj', '').replace('Vec', '').lower()
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> py::array_t<{vartype}> {{
|
||||||
|
return py::array_t<{vartype}>(self.{fullvarname}->size(),
|
||||||
|
self.{fullvarname}->data());
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, py::object rhs) {{
|
||||||
|
self.{fullvarname}->clear();
|
||||||
|
self.{fullvarname}->reserve(py::len(rhs));
|
||||||
|
for (auto val : rhs) {{
|
||||||
|
self.{fullvarname}->push_back(py::cast<{vartype}>(val));
|
||||||
|
}}
|
||||||
|
}}, py::return_value_policy::reference_internal);"""
|
||||||
|
elif vartype == 'mjStringVec': # C++ vector of strings -> Python list
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> py::list {{
|
||||||
|
py::list list;
|
||||||
|
for (auto val : *self.{fullvarname}) {{
|
||||||
|
list.append(val);
|
||||||
|
}}
|
||||||
|
return list;
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, py::object rhs) {{
|
||||||
|
self.{fullvarname}->clear();
|
||||||
|
self.{fullvarname}->reserve(py::len(rhs));
|
||||||
|
for (auto val : rhs) {{
|
||||||
|
self.{fullvarname}->push_back(py::cast<std::string>(val));
|
||||||
|
}}
|
||||||
|
}}, py::return_value_policy::reference_internal);"""
|
||||||
|
elif 'VecVec' in vartype: # C++ vector of vectors -> Python list of lists
|
||||||
|
vartype = vartype.replace('mj', '').replace('VecVec', '').lower()
|
||||||
|
return f"""\
|
||||||
|
{classname}.def_property(
|
||||||
|
"{varname}",
|
||||||
|
[]({rawclassname}& self) -> py::list {{
|
||||||
|
py::list list;
|
||||||
|
for (auto inner_vec : *self.{fullvarname}) {{
|
||||||
|
py::list inner_list;
|
||||||
|
for (auto val : inner_vec) {{
|
||||||
|
inner_list.append(val);
|
||||||
|
}}
|
||||||
|
list.append(inner_list);
|
||||||
|
}}
|
||||||
|
return list;
|
||||||
|
}},
|
||||||
|
[]({rawclassname}& self, py::object rhs) {{
|
||||||
|
self.{fullvarname}->clear();
|
||||||
|
self.{fullvarname}->reserve(py::len(rhs));
|
||||||
|
for (auto inner_list : rhs) {{
|
||||||
|
auto inner_vec = py::cast<std::vector<{vartype}>>(inner_list);
|
||||||
|
self.{fullvarname}->push_back(inner_vec);
|
||||||
|
}}
|
||||||
|
}}, py::return_value_policy::reference_internal);"""
|
||||||
|
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def _binding_code(field: ast_nodes.StructFieldDecl, key: str) -> str:
|
||||||
|
if isinstance(field.type, ast_nodes.ValueType):
|
||||||
|
return _value_binding_code(field.type, key, field.name)
|
||||||
|
elif isinstance(field.type, ast_nodes.PointerType):
|
||||||
|
return _ptr_binding_code(field.type, key, field.name)
|
||||||
|
elif isinstance(field.type, ast_nodes.ArrayType):
|
||||||
|
return _array_binding_code(field.type, key, field.name)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def generate() -> None:
|
||||||
|
for key in structs.STRUCTS.keys():
|
||||||
|
if (key.startswith('mjs') or key == 'mjSpec') and key != 'mjsElement':
|
||||||
|
print('\n // ' + key)
|
||||||
|
for field in structs.STRUCTS[key].fields:
|
||||||
|
code = _binding_code(field, key)
|
||||||
|
if code != 'mjsElement':
|
||||||
|
print(code)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: Sequence[str]) -> None:
|
||||||
|
if len(argv) > 1:
|
||||||
|
raise app.UsageError('Too many command-line arguments.')
|
||||||
|
generate()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(main)
|
||||||
@@ -57,8 +57,6 @@ PYBIND11_MODULE(_constants, pymodule) {
|
|||||||
X(mjMINIMP);
|
X(mjMINIMP);
|
||||||
X(mjMAXIMP);
|
X(mjMAXIMP);
|
||||||
X(mjMAXCONPAIR);
|
X(mjMAXCONPAIR);
|
||||||
X(mjMAXVFS);
|
|
||||||
X(mjMAXVFSNAME);
|
|
||||||
X(mjNEQDATA);
|
X(mjNEQDATA);
|
||||||
X(mjNDYN);
|
X(mjNDYN);
|
||||||
X(mjNGAIN);
|
X(mjNGAIN);
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
@@ -29,6 +28,7 @@
|
|||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include "raw.h"
|
#include "raw.h"
|
||||||
|
#include "structs.h"
|
||||||
#include <pybind11/eigen.h>
|
#include <pybind11/eigen.h>
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <pybind11/stl.h>
|
#include <pybind11/stl.h>
|
||||||
@@ -108,9 +108,10 @@ PYBIND11_MODULE(_functions, pymodule) {
|
|||||||
// Skipped: mj_copyModel (have MjModel.__copy__, memory managed by MjModel)
|
// Skipped: mj_copyModel (have MjModel.__copy__, memory managed by MjModel)
|
||||||
pymodule.def(
|
pymodule.def(
|
||||||
"mj_saveModel",
|
"mj_saveModel",
|
||||||
[](const MjModelWrapper& m, const std::optional<std::string>& filename = std::nullopt,
|
[](const MjModelWrapper& m,
|
||||||
std::optional<
|
const std::optional<std::string>& filename = std::nullopt,
|
||||||
Eigen::Ref<Eigen::Vector<std::uint8_t, Eigen::Dynamic>>> buffer = std::nullopt) {
|
std::optional<Eigen::Ref<Eigen::Vector<std::uint8_t, Eigen::Dynamic>>>
|
||||||
|
buffer = std::nullopt) {
|
||||||
void* buffer_ptr = nullptr;
|
void* buffer_ptr = nullptr;
|
||||||
int buffer_sz = 0;
|
int buffer_sz = 0;
|
||||||
if (buffer.has_value()) {
|
if (buffer.has_value()) {
|
||||||
@@ -122,8 +123,7 @@ PYBIND11_MODULE(_functions, pymodule) {
|
|||||||
buffer_ptr, buffer_sz);
|
buffer_ptr, buffer_sz);
|
||||||
},
|
},
|
||||||
py::arg("m"), py::arg_v("filename", std::nullopt),
|
py::arg("m"), py::arg_v("filename", std::nullopt),
|
||||||
py::arg_v("buffer", std::nullopt),
|
py::arg_v("buffer", std::nullopt), py::doc(traits::mj_saveModel::doc),
|
||||||
py::doc(traits::mj_saveModel::doc),
|
|
||||||
py::call_guard<py::gil_scoped_release>());
|
py::call_guard<py::gil_scoped_release>());
|
||||||
// Skipped: mj_loadModel (have MjModel.from_binary_path)
|
// Skipped: mj_loadModel (have MjModel.from_binary_path)
|
||||||
// Skipped: mj_deleteModel (have MjModel.__del__)
|
// Skipped: mj_deleteModel (have MjModel.__del__)
|
||||||
@@ -700,8 +700,8 @@ PYBIND11_MODULE(_functions, pymodule) {
|
|||||||
Def<traits::mju_dist3>(pymodule);
|
Def<traits::mju_dist3>(pymodule);
|
||||||
Def<traits::mju_mulMatVec3>(pymodule);
|
Def<traits::mju_mulMatVec3>(pymodule);
|
||||||
Def<traits::mju_mulMatTVec3>(pymodule);
|
Def<traits::mju_mulMatTVec3>(pymodule);
|
||||||
Def<traits::mju_rotVecMat>(pymodule);
|
// skipped: mju_rotVecMat
|
||||||
Def<traits::mju_rotVecMatT>(pymodule);
|
// skipped: mju_rotVecMatT
|
||||||
Def<traits::mju_cross>(pymodule);
|
Def<traits::mju_cross>(pymodule);
|
||||||
Def<traits::mju_zero4>(pymodule);
|
Def<traits::mju_zero4>(pymodule);
|
||||||
Def<traits::mju_unit4>(pymodule);
|
Def<traits::mju_unit4>(pymodule);
|
||||||
|
|||||||
@@ -168,7 +168,7 @@
|
|||||||
X( float, light_, specular, nlight, 3 )
|
X( float, light_, specular, nlight, 3 )
|
||||||
|
|
||||||
#define MJMODEL_MATERIAL \
|
#define MJMODEL_MATERIAL \
|
||||||
X( int, mat_, texid, nmat, 1 ) \
|
X( int, mat_, texid, nmat, mjNTEXMAT ) \
|
||||||
X( mjtByte, mat_, texuniform, nmat, 1 ) \
|
X( mjtByte, mat_, texuniform, nmat, 1 ) \
|
||||||
X( float, mat_, texrepeat, nmat, 2 ) \
|
X( float, mat_, texrepeat, nmat, 2 ) \
|
||||||
X( float, mat_, emission, nmat, 1 ) \
|
X( float, mat_, emission, nmat, 1 ) \
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Copyright 2024 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.
|
||||||
|
# ==============================================================================
|
||||||
|
"""Test that copying mujoco.MjData multiple times doesn't leak memory."""
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
from absl.testing import absltest
|
||||||
|
import mujoco
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryLeakTest(absltest.TestCase):
|
||||||
|
|
||||||
|
# Regression test for https://github.com/google-deepmind/mujoco/issues/1572
|
||||||
|
def test_deepcopy_mjdata_leak(self):
|
||||||
|
# MuJoCo model with textures that take up significant memory.
|
||||||
|
model_xml = textwrap.dedent("""
|
||||||
|
<mujoco>
|
||||||
|
<asset>
|
||||||
|
<material name="body"/>
|
||||||
|
<texture name="grid" type="2d" builtin="checker"
|
||||||
|
width="1024" height="1024" rgb1="0 0 0" rgb2="1 1 1"/>
|
||||||
|
<material name="grid" texture="grid" texrepeat="1 1"
|
||||||
|
texuniform="true" reflectance=".2"/>
|
||||||
|
</asset>
|
||||||
|
<worldbody>
|
||||||
|
<geom size="0 0 .05" type="plane" material="grid"/>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
""")
|
||||||
|
limit = self._memory_limit(4 * 2**30)
|
||||||
|
try:
|
||||||
|
model = mujoco.MjModel.from_xml_string(model_xml)
|
||||||
|
data = mujoco.MjData(model)
|
||||||
|
total = 0
|
||||||
|
for _ in range(1000):
|
||||||
|
mujoco.mj_step(model, data)
|
||||||
|
last_data = copy.deepcopy(data)
|
||||||
|
total += last_data.time
|
||||||
|
finally:
|
||||||
|
self._memory_limit(limit)
|
||||||
|
|
||||||
|
def _memory_limit(self, limit_in_bytes: int) -> int:
|
||||||
|
"""Limits max memory usage, and returns previous limit."""
|
||||||
|
soft = -1
|
||||||
|
try:
|
||||||
|
import resource # pylint: disable=g-import-not-at-top
|
||||||
|
soft, hard = resource.getrlimit(resource.RLIMIT_AS)
|
||||||
|
resource.setrlimit(resource.RLIMIT_AS, (limit_in_bytes, hard))
|
||||||
|
except (ImportError, ValueError):
|
||||||
|
# On Windows or systems where setting resource limits fails, do nothing.
|
||||||
|
pass
|
||||||
|
return soft
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
absltest.main()
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjrender.h>
|
#include <mujoco/mjrender.h>
|
||||||
|
#include <mujoco/mjspec.h>
|
||||||
#include <mujoco/mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
|
|
||||||
// Type aliases for MuJoCo C structs to allow us refer to consistently refer
|
// Type aliases for MuJoCo C structs to allow us refer to consistently refer
|
||||||
@@ -28,6 +29,35 @@ using MjContact = ::mjContact;
|
|||||||
using MjData = ::mjData;
|
using MjData = ::mjData;
|
||||||
using MjLROpt = ::mjLROpt;
|
using MjLROpt = ::mjLROpt;
|
||||||
using MjModel = ::mjModel;
|
using MjModel = ::mjModel;
|
||||||
|
using MjSpec = ::mjSpec;
|
||||||
|
using MjsElement = ::mjsElement;
|
||||||
|
using MjsOrientation = ::mjsOrientation;
|
||||||
|
using MjsPlugin = ::mjsPlugin;
|
||||||
|
using MjsBody = ::mjsBody;
|
||||||
|
using MjsFrame = ::mjsFrame;
|
||||||
|
using MjsJoint = ::mjsJoint;
|
||||||
|
using MjsGeom = ::mjsGeom;
|
||||||
|
using MjsSite = ::mjsSite;
|
||||||
|
using MjsCamera = ::mjsCamera;
|
||||||
|
using MjsLight = ::mjsLight;
|
||||||
|
using MjsFlex = ::mjsFlex;
|
||||||
|
using MjsMesh = ::mjsMesh;
|
||||||
|
using MjsHField = ::mjsHField;
|
||||||
|
using MjsSkin = ::mjsSkin;
|
||||||
|
using MjsTexture = ::mjsTexture;
|
||||||
|
using MjsMaterial = ::mjsMaterial;
|
||||||
|
using MjsPair = ::mjsPair;
|
||||||
|
using MjsExclude = ::mjsExclude;
|
||||||
|
using MjsEquality = ::mjsEquality;
|
||||||
|
using MjsTendon = ::mjsTendon;
|
||||||
|
using MjsWrap = ::mjsWrap;
|
||||||
|
using MjsActuator = ::mjsActuator;
|
||||||
|
using MjsSensor = ::mjsSensor;
|
||||||
|
using MjsNumeric = ::mjsNumeric;
|
||||||
|
using MjsText = ::mjsText;
|
||||||
|
using MjsTuple = ::mjsTuple;
|
||||||
|
using MjsKey = ::mjsKey;
|
||||||
|
using MjsDefault = ::mjsDefault;
|
||||||
using MjOption = ::mjOption;
|
using MjOption = ::mjOption;
|
||||||
using MjSolverStat = ::mjSolverStat;
|
using MjSolverStat = ::mjSolverStat;
|
||||||
using MjStatistic = ::mjStatistic;
|
using MjStatistic = ::mjStatistic;
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ class MjWrapper<raw::MjrContext> : public WrapperBase<raw::MjrContext> {
|
|||||||
X(auxFBO_r);
|
X(auxFBO_r);
|
||||||
X(auxColor);
|
X(auxColor);
|
||||||
X(auxColor_r);
|
X(auxColor_r);
|
||||||
|
X(mat_texid);
|
||||||
|
X(mat_texuniform);
|
||||||
|
X(mat_texrepeat);
|
||||||
X(textureType);
|
X(textureType);
|
||||||
X(texture);
|
X(texture);
|
||||||
X(skinvertVBO);
|
X(skinvertVBO);
|
||||||
@@ -95,6 +98,9 @@ MjrContextWrapper::MjWrapper()
|
|||||||
X(auxFBO_r),
|
X(auxFBO_r),
|
||||||
X(auxColor),
|
X(auxColor),
|
||||||
X(auxColor_r),
|
X(auxColor_r),
|
||||||
|
X(mat_texid),
|
||||||
|
X(mat_texuniform),
|
||||||
|
X(mat_texrepeat),
|
||||||
X(textureType),
|
X(textureType),
|
||||||
X(texture),
|
X(texture),
|
||||||
X_SKIN(skinvertVBO),
|
X_SKIN(skinvertVBO),
|
||||||
@@ -119,6 +125,9 @@ MjrContextWrapper::MjWrapper(const MjModelWrapper& model, int fontscale)
|
|||||||
X(auxFBO_r),
|
X(auxFBO_r),
|
||||||
X(auxColor),
|
X(auxColor),
|
||||||
X(auxColor_r),
|
X(auxColor_r),
|
||||||
|
X(mat_texid),
|
||||||
|
X(mat_texuniform),
|
||||||
|
X(mat_texrepeat),
|
||||||
X(textureType),
|
X(textureType),
|
||||||
X(texture),
|
X(texture),
|
||||||
X_SKIN(skinvertVBO),
|
X_SKIN(skinvertVBO),
|
||||||
@@ -238,6 +247,9 @@ PYBIND11_MODULE(_render, pymodule) {
|
|||||||
X(auxFBO_r);
|
X(auxFBO_r);
|
||||||
X(auxColor);
|
X(auxColor);
|
||||||
X(auxColor_r);
|
X(auxColor_r);
|
||||||
|
X(mat_texid);
|
||||||
|
X(mat_texuniform);
|
||||||
|
X(mat_texrepeat);
|
||||||
X(textureType);
|
X(textureType);
|
||||||
X(texture);
|
X(texture);
|
||||||
X(skinvertVBO);
|
X(skinvertVBO);
|
||||||
|
|||||||
@@ -123,6 +123,9 @@ class SimulateWrapper {
|
|||||||
|
|
||||||
mujoco::Simulate* simulate() { return simulate_; }
|
mujoco::Simulate* simulate() { return simulate_; }
|
||||||
|
|
||||||
|
py::object GetModel() const { return m_; }
|
||||||
|
py::object GetData() const { return d_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mujoco::Simulate* simulate_;
|
mujoco::Simulate* simulate_;
|
||||||
std::atomic_int destroyed_ = 0;
|
std::atomic_int destroyed_ = 0;
|
||||||
@@ -222,6 +225,8 @@ PYBIND11_MODULE(_simulate, pymodule) {
|
|||||||
.def("lock", GetIfNotNull(&mujoco::Simulate::mtx),
|
.def("lock", GetIfNotNull(&mujoco::Simulate::mtx),
|
||||||
py::call_guard<py::gil_scoped_release>(),
|
py::call_guard<py::gil_scoped_release>(),
|
||||||
py::return_value_policy::reference_internal)
|
py::return_value_policy::reference_internal)
|
||||||
|
.def_property_readonly("m", &SimulateWrapper::GetModel)
|
||||||
|
.def_property_readonly("d", &SimulateWrapper::GetData)
|
||||||
.def_property_readonly("ctrl_noise_std",
|
.def_property_readonly("ctrl_noise_std",
|
||||||
GetIfNotNull(&mujoco::Simulate::ctrl_noise_std),
|
GetIfNotNull(&mujoco::Simulate::ctrl_noise_std),
|
||||||
py::call_guard<py::gil_scoped_release>())
|
py::call_guard<py::gil_scoped_release>())
|
||||||
|
|||||||
@@ -0,0 +1,954 @@
|
|||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef> // IWYU pragma: keep
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view> // IWYU pragma: keep
|
||||||
|
#include <vector> // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
#include <mujoco/mjspec.h> // IWYU pragma: keep
|
||||||
|
#include <mujoco/mujoco.h>
|
||||||
|
#include "errors.h"
|
||||||
|
#include "indexers.h" // IWYU pragma: keep
|
||||||
|
#include "raw.h"
|
||||||
|
#include "structs.h" // IWYU pragma: keep
|
||||||
|
#include <pybind11/cast.h>
|
||||||
|
#include <pybind11/eigen.h>
|
||||||
|
#include <pybind11/eigen/matrix.h>
|
||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/pytypes.h>
|
||||||
|
#include <pybind11/stl.h>
|
||||||
|
|
||||||
|
namespace py = ::pybind11;
|
||||||
|
|
||||||
|
namespace mujoco::python {
|
||||||
|
using MjInt2 = Eigen::Map<Eigen::Vector2i>;
|
||||||
|
using MjInt3 = Eigen::Map<Eigen::Vector3i>;
|
||||||
|
using MjFloat2 = Eigen::Map<Eigen::Vector2f>;
|
||||||
|
using MjFloat3 = Eigen::Map<Eigen::Vector3f>;
|
||||||
|
using MjFloat4 = Eigen::Map<Eigen::Vector4f>;
|
||||||
|
using MjDouble2 = Eigen::Map<Eigen::Vector2d>;
|
||||||
|
using MjDouble3 = Eigen::Map<Eigen::Vector3d>;
|
||||||
|
using MjDouble4 = Eigen::Map<Eigen::Vector4d>;
|
||||||
|
using MjDouble5 = Eigen::Map<Eigen::Matrix<double, 5, 1>>;
|
||||||
|
using MjDouble6 = Eigen::Map<Eigen::Matrix<double, 6, 1>>;
|
||||||
|
using MjDouble10 = Eigen::Map<Eigen::Matrix<double, 10, 1>>;
|
||||||
|
using MjDouble11 = Eigen::Map<Eigen::Matrix<double, 11, 1>>;
|
||||||
|
using MjDoubleVec = Eigen::Map<Eigen::VectorXd>;
|
||||||
|
|
||||||
|
using MjIntRef2 = Eigen::Ref<const Eigen::Vector2i>;
|
||||||
|
using MjIntRef3 = Eigen::Ref<const Eigen::Vector3i>;
|
||||||
|
using MjFloatRef2 = Eigen::Ref<const Eigen::Vector2f>;
|
||||||
|
using MjFloatRef3 = Eigen::Ref<const Eigen::Vector3f>;
|
||||||
|
using MjFloatRef4 = Eigen::Ref<const Eigen::Vector4f>;
|
||||||
|
using MjDoubleRef2 = Eigen::Ref<const Eigen::Vector2d>;
|
||||||
|
using MjDoubleRef3 = Eigen::Ref<const Eigen::Vector3d>;
|
||||||
|
using MjDoubleRef4 = Eigen::Ref<const Eigen::Vector4d>;
|
||||||
|
using MjDoubleRef5 = Eigen::Ref<const Eigen::Matrix<double, 5, 1>>;
|
||||||
|
using MjDoubleRef6 = Eigen::Ref<const Eigen::Matrix<double, 6, 1>>;
|
||||||
|
using MjDoubleRef10 = Eigen::Ref<const Eigen::Matrix<double, 10, 1>>;
|
||||||
|
using MjDoubleRef11 = Eigen::Ref<const Eigen::Matrix<double, 11, 1>>;
|
||||||
|
using MjDoubleRefVec = Eigen::Ref<const Eigen::VectorXd>;
|
||||||
|
|
||||||
|
struct MjSpec {
|
||||||
|
MjSpec() : ptr(mj_makeSpec()) {}
|
||||||
|
~MjSpec() { mj_deleteSpec(ptr); }
|
||||||
|
raw::MjSpec* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
PYBIND11_MODULE(_specs, m) {
|
||||||
|
auto structs_m = py::module::import("mujoco._structs");
|
||||||
|
py::function mjmodel_from_spec_ptr =
|
||||||
|
structs_m.attr("MjModel").attr("_from_spec_ptr");
|
||||||
|
py::function mjmodel_mjdata_from_spec_ptr =
|
||||||
|
structs_m.attr("_recompile_spec_addr");
|
||||||
|
|
||||||
|
py::class_<MjSpec> mjSpec(m, "MjSpec");
|
||||||
|
py::class_<raw::MjsElement> mjsElement(m, "MjsElement");
|
||||||
|
py::class_<raw::MjsDefault> mjsDefault(m, "MjsDefault");
|
||||||
|
py::class_<raw::MjsBody> mjsBody(m, "MjsBody");
|
||||||
|
py::class_<raw::MjsFrame> mjsFrame(m, "MjsFrame");
|
||||||
|
py::class_<raw::MjsGeom> mjsGeom(m, "MjsGeom");
|
||||||
|
py::class_<raw::MjsJoint> mjsJoint(m, "MjsJoint");
|
||||||
|
py::class_<raw::MjsLight> mjsLight(m, "MjsLight");
|
||||||
|
py::class_<raw::MjsMaterial> mjsMaterial(m, "MjsMaterial");
|
||||||
|
py::class_<raw::MjsSite> mjsSite(m, "MjsSite");
|
||||||
|
py::class_<raw::MjsMesh> mjsMesh(m, "MjsMesh");
|
||||||
|
py::class_<raw::MjsSkin> mjsSkin(m, "MjsSkin");
|
||||||
|
py::class_<raw::MjsTexture> mjsTexture(m, "MjsTexture");
|
||||||
|
py::class_<raw::MjsText> mjsText(m, "MjsText");
|
||||||
|
py::class_<raw::MjsTuple> mjsTuple(m, "MjsTuple");
|
||||||
|
py::class_<raw::MjsCamera> mjsCamera(m, "MjsCamera");
|
||||||
|
py::class_<raw::MjsFlex> mjsFlex(m, "MjsFlex");
|
||||||
|
py::class_<raw::MjsHField> mjsHField(m, "MjsHField");
|
||||||
|
py::class_<raw::MjsKey> mjsKey(m, "MjsKey");
|
||||||
|
py::class_<raw::MjsNumeric> mjsNumeric(m, "MjsNumeric");
|
||||||
|
py::class_<raw::MjsPair> mjsPair(m, "MjsPair");
|
||||||
|
py::class_<raw::MjsExclude> mjsExclude(m, "MjsExclude");
|
||||||
|
py::class_<raw::MjsEquality> mjsEquality(m, "MjsEquality");
|
||||||
|
py::class_<raw::MjsTendon> mjsTendon(m, "MjsTendon");
|
||||||
|
py::class_<raw::MjsSensor> mjsSensor(m, "MjsSensor");
|
||||||
|
py::class_<raw::MjsActuator> mjsActuator(m, "MjsActuator");
|
||||||
|
py::class_<raw::MjsPlugin> mjsPlugin(m, "MjsPlugin");
|
||||||
|
py::class_<raw::MjsOrientation> mjsOrientation(m, "MjsOrientation");
|
||||||
|
py::class_<raw::MjsWrap> mjsWrap(m, "MjsWrap");
|
||||||
|
|
||||||
|
// ============================= MJSPEC =====================================
|
||||||
|
mjSpec.def(py::init<>());
|
||||||
|
mjSpec.def("recompile", [mjmodel_mjdata_from_spec_ptr](
|
||||||
|
const MjSpec& self, py::object m, py::object d) {
|
||||||
|
return mjmodel_mjdata_from_spec_ptr(reinterpret_cast<uintptr_t>(self.ptr),
|
||||||
|
m, d);
|
||||||
|
});
|
||||||
|
mjSpec.def(
|
||||||
|
"copy",
|
||||||
|
[](const MjSpec& self) -> raw::MjSpec* { return mj_copySpec(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"worldbody",
|
||||||
|
[](MjSpec& self) -> raw::MjsBody* {
|
||||||
|
return mjs_findBody(self.ptr, "world");
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"find_body",
|
||||||
|
[](MjSpec& self, std::string& name) -> raw::MjsBody* {
|
||||||
|
return mjs_findBody(self.ptr, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"find_mesh",
|
||||||
|
[](MjSpec& self, std::string& name) -> raw::MjsMesh* {
|
||||||
|
return mjs_findMesh(self.ptr, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"find_frame",
|
||||||
|
[](MjSpec& self, std::string& name) -> raw::MjsFrame* {
|
||||||
|
return mjs_findFrame(self.ptr, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"find_keyframe",
|
||||||
|
[](MjSpec& self, std::string& name) -> raw::MjsKey* {
|
||||||
|
return mjs_findKeyframe(self.ptr, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"find_default",
|
||||||
|
[](MjSpec& self, std::string& classname) -> raw::MjsDefault* {
|
||||||
|
return mjs_findDefault(self.ptr, classname.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def("compile", [mjmodel_from_spec_ptr](MjSpec& self) {
|
||||||
|
return mjmodel_from_spec_ptr(reinterpret_cast<uintptr_t>(self.ptr));
|
||||||
|
});
|
||||||
|
mjSpec.def(
|
||||||
|
"copy_back",
|
||||||
|
[](MjSpec& self, raw::MjModel& model) {
|
||||||
|
return mj_copyBack(self.ptr, &model);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def("to_xml", [](MjSpec& self) -> std::string {
|
||||||
|
int size = mj_saveXMLString(self.ptr, nullptr, 0, nullptr, 0);
|
||||||
|
std::unique_ptr<char[]> buf(new char[size + 1]);
|
||||||
|
std::array<char, 1024> err;
|
||||||
|
buf[0] = '\0';
|
||||||
|
err[0] = '\0';
|
||||||
|
mj_saveXMLString(self.ptr, buf.get(), size + 1, err.data(), err.size());
|
||||||
|
if (err[0] != '\0') {
|
||||||
|
throw FatalError(std::string(err.data()));
|
||||||
|
}
|
||||||
|
return std::string(buf.get());
|
||||||
|
});
|
||||||
|
mjSpec.def("from_file", [](MjSpec& self, std::string& filename) -> void {
|
||||||
|
std::array<char, 1024> err;
|
||||||
|
err[0] = '\0';
|
||||||
|
mj_deleteSpec(self.ptr);
|
||||||
|
self.ptr = mj_parseXML(filename.c_str(), 0, err.data(), err.size());
|
||||||
|
if (!self.ptr) {
|
||||||
|
throw FatalError(std::string(err.data()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mjSpec.def("from_string", [](MjSpec& self, std::string& xml) -> void {
|
||||||
|
std::array<char, 1024> err;
|
||||||
|
err[0] = '\0';
|
||||||
|
mj_deleteSpec(self.ptr);
|
||||||
|
self.ptr = mj_parseXMLString(xml.c_str(), 0, err.data(), err.size());
|
||||||
|
if (!self.ptr) {
|
||||||
|
throw FatalError(std::string(err.data()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mjSpec.def(
|
||||||
|
"add_default",
|
||||||
|
[](MjSpec* spec, std::string& classname,
|
||||||
|
raw::MjsDefault* parent) -> raw::MjsDefault* {
|
||||||
|
return mjs_addDefault(spec->ptr, classname.c_str(), parent);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"default",
|
||||||
|
[](MjSpec& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getSpecDefault(self.ptr);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_material",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsMaterial* {
|
||||||
|
return mjs_addMaterial(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_mesh",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsMesh* {
|
||||||
|
return mjs_addMesh(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_skin",
|
||||||
|
[](MjSpec& self) -> raw::MjsSkin* { return mjs_addSkin(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_texture",
|
||||||
|
[](MjSpec& self) -> raw::MjsTexture* { return mjs_addTexture(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_text",
|
||||||
|
[](MjSpec& self) -> raw::MjsText* { return mjs_addText(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_tuple",
|
||||||
|
[](MjSpec& self) -> raw::MjsTuple* { return mjs_addTuple(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_flex",
|
||||||
|
[](MjSpec& self) -> raw::MjsFlex* { return mjs_addFlex(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_hfield",
|
||||||
|
[](MjSpec& self) -> raw::MjsHField* { return mjs_addHField(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_key",
|
||||||
|
[](MjSpec& self) -> raw::MjsKey* { return mjs_addKey(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_numeric",
|
||||||
|
[](MjSpec& self) -> raw::MjsNumeric* { return mjs_addNumeric(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_pair",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsPair* {
|
||||||
|
return mjs_addPair(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_exclude",
|
||||||
|
[](MjSpec& self) -> raw::MjsExclude* { return mjs_addExclude(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_equality",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsEquality* {
|
||||||
|
return mjs_addEquality(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_tendon",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsTendon* {
|
||||||
|
return mjs_addTendon(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_sensor",
|
||||||
|
[](MjSpec& self) -> raw::MjsSensor* { return mjs_addSensor(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_actuator",
|
||||||
|
[](MjSpec& self, raw::MjsDefault* default_) -> raw::MjsActuator* {
|
||||||
|
return mjs_addActuator(self.ptr, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def(
|
||||||
|
"add_plugin",
|
||||||
|
[](MjSpec& self) -> raw::MjsPlugin* { return mjs_addPlugin(self.ptr); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def("detach_body", [](MjSpec& self, raw::MjsBody& body) {
|
||||||
|
mjs_detachBody(self.ptr, &body);
|
||||||
|
});
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"actuators",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_ACTUATOR);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asActuator(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"sensors",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_SENSOR);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asSensor(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"flexes",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_FLEX);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asFlex(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"pairs",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_PAIR);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asPair(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"equality",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_EQUALITY);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asEquality(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"excludes",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_EXCLUDE);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asExclude(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"tendons",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_TENDON);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asTendon(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"numeric",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_NUMERIC);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asNumeric(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"text",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_TEXT);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asText(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"tuple",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_TUPLE);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asTuple(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"key",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_KEY);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asKey(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"mesh",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_MESH);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asMesh(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"hfield",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_HFIELD);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asHField(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"skin",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_SKIN);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asSkin(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"texture",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_TEXTURE);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asTexture(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjSpec.def_property_readonly(
|
||||||
|
"material",
|
||||||
|
[](MjSpec& self) -> py::list {
|
||||||
|
py::list list;
|
||||||
|
raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_MATERIAL);
|
||||||
|
while (el) {
|
||||||
|
list.append(mjs_asMaterial(el));
|
||||||
|
el = mjs_nextElement(self.ptr, el);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSBODY =====================================
|
||||||
|
mjsBody.def_property_readonly(
|
||||||
|
"id", [](raw::MjsBody& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsBody.def("delete", [](raw::MjsBody& self) { mjs_delete(self.element); });
|
||||||
|
mjsBody.def(
|
||||||
|
"add_body",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsBody* {
|
||||||
|
return mjs_addBody(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_frame",
|
||||||
|
[](raw::MjsBody& self, raw::MjsFrame* parentframe_) -> raw::MjsFrame* {
|
||||||
|
return mjs_addFrame(&self, parentframe_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_geom",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsGeom* {
|
||||||
|
return mjs_addGeom(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_joint",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsJoint* {
|
||||||
|
return mjs_addJoint(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_freejoint",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsJoint* {
|
||||||
|
return mjs_addFreeJoint(&self);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_light",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsLight* {
|
||||||
|
return mjs_addLight(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_site",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsSite* {
|
||||||
|
return mjs_addSite(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"add_camera",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault* default_) -> raw::MjsCamera* {
|
||||||
|
return mjs_addCamera(&self, default_);
|
||||||
|
},
|
||||||
|
py::arg_v("default", nullptr),
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def("set_frame",
|
||||||
|
[](raw::MjsBody& self, raw::MjsFrame& frame) -> void {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsBody.def("set_default",
|
||||||
|
[](raw::MjsBody& self, raw::MjsDefault& default_) -> void {
|
||||||
|
mjs_setDefault(self.element, &default_);
|
||||||
|
});
|
||||||
|
mjsBody.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"find_child",
|
||||||
|
[](raw::MjsBody& self, std::string& name) -> raw::MjsBody* {
|
||||||
|
return mjs_findChild(&self, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_body",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsBody* {
|
||||||
|
return mjs_asBody(mjs_firstChild(&self, mjOBJ_BODY));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_body",
|
||||||
|
[](raw::MjsBody& self, raw::MjsBody& child) -> raw::MjsBody* {
|
||||||
|
return mjs_asBody(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_camera",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsCamera* {
|
||||||
|
return mjs_asCamera(mjs_firstChild(&self, mjOBJ_CAMERA));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_camera",
|
||||||
|
[](raw::MjsBody& self, raw::MjsCamera& child) -> raw::MjsCamera* {
|
||||||
|
return mjs_asCamera(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_light",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsLight* {
|
||||||
|
return mjs_asLight(mjs_firstChild(&self, mjOBJ_LIGHT));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_light",
|
||||||
|
[](raw::MjsBody& self, raw::MjsLight& child) -> raw::MjsLight* {
|
||||||
|
return mjs_asLight(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_joint",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsJoint* {
|
||||||
|
return mjs_asJoint(mjs_firstChild(&self, mjOBJ_JOINT));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_joint",
|
||||||
|
[](raw::MjsBody& self, raw::MjsJoint& child) -> raw::MjsJoint* {
|
||||||
|
return mjs_asJoint(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_geom",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsGeom* {
|
||||||
|
return mjs_asGeom(mjs_firstChild(&self, mjOBJ_GEOM));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_geom",
|
||||||
|
[](raw::MjsBody& self, raw::MjsGeom& child) -> raw::MjsGeom* {
|
||||||
|
return mjs_asGeom(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_site",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsSite* {
|
||||||
|
return mjs_asSite(mjs_firstChild(&self, mjOBJ_SITE));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_site",
|
||||||
|
[](raw::MjsBody& self, raw::MjsSite& child) -> raw::MjsSite* {
|
||||||
|
return mjs_asSite(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"first_frame",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjsFrame* {
|
||||||
|
return mjs_asFrame(mjs_firstChild(&self, mjOBJ_FRAME));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"next_frame",
|
||||||
|
[](raw::MjsBody& self, raw::MjsFrame& child) -> raw::MjsFrame* {
|
||||||
|
return mjs_asFrame(mjs_nextChild(&self, child.element));
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def(
|
||||||
|
"spec",
|
||||||
|
[](raw::MjsBody& self) -> raw::MjSpec* { return mjs_getSpec(&self); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsBody.def("attach_frame",
|
||||||
|
[](raw::MjsBody& self, raw::MjsFrame& frame, std::string& prefix,
|
||||||
|
std::string& suffix) -> void {
|
||||||
|
mjs_attachFrame(&self, &frame, prefix.c_str(), suffix.c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================= MJSFRAME ====================================
|
||||||
|
mjsFrame.def_property_readonly(
|
||||||
|
"id", [](raw::MjsFrame& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsFrame.def("delete", [](raw::MjsFrame& self) { mjs_delete(self.element); });
|
||||||
|
mjsFrame.def("set_frame", [](raw::MjsFrame& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsFrame.def("attach_body", [](raw::MjsFrame& self, raw::MjsBody& body,
|
||||||
|
std::string& prefix, std::string& suffix) {
|
||||||
|
mjs_attachBody(&self, &body, prefix.c_str(), suffix.c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================= MJSGEOM =====================================
|
||||||
|
mjsGeom.def_property_readonly(
|
||||||
|
"id", [](raw::MjsGeom& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsGeom.def("delete", [](raw::MjsGeom& self) { mjs_delete(self.element); });
|
||||||
|
mjsGeom.def("set_frame", [](raw::MjsGeom& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsGeom.def("set_default", [](raw::MjsGeom& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsGeom.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsGeom& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSJOINT ====================================
|
||||||
|
mjsJoint.def_property_readonly(
|
||||||
|
"id", [](raw::MjsJoint& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsJoint.def("delete", [](raw::MjsJoint& self) { mjs_delete(self.element); });
|
||||||
|
mjsJoint.def("set_frame", [](raw::MjsJoint& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsJoint.def("set_default", [](raw::MjsJoint& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsJoint.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsJoint& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSSITE =====================================
|
||||||
|
mjsSite.def_property_readonly(
|
||||||
|
"id", [](raw::MjsSite& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsSite.def("delete", [](raw::MjsSite& self) { mjs_delete(self.element); });
|
||||||
|
mjsSite.def("set_frame", [](raw::MjsSite& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsSite.def("set_default", [](raw::MjsSite& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsSite.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsSite& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSCAMERA ===================================
|
||||||
|
mjsCamera.def_property_readonly("id", [](raw::MjsCamera& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsCamera.def("delete",
|
||||||
|
[](raw::MjsCamera& self) { mjs_delete(self.element); });
|
||||||
|
mjsCamera.def("set_frame", [](raw::MjsCamera& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsCamera.def("set_default", [](raw::MjsCamera& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsCamera.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsCamera& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSLIGHT ====================================
|
||||||
|
mjsLight.def_property_readonly(
|
||||||
|
"id", [](raw::MjsLight& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsLight.def("delete", [](raw::MjsLight& self) { mjs_delete(self.element); });
|
||||||
|
mjsLight.def("set_frame", [](raw::MjsLight& self, raw::MjsFrame& frame) {
|
||||||
|
mjs_setFrame(self.element, &frame);
|
||||||
|
});
|
||||||
|
mjsLight.def("set_default", [](raw::MjsLight& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsLight.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsLight& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSMATERIAL =================================
|
||||||
|
mjsMaterial.def_property_readonly("id", [](raw::MjsMaterial& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsMaterial.def("delete",
|
||||||
|
[](raw::MjsMaterial& self) { mjs_delete(self.element); });
|
||||||
|
mjsMaterial.def("set_default",
|
||||||
|
[](raw::MjsMaterial& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsMaterial.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsMaterial& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSMESH =====================================
|
||||||
|
mjsMesh.def_property_readonly(
|
||||||
|
"id", [](raw::MjsMesh& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsMesh.def("delete", [](raw::MjsMesh& self) { mjs_delete(self.element); });
|
||||||
|
mjsMesh.def("set_default", [](raw::MjsMesh& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsMesh.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsMesh& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSPAIR =====================================
|
||||||
|
mjsPair.def_property_readonly(
|
||||||
|
"id", [](raw::MjsPair& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsPair.def("delete", [](raw::MjsPair& self) { mjs_delete(self.element); });
|
||||||
|
mjsPair.def("set_default", [](raw::MjsPair& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsPair.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsPair& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSEQUAL ====================================
|
||||||
|
mjsEquality.def_property_readonly("id", [](raw::MjsEquality& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsEquality.def("delete",
|
||||||
|
[](raw::MjsEquality& self) { mjs_delete(self.element); });
|
||||||
|
mjsEquality.def("set_default",
|
||||||
|
[](raw::MjsEquality& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsEquality.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsEquality& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSACTUATOR =================================
|
||||||
|
mjsActuator.def_property_readonly("id", [](raw::MjsActuator& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsActuator.def("delete",
|
||||||
|
[](raw::MjsActuator& self) { mjs_delete(self.element); });
|
||||||
|
mjsActuator.def("set_default",
|
||||||
|
[](raw::MjsActuator& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsActuator.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsActuator& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSTENDON ===================================
|
||||||
|
mjsTendon.def_property_readonly("id", [](raw::MjsTendon& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsTendon.def("delete",
|
||||||
|
[](raw::MjsTendon& self) { mjs_delete(self.element); });
|
||||||
|
mjsTendon.def("set_default", [](raw::MjsTendon& self, raw::MjsDefault& def) {
|
||||||
|
mjs_setDefault(self.element, &def);
|
||||||
|
});
|
||||||
|
mjsTendon.def(
|
||||||
|
"default",
|
||||||
|
[](raw::MjsTendon& self) -> raw::MjsDefault* {
|
||||||
|
return mjs_getDefault(self.element);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsTendon.def(
|
||||||
|
"wrap_site",
|
||||||
|
[](raw::MjsTendon& self, std::string& name) {
|
||||||
|
return mjs_wrapSite(&self, name.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsTendon.def(
|
||||||
|
"wrap_geom",
|
||||||
|
[](raw::MjsTendon& self, std::string& name, std::string& sidesite) {
|
||||||
|
return mjs_wrapGeom(&self, name.c_str(), sidesite.c_str());
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsTendon.def(
|
||||||
|
"wrap_joint",
|
||||||
|
[](raw::MjsTendon& self, std::string& name, double coef) {
|
||||||
|
return mjs_wrapJoint(&self, name.c_str(), coef);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsTendon.def(
|
||||||
|
"wrap_pulley",
|
||||||
|
[](raw::MjsTendon& self, double divisor) {
|
||||||
|
return mjs_wrapPulley(&self, divisor);
|
||||||
|
},
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
|
||||||
|
// ============================= MJSSENSOR ===================================
|
||||||
|
mjsSensor.def_property_readonly("id", [](raw::MjsSensor& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsSensor.def("delete",
|
||||||
|
[](raw::MjsSensor& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSFLEX =====================================
|
||||||
|
mjsFlex.def_property_readonly(
|
||||||
|
"id", [](raw::MjsFlex& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsFlex.def("delete", [](raw::MjsFlex& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSHFIELD ===================================
|
||||||
|
mjsHField.def_property_readonly("id", [](raw::MjsHField& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsHField.def("delete",
|
||||||
|
[](raw::MjsHField& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSSKIN =====================================
|
||||||
|
mjsSkin.def_property_readonly(
|
||||||
|
"id", [](raw::MjsSkin& self) -> int { return mjs_getId(self.element); },
|
||||||
|
py::return_value_policy::reference_internal);
|
||||||
|
mjsSkin.def("delete", [](raw::MjsSkin& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSTEXTURE ==================================
|
||||||
|
mjsTexture.def_property_readonly("id", [](raw::MjsTexture& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsTexture.def("delete",
|
||||||
|
[](raw::MjsTexture& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSKEY ======================================
|
||||||
|
mjsKey.def_property_readonly(
|
||||||
|
"id", [](raw::MjsKey& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsKey.def("delete", [](raw::MjsKey& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSTEXT =====================================
|
||||||
|
mjsText.def_property_readonly(
|
||||||
|
"id", [](raw::MjsText& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsText.def("delete", [](raw::MjsText& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSNUMERIC ==================================
|
||||||
|
mjsNumeric.def_property_readonly("id", [](raw::MjsNumeric& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsNumeric.def("delete",
|
||||||
|
[](raw::MjsNumeric& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSEXCLUDE ==================================
|
||||||
|
mjsExclude.def_property_readonly("id", [](raw::MjsExclude& self) -> int {
|
||||||
|
return mjs_getId(self.element);
|
||||||
|
});
|
||||||
|
mjsExclude.def("delete",
|
||||||
|
[](raw::MjsExclude& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSTUPLE ====================================
|
||||||
|
mjsTuple.def_property_readonly(
|
||||||
|
"id", [](raw::MjsTuple& self) -> int { return mjs_getId(self.element); });
|
||||||
|
mjsTuple.def("delete", [](raw::MjsTuple& self) { mjs_delete(self.element); });
|
||||||
|
|
||||||
|
// ============================= MJSPLUGIN ===================================
|
||||||
|
mjsPlugin.def_property_readonly("id", [](raw::MjsPlugin& self) -> int {
|
||||||
|
return mjs_getId(self.instance);
|
||||||
|
});
|
||||||
|
mjsPlugin.def("delete",
|
||||||
|
[](raw::MjsPlugin& self) { mjs_delete(self.instance); });
|
||||||
|
|
||||||
|
#include "specs.cc.inc"
|
||||||
|
} // PYBIND11_MODULE // NOLINT
|
||||||
|
} // namespace mujoco::python
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
# Copyright 2024 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.
|
||||||
|
# ==============================================================================
|
||||||
|
"""Tests for mjSpec bindings."""
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
from absl.testing import absltest
|
||||||
|
import mujoco
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def get_linenumber():
|
||||||
|
cf = inspect.currentframe()
|
||||||
|
return cf.f_back.f_lineno
|
||||||
|
|
||||||
|
|
||||||
|
class SpecsTest(absltest.TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
# Create a spec.
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
|
||||||
|
# Check that euler sequence order is set correctly.
|
||||||
|
self.assertEqual(spec.eulerseq[0], ord('x'))
|
||||||
|
spec.eulerseq = ['z', 'y', 'x']
|
||||||
|
self.assertEqual(spec.eulerseq[0], ord('z'))
|
||||||
|
|
||||||
|
# Add a body, check that it has default orientation.
|
||||||
|
body = spec.worldbody.add_body()
|
||||||
|
self.assertEqual(body.name, '')
|
||||||
|
np.testing.assert_array_equal(body.quat, [1, 0, 0, 0])
|
||||||
|
|
||||||
|
# Change the name of the body and read it back twice.
|
||||||
|
body.name = 'foobar'
|
||||||
|
self.assertEqual(body.name, 'foobar')
|
||||||
|
body.name = 'baz'
|
||||||
|
self.assertEqual(body.name, 'baz')
|
||||||
|
|
||||||
|
# Change the position of the body and read it back.
|
||||||
|
body.pos = [1, 2, 3]
|
||||||
|
np.testing.assert_array_equal(body.pos, [1, 2, 3])
|
||||||
|
self.assertEqual(body.pos.shape, (3,))
|
||||||
|
|
||||||
|
# Change the orientation of the body and read it back.
|
||||||
|
body.quat = [0, 1, 0, 0]
|
||||||
|
np.testing.assert_array_equal(body.quat, [0, 1, 0, 0])
|
||||||
|
self.assertEqual(body.quat.shape, (4,))
|
||||||
|
|
||||||
|
# Add a site to the body with user data and read it back.
|
||||||
|
site = body.add_site()
|
||||||
|
site.name = 'sitename'
|
||||||
|
site.userdata = [1, 2, 3, 4, 5, 6]
|
||||||
|
self.assertEqual(site.name, 'sitename')
|
||||||
|
np.testing.assert_array_equal(site.userdata, [1, 2, 3, 4, 5, 6])
|
||||||
|
|
||||||
|
# Check that the site and body have no id before compilation.
|
||||||
|
self.assertEqual(body.id, -1)
|
||||||
|
self.assertEqual(site.id, -1)
|
||||||
|
|
||||||
|
# Compile the spec and check for expected values in the model.
|
||||||
|
model = spec.compile()
|
||||||
|
self.assertEqual(spec.worldbody.id, 0)
|
||||||
|
self.assertEqual(body.id, 1)
|
||||||
|
self.assertEqual(site.id, 0)
|
||||||
|
self.assertEqual(model.nbody, 2) # 2 bodies, including the world body
|
||||||
|
np.testing.assert_array_equal(model.body_pos[1], [1, 2, 3])
|
||||||
|
np.testing.assert_array_equal(model.body_quat[1], [0, 1, 0, 0])
|
||||||
|
self.assertEqual(model.nsite, 1)
|
||||||
|
self.assertEqual(model.nuser_site, 6)
|
||||||
|
np.testing.assert_array_equal(model.site_user[0], [1, 2, 3, 4, 5, 6])
|
||||||
|
|
||||||
|
self.assertEqual(spec.to_xml(), textwrap.dedent("""\
|
||||||
|
<mujoco model="MuJoCo Model">
|
||||||
|
<compiler angle="radian"/>
|
||||||
|
|
||||||
|
<size nuser_site="6"/>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<body name="baz" pos="1 2 3" quat="0 1 0 0">
|
||||||
|
<site name="sitename" pos="0 0 0" user="1 2 3 4 5 6"/>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
"""),)
|
||||||
|
|
||||||
|
def test_compile_errors_with_line_info(self):
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
|
||||||
|
added_on_line = get_linenumber() + 1
|
||||||
|
geom = spec.worldbody.add_geom()
|
||||||
|
geom.name = 'MyGeom'
|
||||||
|
geom.info = f'geom added on line {added_on_line}'
|
||||||
|
|
||||||
|
# Try to compile, get error.
|
||||||
|
expected_error = (
|
||||||
|
'Error: size 0 must be positive in geom\n'
|
||||||
|
+ f'Element name \'MyGeom\', id 0, geom added on line {added_on_line}'
|
||||||
|
)
|
||||||
|
with self.assertRaisesRegex(ValueError, expected_error):
|
||||||
|
spec.compile()
|
||||||
|
|
||||||
|
def test_recompile(self):
|
||||||
|
# Create a spec.
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
|
||||||
|
# Add movable body1.
|
||||||
|
body1 = spec.worldbody.add_body()
|
||||||
|
geom = body1.add_geom()
|
||||||
|
geom.size[0] = 1
|
||||||
|
geom.pos = [1, 1, 0]
|
||||||
|
joint = body1.add_joint()
|
||||||
|
joint.type = mujoco.mjtJoint.mjJNT_BALL
|
||||||
|
|
||||||
|
# Compile model, make data.
|
||||||
|
model = spec.compile()
|
||||||
|
data = mujoco.MjData(model)
|
||||||
|
|
||||||
|
# Simulate for 1 second.
|
||||||
|
while data.time < 1:
|
||||||
|
mujoco.mj_step(model, data)
|
||||||
|
|
||||||
|
# Add movable body2.
|
||||||
|
body2 = spec.worldbody.add_body()
|
||||||
|
body2.pos[1] = 3
|
||||||
|
geom = body2.add_geom()
|
||||||
|
geom.size[0] = 1
|
||||||
|
geom.pos = [0, 1, 0]
|
||||||
|
joint = body2.add_joint()
|
||||||
|
joint.type = mujoco.mjtJoint.mjJNT_BALL
|
||||||
|
|
||||||
|
# Recompile model and data while maintaining the state.
|
||||||
|
model_new, data_new = spec.recompile(model, data)
|
||||||
|
|
||||||
|
# Check that the state is preserved.
|
||||||
|
np.testing.assert_array_equal(model_new.body_pos[1], model.body_pos[1])
|
||||||
|
np.testing.assert_array_equal(data_new.qpos[:4], data.qpos)
|
||||||
|
np.testing.assert_array_equal(data_new.qvel[:3], data.qvel)
|
||||||
|
|
||||||
|
def test_uncompiled_spec_cannot_be_written(self):
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
|
||||||
|
# Cannot write XML of an uncompiled spec.
|
||||||
|
expected_error = 'XML Write error: Only compiled model can be written'
|
||||||
|
with self.assertRaisesWithLiteralMatch(mujoco.FatalError, expected_error):
|
||||||
|
spec.to_xml()
|
||||||
|
|
||||||
|
def test_modelname_default_class(self):
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
spec.modelname = 'test'
|
||||||
|
|
||||||
|
main = spec.default()
|
||||||
|
main.geom.size[0] = 2
|
||||||
|
|
||||||
|
def1 = spec.add_default('def1', main)
|
||||||
|
def1.geom.size[0] = 3
|
||||||
|
|
||||||
|
spec.worldbody.add_geom(def1)
|
||||||
|
spec.worldbody.add_geom(main)
|
||||||
|
|
||||||
|
spec.compile()
|
||||||
|
self.assertEqual(spec.to_xml(), textwrap.dedent("""\
|
||||||
|
<mujoco model="test">
|
||||||
|
<compiler angle="radian"/>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<geom size="2 0 0"/>
|
||||||
|
<default class="def1">
|
||||||
|
<geom size="3 0 0"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<geom class="def1"/>
|
||||||
|
<geom/>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
"""))
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
spec.modelname = 'test'
|
||||||
|
|
||||||
|
main = spec.default()
|
||||||
|
main.geom.size[0] = 2
|
||||||
|
|
||||||
|
def1 = spec.add_default('def1', main)
|
||||||
|
def1.geom.size[0] = 3
|
||||||
|
|
||||||
|
spec.worldbody.add_geom(def1)
|
||||||
|
spec.worldbody.add_geom(main)
|
||||||
|
|
||||||
|
spec.compile()
|
||||||
|
self.assertEqual(spec.to_xml(), textwrap.dedent("""\
|
||||||
|
<mujoco model="test">
|
||||||
|
<compiler angle="radian"/>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<geom size="2 0 0"/>
|
||||||
|
<default class="def1">
|
||||||
|
<geom size="3 0 0"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<geom class="def1"/>
|
||||||
|
<geom/>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
|
"""))
|
||||||
|
|
||||||
|
def test_element_list(self):
|
||||||
|
spec = mujoco.MjSpec()
|
||||||
|
sensor1 = spec.add_sensor()
|
||||||
|
sensor2 = spec.add_sensor()
|
||||||
|
sensor3 = spec.add_sensor()
|
||||||
|
sensor1.name = 'sensor1'
|
||||||
|
sensor2.name = 'sensor2'
|
||||||
|
sensor3.name = 'sensor3'
|
||||||
|
self.assertLen(spec.sensors, 3)
|
||||||
|
self.assertEqual(spec.sensors[0].name, 'sensor1')
|
||||||
|
self.assertEqual(spec.sensors[1].name, 'sensor2')
|
||||||
|
self.assertEqual(spec.sensors[2].name, 'sensor3')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
absltest.main()
|
||||||
+47
-23
@@ -28,6 +28,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -316,24 +317,22 @@ static raw::MjModel* LoadModelFileImpl(
|
|||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const std::vector<VfsAsset>& assets,
|
const std::vector<VfsAsset>& assets,
|
||||||
LoadFunc&& loadfunc) {
|
LoadFunc&& loadfunc) {
|
||||||
std::unique_ptr<mjVFS, void(*)(mjVFS*)> vfs(nullptr, [](mjVFS*){});
|
mjVFS vfs;
|
||||||
|
mjVFS* vfs_ptr = nullptr;
|
||||||
if (!assets.empty()) {
|
if (!assets.empty()) {
|
||||||
// mjVFS should be allocated on the heap, because it's ~2MB
|
mj_defaultVFS(&vfs);
|
||||||
vfs = decltype(vfs)(new mjVFS, [](mjVFS* vfs) {
|
vfs_ptr = &vfs;
|
||||||
mj_deleteVFS(vfs);
|
|
||||||
delete vfs;
|
|
||||||
});
|
|
||||||
mj_defaultVFS(vfs.get());
|
|
||||||
for (const auto& asset : assets) {
|
for (const auto& asset : assets) {
|
||||||
const int vfs_error = InterceptMjErrors(mj_addBufferVFS)(
|
const int vfs_error = InterceptMjErrors(mj_addBufferVFS)(
|
||||||
vfs.get(), asset.name, asset.content, asset.content_size);
|
vfs_ptr, asset.name, asset.content, asset.content_size);
|
||||||
if (vfs_error) {
|
if (vfs_error) {
|
||||||
throw py::value_error("assets dict is too big");
|
throw py::value_error("assets dict is too big");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
raw::MjModel* model = loadfunc(filename.c_str(), vfs.get());
|
raw::MjModel* model = loadfunc(filename.c_str(), vfs_ptr);
|
||||||
|
mj_deleteVFS(vfs_ptr);
|
||||||
if (model && !model->buffer) {
|
if (model && !model->buffer) {
|
||||||
mj_deleteModel(model);
|
mj_deleteModel(model);
|
||||||
model = nullptr;
|
model = nullptr;
|
||||||
@@ -350,12 +349,6 @@ ConvertAssetsDict(
|
|||||||
std::vector<VfsAsset> out;
|
std::vector<VfsAsset> out;
|
||||||
if (assets.has_value()) {
|
if (assets.has_value()) {
|
||||||
for (const auto& [name, content] : *assets) {
|
for (const auto& [name, content] : *assets) {
|
||||||
if (name.length() >= mjMAXVFSNAME) {
|
|
||||||
std::ostringstream error;
|
|
||||||
error << "Filename length " << name.length() << " exceeds "
|
|
||||||
<< mjMAXVFSNAME - 1 << " character limit: " << name;
|
|
||||||
throw py::value_error(error.str());
|
|
||||||
}
|
|
||||||
out.emplace_back(name.c_str(), PYBIND11_BYTES_AS_STRING(content.ptr()),
|
out.emplace_back(name.c_str(), PYBIND11_BYTES_AS_STRING(content.ptr()),
|
||||||
py::len(content));
|
py::len(content));
|
||||||
}
|
}
|
||||||
@@ -430,6 +423,27 @@ MjModelWrapper MjModelWrapper::LoadXML(
|
|||||||
return MjModelWrapper(model);
|
return MjModelWrapper(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MjModelWrapper MjModelWrapper::CompileSpec(raw::MjSpec* spec) {
|
||||||
|
auto m = mj_compile(spec, nullptr);
|
||||||
|
if (!m || mjs_isWarning(spec)) {
|
||||||
|
throw py::value_error(mjs_getError(spec));
|
||||||
|
}
|
||||||
|
return MjModelWrapper(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
py::tuple RecompileSpec(raw::MjSpec* spec, const MjModelWrapper& old_m,
|
||||||
|
const MjDataWrapper& old_d) {
|
||||||
|
raw::MjModel* m = static_cast<raw::MjModel*>(mju_malloc(sizeof(mjModel)));
|
||||||
|
m->buffer = nullptr;
|
||||||
|
raw::MjData* d = mj_copyData(nullptr, old_m.get(), old_d.get());
|
||||||
|
mj_recompile(spec, nullptr, m, d);
|
||||||
|
|
||||||
|
py::object m_pyobj = py::cast((MjModelWrapper(m)));
|
||||||
|
py::object d_pyobj =
|
||||||
|
py::cast((MjDataWrapper(py::cast<MjModelWrapper*>(m_pyobj), d)));
|
||||||
|
return py::make_tuple(m_pyobj, d_pyobj);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// A byte at the start of serialized mjModel structs, which can be incremented
|
// A byte at the start of serialized mjModel structs, which can be incremented
|
||||||
// when we change the serialization logic to reject pickles from an unsupported
|
// when we change the serialization logic to reject pickles from an unsupported
|
||||||
@@ -1056,7 +1070,6 @@ MjvGLCameraWrapper::MjWrapper(const MjvGLCameraWrapper& other)
|
|||||||
#define X(var) var(InitPyArray(ptr_->var, owner_))
|
#define X(var) var(InitPyArray(ptr_->var, owner_))
|
||||||
MjvGeomWrapper::MjWrapper()
|
MjvGeomWrapper::MjWrapper()
|
||||||
: WrapperBase(new raw::MjvGeom{}),
|
: WrapperBase(new raw::MjvGeom{}),
|
||||||
X(texrepeat),
|
|
||||||
X(size),
|
X(size),
|
||||||
X(pos),
|
X(pos),
|
||||||
mat([this]() {
|
mat([this]() {
|
||||||
@@ -1069,7 +1082,6 @@ MjvGeomWrapper::MjWrapper()
|
|||||||
|
|
||||||
MjvGeomWrapper::MjWrapper(raw::MjvGeom* ptr, py::handle owner)
|
MjvGeomWrapper::MjWrapper(raw::MjvGeom* ptr, py::handle owner)
|
||||||
: WrapperBase(ptr, owner),
|
: WrapperBase(ptr, owner),
|
||||||
X(texrepeat),
|
|
||||||
X(size),
|
X(size),
|
||||||
X(pos),
|
X(pos),
|
||||||
mat([this]() {
|
mat([this]() {
|
||||||
@@ -1557,6 +1569,11 @@ PYBIND11_MODULE(_structs, m) {
|
|||||||
py::arg("xml"), py::arg_v("assets", py::none()),
|
py::arg("xml"), py::arg_v("assets", py::none()),
|
||||||
py::doc(
|
py::doc(
|
||||||
R"(Loads an MjModel from an XML string and an optional assets dictionary.)"));
|
R"(Loads an MjModel from an XML string and an optional assets dictionary.)"));
|
||||||
|
mjModel.def_static(
|
||||||
|
"_from_spec_ptr", [](uintptr_t addr) {
|
||||||
|
return MjModelWrapper::CompileSpec(
|
||||||
|
reinterpret_cast<raw::MjSpec*>(addr));
|
||||||
|
});
|
||||||
mjModel.def_static(
|
mjModel.def_static(
|
||||||
"from_xml_path", &MjModelWrapper::LoadXMLFile,
|
"from_xml_path", &MjModelWrapper::LoadXMLFile,
|
||||||
py::arg("filename"), py::arg_v("assets", py::none()),
|
py::arg("filename"), py::arg_v("assets", py::none()),
|
||||||
@@ -1907,9 +1924,11 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
mjData.def("__copy__", [](const MjDataWrapper& other) {
|
mjData.def("__copy__", [](const MjDataWrapper& other) {
|
||||||
return MjDataWrapper(other);
|
return MjDataWrapper(other);
|
||||||
});
|
});
|
||||||
mjData.def("__deepcopy__", [](const MjDataWrapper& other, py::dict) {
|
mjData.def("__deepcopy__", [](const MjDataWrapper& other, py::dict memo) {
|
||||||
MjModelWrapper* model_copy = new MjModelWrapper(other.model());
|
// Use copy.deepcopy(model) to make a model that Python is aware of.
|
||||||
return MjDataWrapper(other, model_copy);
|
py::object new_model_py =
|
||||||
|
py::cast(other.model()).attr("__deepcopy__")(memo);
|
||||||
|
return MjDataWrapper(other, new_model_py.cast<MjModelWrapper*>());
|
||||||
});
|
});
|
||||||
mjData.def(py::pickle(
|
mjData.def(py::pickle(
|
||||||
[](const MjDataWrapper& d) { // __getstate__
|
[](const MjDataWrapper& d) { // __getstate__
|
||||||
@@ -2185,8 +2204,7 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
X(objtype);
|
X(objtype);
|
||||||
X(objid);
|
X(objid);
|
||||||
X(category);
|
X(category);
|
||||||
X(texid);
|
X(matid);
|
||||||
X(texuniform);
|
|
||||||
X(texcoord);
|
X(texcoord);
|
||||||
X(segid);
|
X(segid);
|
||||||
X(emission);
|
X(emission);
|
||||||
@@ -2199,7 +2217,6 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
#define X(var) DefinePyArray(mjvGeom, #var, &MjvGeomWrapper::var)
|
#define X(var) DefinePyArray(mjvGeom, #var, &MjvGeomWrapper::var)
|
||||||
X(texrepeat);
|
|
||||||
X(size);
|
X(size);
|
||||||
X(pos);
|
X(pos);
|
||||||
X(mat);
|
X(mat);
|
||||||
@@ -2404,5 +2421,12 @@ This is useful for example when the MJB is not available as a file on disk.)"));
|
|||||||
},
|
},
|
||||||
py::arg("cam1"), py::arg("cam2"),
|
py::arg("cam1"), py::arg("cam2"),
|
||||||
py::doc(python_traits::mjv_averageCamera::doc));
|
py::doc(python_traits::mjv_averageCamera::doc));
|
||||||
|
|
||||||
|
m.def(
|
||||||
|
"_recompile_spec_addr",
|
||||||
|
[](uintptr_t spec_addr, const MjModelWrapper& m, const MjDataWrapper& d) {
|
||||||
|
return RecompileSpec(reinterpret_cast<raw::MjSpec*>(spec_addr), m, d);
|
||||||
|
}
|
||||||
|
);
|
||||||
} // PYBIND11_MODULE NOLINT(readability/fn_size)
|
} // PYBIND11_MODULE NOLINT(readability/fn_size)
|
||||||
} // namespace mujoco::python::_impl
|
} // namespace mujoco::python::_impl
|
||||||
|
|||||||
+13
-6
@@ -462,6 +462,10 @@ class MjWrapper<raw::MjModel> : public WrapperBase<raw::MjModel> {
|
|||||||
public:
|
public:
|
||||||
MjWrapper(const MjWrapper&);
|
MjWrapper(const MjWrapper&);
|
||||||
MjWrapper(MjWrapper&&);
|
MjWrapper(MjWrapper&&);
|
||||||
|
|
||||||
|
// Takes ownership of the raw mjModel pointer.
|
||||||
|
explicit MjWrapper(raw::MjModel* ptr);
|
||||||
|
|
||||||
~MjWrapper();
|
~MjWrapper();
|
||||||
|
|
||||||
MjModelIndexer& indexer() { return indexer_; }
|
MjModelIndexer& indexer() { return indexer_; }
|
||||||
@@ -485,6 +489,8 @@ class MjWrapper<raw::MjModel> : public WrapperBase<raw::MjModel> {
|
|||||||
const std::optional<
|
const std::optional<
|
||||||
std::unordered_map<std::string, pybind11::bytes>>& assets);
|
std::unordered_map<std::string, pybind11::bytes>>& assets);
|
||||||
|
|
||||||
|
static MjWrapper CompileSpec(raw::MjSpec* spec);
|
||||||
|
|
||||||
static constexpr char kFromRawPointer[] =
|
static constexpr char kFromRawPointer[] =
|
||||||
"__MUJOCO_STRUCTS_MJMODELWRAPPER_LOOKUP";
|
"__MUJOCO_STRUCTS_MJMODELWRAPPER_LOOKUP";
|
||||||
static MjWrapper* FromRawPointer(raw::MjModel* m) noexcept;
|
static MjWrapper* FromRawPointer(raw::MjModel* m) noexcept;
|
||||||
@@ -502,8 +508,6 @@ class MjWrapper<raw::MjModel> : public WrapperBase<raw::MjModel> {
|
|||||||
pybind11::bytes paths_bytes;
|
pybind11::bytes paths_bytes;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit MjWrapper(raw::MjModel* ptr);
|
|
||||||
|
|
||||||
MjModelIndexer indexer_;
|
MjModelIndexer indexer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -591,8 +595,14 @@ class MjWrapper<raw::MjData>: public WrapperBase<raw::MjData> {
|
|||||||
explicit MjWrapper(MjModelWrapper* model);
|
explicit MjWrapper(MjModelWrapper* model);
|
||||||
MjWrapper(const MjWrapper& other);
|
MjWrapper(const MjWrapper& other);
|
||||||
MjWrapper(MjWrapper&&);
|
MjWrapper(MjWrapper&&);
|
||||||
|
|
||||||
// Used for deepcopy
|
// Used for deepcopy
|
||||||
MjWrapper(const MjWrapper& other, MjModelWrapper* model);
|
MjWrapper(const MjWrapper& other, MjModelWrapper* model);
|
||||||
|
|
||||||
|
// Internal constructor which takes ownership of given mjData pointer.
|
||||||
|
// Used for deserialization and recompile.
|
||||||
|
explicit MjWrapper(MjModelWrapper* model, raw::MjData* d);
|
||||||
|
|
||||||
~MjWrapper();
|
~MjWrapper();
|
||||||
|
|
||||||
const MjModelWrapper& model() const { return *model_; }
|
const MjModelWrapper& model() const { return *model_; }
|
||||||
@@ -622,9 +632,6 @@ class MjWrapper<raw::MjData>: public WrapperBase<raw::MjData> {
|
|||||||
py_array_or_tuple_t<mjtNum> energy;
|
py_array_or_tuple_t<mjtNum> energy;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal constructor which takes ownership of given mjData pointer.
|
|
||||||
// Used for deserialization.
|
|
||||||
explicit MjWrapper(MjModelWrapper* model, raw::MjData* d);
|
|
||||||
raw::MjData* Copy() const;
|
raw::MjData* Copy() const;
|
||||||
|
|
||||||
// A reference to the model that was used to create this mjData.
|
// A reference to the model that was used to create this mjData.
|
||||||
@@ -727,7 +734,7 @@ class MjWrapper<raw::MjvGeom> : public WrapperBase<raw::MjvGeom> {
|
|||||||
py_array_or_tuple_t< \
|
py_array_or_tuple_t< \
|
||||||
std::remove_all_extents_t<decltype(raw::MjvGeom::var)>> \
|
std::remove_all_extents_t<decltype(raw::MjvGeom::var)>> \
|
||||||
var
|
var
|
||||||
X(texrepeat);
|
X(matid);
|
||||||
X(size);
|
X(size);
|
||||||
X(pos);
|
X(pos);
|
||||||
X(mat);
|
X(mat);
|
||||||
|
|||||||
@@ -247,7 +247,11 @@ class USDExporter:
|
|||||||
|
|
||||||
assert geom_name not in self.geom_names
|
assert geom_name not in self.geom_names
|
||||||
|
|
||||||
texture_file = self.texture_files[geom.texid] if geom.texid != -1 else None
|
texture_file = (
|
||||||
|
self.texture_files[self.model.mat_texid[mujoco.mjNTEXMAT*geom.matid]]
|
||||||
|
if geom.matid != -1
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
|
||||||
# handling meshes in our scene
|
# handling meshes in our scene
|
||||||
if geom.type == mujoco.mjtGeom.mjGEOM_MESH:
|
if geom.type == mujoco.mjtGeom.mjGEOM_MESH:
|
||||||
|
|||||||
@@ -94,6 +94,20 @@ class Handle:
|
|||||||
def user_scn(self):
|
def user_scn(self):
|
||||||
return self._user_scn
|
return self._user_scn
|
||||||
|
|
||||||
|
@property
|
||||||
|
def m(self):
|
||||||
|
sim = self._sim()
|
||||||
|
if sim is not None:
|
||||||
|
return sim.m
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def d(self):
|
||||||
|
sim = self._sim()
|
||||||
|
if sim is not None:
|
||||||
|
return sim.d
|
||||||
|
return None
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
sim = self._sim()
|
sim = self._sim()
|
||||||
if sim is not None:
|
if sim is not None:
|
||||||
|
|||||||
@@ -347,6 +347,7 @@ setuptools.setup(
|
|||||||
CMakeExtension('mujoco._render'),
|
CMakeExtension('mujoco._render'),
|
||||||
CMakeExtension('mujoco._rollout'),
|
CMakeExtension('mujoco._rollout'),
|
||||||
CMakeExtension('mujoco._simulate'),
|
CMakeExtension('mujoco._simulate'),
|
||||||
|
CMakeExtension('mujoco._specs'),
|
||||||
CMakeExtension('mujoco._structs'),
|
CMakeExtension('mujoco._structs'),
|
||||||
],
|
],
|
||||||
scripts=[
|
scripts=[
|
||||||
|
|||||||
+197
-176
@@ -420,8 +420,8 @@
|
|||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Make renderer, render and show the pixels\n",
|
"# Make renderer, render and show the pixels\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -445,10 +445,11 @@
|
|||||||
},
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"renderer.update_scene(data)\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -480,11 +481,11 @@
|
|||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
"renderer.update_scene(data)\n",
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -508,9 +509,10 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Run this cell multiple times for different colors\n",
|
"# Run this cell multiple times for different colors\n",
|
||||||
"model.geom('red_box').rgba[:3] = np.random.rand(3)\n",
|
"model.geom('red_box').rgba[:3] = np.random.rand(3)\n",
|
||||||
"renderer.update_scene(data)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -540,12 +542,13 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data)\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data)\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
@@ -583,7 +586,6 @@
|
|||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# enable joint visualization option:\n",
|
"# enable joint visualization option:\n",
|
||||||
"scene_option = mujoco.MjvOption()\n",
|
"scene_option = mujoco.MjvOption()\n",
|
||||||
@@ -595,12 +597,13 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, scene_option=scene_option)\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data, scene_option=scene_option)\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
@@ -651,12 +654,13 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, scene_option=scene_option)\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data, scene_option=scene_option)\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=60)"
|
"media.show_video(frames, fps=60)"
|
||||||
]
|
]
|
||||||
@@ -760,12 +764,12 @@
|
|||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(tippe_top)\n",
|
"model = mujoco.MjModel.from_xml_string(tippe_top)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"mujoco.mj_forward(model, data)\n",
|
||||||
"renderer.update_scene(data, camera=\"closeup\")\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
|
" renderer.update_scene(data, camera=\"closeup\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -821,12 +825,13 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetDataKeyframe(model, data, 0) # Reset the state to keyframe 0\n",
|
"mujoco.mj_resetDataKeyframe(model, data, 0) # Reset the state to keyframe 0\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, \"closeup\")\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data, \"closeup\")\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
@@ -939,12 +944,14 @@
|
|||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(chaotic_pendulum)\n",
|
"model = mujoco.MjModel.from_xml_string(chaotic_pendulum)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model, 480, 640)\n",
|
"height = 480\n",
|
||||||
|
"width = 640\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
"renderer.update_scene(data, camera=\"fixed\")\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
|
" renderer.update_scene(data, camera=\"fixed\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -970,7 +977,8 @@
|
|||||||
"framerate = 30 # Hz\n",
|
"framerate = 30 # Hz\n",
|
||||||
"n_frames = int(n_seconds * framerate)\n",
|
"n_frames = int(n_seconds * framerate)\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"renderer = mujoco.Renderer(model, 240, 320)\n",
|
"height = 240\n",
|
||||||
|
"width = 320\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# set initial state\n",
|
"# set initial state\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
@@ -981,17 +989,18 @@
|
|||||||
"sim_time = 0\n",
|
"sim_time = 0\n",
|
||||||
"render_time = 0\n",
|
"render_time = 0\n",
|
||||||
"n_steps = 0\n",
|
"n_steps = 0\n",
|
||||||
"for i in range(n_frames):\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
" while data.time * framerate < i:\n",
|
" for i in range(n_frames):\n",
|
||||||
|
" while data.time * framerate < i:\n",
|
||||||
|
" tic = time.time()\n",
|
||||||
|
" mujoco.mj_step(model, data)\n",
|
||||||
|
" sim_time += time.time() - tic\n",
|
||||||
|
" n_steps += 1\n",
|
||||||
" tic = time.time()\n",
|
" tic = time.time()\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" renderer.update_scene(data, \"fixed\")\n",
|
||||||
" sim_time += time.time() - tic\n",
|
" frame = renderer.render()\n",
|
||||||
" n_steps += 1\n",
|
" render_time += time.time() - tic\n",
|
||||||
" tic = time.time()\n",
|
" frames.append(frame)\n",
|
||||||
" renderer.update_scene(data, \"fixed\")\n",
|
|
||||||
" frame = renderer.render()\n",
|
|
||||||
" render_time += time.time() - tic\n",
|
|
||||||
" frames.append(frame)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# print timing and play video\n",
|
"# print timing and play video\n",
|
||||||
"step_time = 1e6*sim_time/n_steps\n",
|
"step_time = 1e6*sim_time/n_steps\n",
|
||||||
@@ -1233,12 +1242,14 @@
|
|||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(free_body_MJCF)\n",
|
"model = mujoco.MjModel.from_xml_string(free_body_MJCF)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model, 400, 600)\n",
|
"height = 400\n",
|
||||||
|
"width = 600\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
"renderer.update_scene(data, \"fixed\")\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
|
" renderer.update_scene(data, \"fixed\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1262,7 +1273,6 @@
|
|||||||
"height = 240\n",
|
"height = 240\n",
|
||||||
"width = 320\n",
|
"width = 320\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"renderer = mujoco.Renderer(model, height, width)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# visualize contact frames and forces, make body transparent\n",
|
"# visualize contact frames and forces, make body transparent\n",
|
||||||
"options = mujoco.MjvOption()\n",
|
"options = mujoco.MjvOption()\n",
|
||||||
@@ -1282,12 +1292,13 @@
|
|||||||
"data.qvel[3:6] = 5*np.random.randn(3)\n",
|
"data.qvel[3:6] = 5*np.random.randn(3)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"for i in range(n_frames):\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
" while data.time < i/120.0: #1/4x real time\n",
|
" for i in range(n_frames):\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < i/120.0: #1/4x real time\n",
|
||||||
" renderer.update_scene(data, \"track\", options)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" frame = renderer.render()\n",
|
" renderer.update_scene(data, \"track\", options)\n",
|
||||||
" frames.append(frame)\n",
|
" frame = renderer.render()\n",
|
||||||
|
" frames.append(frame)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=30)"
|
"media.show_video(frames, fps=30)"
|
||||||
]
|
]
|
||||||
@@ -1440,16 +1451,16 @@
|
|||||||
"# load\n",
|
"# load\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model, height, width)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
"for i in range(n_frames):\n",
|
" mujoco.mj_resetData(model, data)\n",
|
||||||
" while data.time < i/30.0:\n",
|
" for i in range(n_frames):\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < i/30.0:\n",
|
||||||
" renderer.update_scene(data, \"y\")\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" frame = renderer.render()\n",
|
" renderer.update_scene(data, \"y\")\n",
|
||||||
" frames.append(frame)\n",
|
" frame = renderer.render()\n",
|
||||||
|
" frames.append(frame)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=30)"
|
"media.show_video(frames, fps=30)"
|
||||||
]
|
]
|
||||||
@@ -1520,12 +1531,14 @@
|
|||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"renderer = mujoco.Renderer(model, 480, 480)\n",
|
"height = 480\n",
|
||||||
|
"width = 480\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
"renderer.update_scene(data, \"fixed\")\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
|
" renderer.update_scene(data, \"fixed\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(renderer.render())\n"
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1553,21 +1566,20 @@
|
|||||||
"times = []\n",
|
"times = []\n",
|
||||||
"sensordata = []\n",
|
"sensordata = []\n",
|
||||||
"\n",
|
"\n",
|
||||||
"renderer = mujoco.Renderer(model, height, width)\n",
|
|
||||||
"\n",
|
|
||||||
"# constant actuator signal\n",
|
"# constant actuator signal\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"data.ctrl = 20\n",
|
"data.ctrl = 20\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"for i in range(n_frames):\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
" while data.time < i/fps:\n",
|
" for i in range(n_frames):\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < i/fps:\n",
|
||||||
" times.append(data.time)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" sensordata.append(data.sensor('accelerometer').data.copy())\n",
|
" times.append(data.time)\n",
|
||||||
" renderer.update_scene(data, \"fixed\")\n",
|
" sensordata.append(data.sensor('accelerometer').data.copy())\n",
|
||||||
" frame = renderer.render()\n",
|
" renderer.update_scene(data, \"fixed\")\n",
|
||||||
" frames.append(frame)\n",
|
" frame = renderer.render()\n",
|
||||||
|
" frames.append(frame)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=fps)"
|
"media.show_video(frames, fps=fps)"
|
||||||
]
|
]
|
||||||
@@ -1644,12 +1656,12 @@
|
|||||||
"</mujoco>\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"renderer.update_scene(data)\n",
|
" mujoco.mj_forward(model, data)\n",
|
||||||
"media.show_image(renderer.render())"
|
" renderer.update_scene(data)\n",
|
||||||
|
" media.show_image(renderer.render())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1664,9 +1676,10 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"scene_option.frame = mujoco.mjtFrame.mjFRAME_GEOM\n",
|
"scene_option.frame = mujoco.mjtFrame.mjFRAME_GEOM\n",
|
||||||
"scene_option.flags[mujoco.mjtVisFlag.mjVIS_TRANSPARENT] = True\n",
|
"scene_option.flags[mujoco.mjtVisFlag.mjVIS_TRANSPARENT] = True\n",
|
||||||
"renderer.update_scene(data, scene_option=scene_option)\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"frame = renderer.render()\n",
|
" renderer.update_scene(data, scene_option=scene_option)\n",
|
||||||
"media.show_image(frame)"
|
" frame = renderer.render()\n",
|
||||||
|
" media.show_image(frame)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1679,25 +1692,24 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"#@title Depth rendering {vertical-output: true}\n",
|
"#@title Depth rendering {vertical-output: true}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# update renderer to render depth\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"renderer.enable_depth_rendering()\n",
|
" # update renderer to render depth\n",
|
||||||
|
" renderer.enable_depth_rendering()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# reset the scene\n",
|
" # reset the scene\n",
|
||||||
"renderer.update_scene(data)\n",
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# depth is a float array, in meters.\n",
|
" # depth is a float array, in meters.\n",
|
||||||
"depth = renderer.render()\n",
|
" depth = renderer.render()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Shift nearest values to the origin.\n",
|
" # Shift nearest values to the origin.\n",
|
||||||
"depth -= depth.min()\n",
|
" depth -= depth.min()\n",
|
||||||
"# Scale by 2 mean distances of near rays.\n",
|
" # Scale by 2 mean distances of near rays.\n",
|
||||||
"depth /= 2*depth[depth <= 1].mean()\n",
|
" depth /= 2*depth[depth <= 1].mean()\n",
|
||||||
"# Scale to [0, 255]\n",
|
" # Scale to [0, 255]\n",
|
||||||
"pixels = 255*np.clip(depth, 0, 1)\n",
|
" pixels = 255*np.clip(depth, 0, 1)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_image(pixels.astype(np.uint8))\n",
|
" media.show_image(pixels.astype(np.uint8))"
|
||||||
"\n",
|
|
||||||
"renderer.disable_depth_rendering()"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1710,25 +1722,26 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"#@title Segmentation rendering {vertical-output: true}\n",
|
"#@title Segmentation rendering {vertical-output: true}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# update renderer to render segmentation\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"renderer.enable_segmentation_rendering()\n",
|
" renderer.disable_depth_rendering()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# reset the scene\n",
|
" # update renderer to render segmentation\n",
|
||||||
"renderer.update_scene(data)\n",
|
" renderer.enable_segmentation_rendering()\n",
|
||||||
"\n",
|
"\n",
|
||||||
"seg = renderer.render()\n",
|
" # reset the scene\n",
|
||||||
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Display the contents of the first channel, which contains object\n",
|
" seg = renderer.render()\n",
|
||||||
"# IDs. The second channel, seg[:, :, 1], contains object types.\n",
|
|
||||||
"geom_ids = seg[:, :, 0]\n",
|
|
||||||
"# Infinity is mapped to -1\n",
|
|
||||||
"geom_ids = geom_ids.astype(np.float64) + 1\n",
|
|
||||||
"# Scale to [0, 1]\n",
|
|
||||||
"geom_ids = geom_ids / geom_ids.max()\n",
|
|
||||||
"pixels = 255*geom_ids\n",
|
|
||||||
"media.show_image(pixels.astype(np.uint8))\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"renderer.disable_segmentation_rendering()"
|
" # Display the contents of the first channel, which contains object\n",
|
||||||
|
" # IDs. The second channel, seg[:, :, 1], contains object types.\n",
|
||||||
|
" geom_ids = seg[:, :, 0]\n",
|
||||||
|
" # Infinity is mapped to -1\n",
|
||||||
|
" geom_ids = geom_ids.astype(np.float64) + 1\n",
|
||||||
|
" # Scale to [0, 1]\n",
|
||||||
|
" geom_ids = geom_ids / geom_ids.max()\n",
|
||||||
|
" pixels = 255*geom_ids\n",
|
||||||
|
" media.show_image(pixels.astype(np.uint8))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1792,37 +1805,39 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"#@title Project from world to camera coordinates {vertical-output: true}\n",
|
"#@title Project from world to camera coordinates {vertical-output: true}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# reset the scene\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
"renderer.update_scene(data)\n",
|
" renderer.disable_segmentation_rendering()\n",
|
||||||
|
" # reset the scene\n",
|
||||||
|
" renderer.update_scene(data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Get the world coordinates of the box corners\n",
|
" # Get the world coordinates of the box corners\n",
|
||||||
"box_pos = data.geom_xpos[model.geom('red_box').id]\n",
|
" box_pos = data.geom_xpos[model.geom('red_box').id]\n",
|
||||||
"box_mat = data.geom_xmat[model.geom('red_box').id].reshape(3, 3)\n",
|
" box_mat = data.geom_xmat[model.geom('red_box').id].reshape(3, 3)\n",
|
||||||
"box_size = model.geom_size[model.geom('red_box').id]\n",
|
" box_size = model.geom_size[model.geom('red_box').id]\n",
|
||||||
"offsets = np.array([-1, 1]) * box_size[:, None]\n",
|
" offsets = np.array([-1, 1]) * box_size[:, None]\n",
|
||||||
"xyz_local = np.stack(list(itertools.product(*offsets))).T\n",
|
" xyz_local = np.stack(list(itertools.product(*offsets))).T\n",
|
||||||
"xyz_global = box_pos[:, None] + box_mat @ xyz_local\n",
|
" xyz_global = box_pos[:, None] + box_mat @ xyz_local\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Camera matrices multiply homogenous [x, y, z, 1] vectors.\n",
|
" # Camera matrices multiply homogenous [x, y, z, 1] vectors.\n",
|
||||||
"corners_homogeneous = np.ones((4, xyz_global.shape[1]), dtype=float)\n",
|
" corners_homogeneous = np.ones((4, xyz_global.shape[1]), dtype=float)\n",
|
||||||
"corners_homogeneous[:3, :] = xyz_global\n",
|
" corners_homogeneous[:3, :] = xyz_global\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Get the camera matrix.\n",
|
" # Get the camera matrix.\n",
|
||||||
"m = compute_camera_matrix(renderer, data)\n",
|
" m = compute_camera_matrix(renderer, data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Project world coordinates into pixel space. See:\n",
|
" # Project world coordinates into pixel space. See:\n",
|
||||||
"# https://en.wikipedia.org/wiki/3D_projection#Mathematical_formula\n",
|
" # https://en.wikipedia.org/wiki/3D_projection#Mathematical_formula\n",
|
||||||
"xs, ys, s = m @ corners_homogeneous\n",
|
" xs, ys, s = m @ corners_homogeneous\n",
|
||||||
"# x and y are in the pixel coordinate system.\n",
|
" # x and y are in the pixel coordinate system.\n",
|
||||||
"x = xs / s\n",
|
" x = xs / s\n",
|
||||||
"y = ys / s\n",
|
" y = ys / s\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Render the camera view and overlay the projected corner coordinates.\n",
|
" # Render the camera view and overlay the projected corner coordinates.\n",
|
||||||
"pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
"fig, ax = plt.subplots(1, 1)\n",
|
" fig, ax = plt.subplots(1, 1)\n",
|
||||||
"ax.imshow(pixels)\n",
|
" ax.imshow(pixels)\n",
|
||||||
"ax.plot(x, y, '+', c='w')\n",
|
" ax.plot(x, y, '+', c='w')\n",
|
||||||
"ax.set_axis_off()"
|
" ax.set_axis_off()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1894,17 +1909,18 @@
|
|||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"mujoco.mj_forward(model, data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model) as renderer:\n",
|
||||||
" # append data to the traces\n",
|
" while data.time < duration:\n",
|
||||||
" positions.append(data.geom_xpos[data.geom(\"green_sphere\").id].copy())\n",
|
" # append data to the traces\n",
|
||||||
" times.append(data.time)\n",
|
" positions.append(data.geom_xpos[data.geom(\"green_sphere\").id].copy())\n",
|
||||||
" speeds.append(get_geom_speed(model, data, \"green_sphere\"))\n",
|
" times.append(data.time)\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" speeds.append(get_geom_speed(model, data, \"green_sphere\"))\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data)\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" modify_scene(renderer.scene)\n",
|
" renderer.update_scene(data)\n",
|
||||||
" pixels = renderer.render()\n",
|
" modify_scene(renderer.scene)\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
@@ -2018,8 +2034,7 @@
|
|||||||
"</mujoco>\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(dominos_xml)\n",
|
"model = mujoco.MjModel.from_xml_string(dominos_xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n"
|
||||||
"renderer = mujoco.Renderer(model, height=1024, width=1440)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2035,16 +2050,19 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"duration = 2.5 # (seconds)\n",
|
"duration = 2.5 # (seconds)\n",
|
||||||
"framerate = 60 # (Hz)\n",
|
"framerate = 60 # (Hz)\n",
|
||||||
|
"height = 1024\n",
|
||||||
|
"width = 1440\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, camera='top')\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data, camera='top')\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
@@ -2061,6 +2079,8 @@
|
|||||||
"#@title Render from moving camera\n",
|
"#@title Render from moving camera\n",
|
||||||
"\n",
|
"\n",
|
||||||
"duration = 3 # (seconds)\n",
|
"duration = 3 # (seconds)\n",
|
||||||
|
"height = 1024\n",
|
||||||
|
"width = 1440\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# find time when box is thrown (speed > 2cm/s)\n",
|
"# find time when box is thrown (speed > 2cm/s)\n",
|
||||||
"throw_time = 0.0\n",
|
"throw_time = 0.0\n",
|
||||||
@@ -2115,13 +2135,14 @@
|
|||||||
"slowdown = 4 # 4x slow-down\n",
|
"slowdown = 4 # 4x slow-down\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"while data.time < duration:\n",
|
"with mujoco.Renderer(model, height, width) as renderer:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" while data.time < duration:\n",
|
||||||
" if len(frames) < data.time * framerate * slowdown:\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" cam.distance, cam.azimuth, cam.elevation, cam.lookat = cam_motion()\n",
|
" if len(frames) < data.time * framerate * slowdown:\n",
|
||||||
" renderer.update_scene(data, cam)\n",
|
" cam.distance, cam.azimuth, cam.elevation, cam.lookat = cam_motion()\n",
|
||||||
" pixels = renderer.render()\n",
|
" renderer.update_scene(data, cam)\n",
|
||||||
" frames.append(pixels)\n",
|
" pixels = renderer.render()\n",
|
||||||
|
" frames.append(pixels)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"media.show_video(frames, fps=framerate)"
|
"media.show_video(frames, fps=framerate)"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# This Makefile assumes that you have GLFW libraries and headers installed on,
|
|
||||||
# which is commonly available through your distro's package manager.
|
|
||||||
# On Debian and Ubuntu, GLFW can be installed via `apt install libglfw3-dev`.
|
|
||||||
|
|
||||||
COMMON=-O2 -I../include -L../lib -std=c++17 -pthread -Wl,-no-as-needed -Wl,-rpath,'$$ORIGIN'/../lib
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all:
|
|
||||||
$(CXX) $(COMMON) testspeed.cc -lmujoco -o ../bin/testspeed
|
|
||||||
$(CXX) $(COMMON) compile.cc -lmujoco -o ../bin/compile
|
|
||||||
$(CXX) $(COMMON) basic.cc -lmujoco -lglfw -o ../bin/basic
|
|
||||||
$(CXX) $(COMMON) record.cc -lmujoco -lglfw -o ../bin/record
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# This Makefile assumes that GLFW is installed via Homebrew.
|
|
||||||
# If your setup is different, you will need to set GLFWROOT manually.
|
|
||||||
|
|
||||||
# This Makefile also assumes that MuJoCo.app is present in /Applications.
|
|
||||||
|
|
||||||
GLFWROOT?=$(shell brew --prefix)
|
|
||||||
MUJOCOPATH?=/Applications/MuJoCo.app/Contents/Frameworks
|
|
||||||
|
|
||||||
CFLAGS=-O2 -F$(MUJOCOPATH) -I$(GLFWROOT)/include -pthread
|
|
||||||
CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++
|
|
||||||
ALLFLAGS=$(CXXFLAGS) -L$(GLFWROOT)/lib -Wl,-rpath,$(MUJOCOPATH)
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all:
|
|
||||||
clang++ $(ALLFLAGS) testspeed.cc -framework mujoco -o testspeed
|
|
||||||
clang++ $(ALLFLAGS) compile.cc -framework mujoco -o compile
|
|
||||||
clang++ $(ALLFLAGS) basic.cc -framework mujoco -lglfw -o basic
|
|
||||||
clang++ $(ALLFLAGS) record.cc -framework mujoco -lglfw -o record
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# A copy of the GLFW library is required to build some sample programs.
|
|
||||||
# If this is not already installed on your system, download the WIN64 archive
|
|
||||||
# from https://github.com/glfw/glfw/releases, and copy files as follows:
|
|
||||||
# - Copy the entire `include/GLFW` subdirectory to `mujoco/include/GLFW`.
|
|
||||||
# - Copy glfw3dll.lib from the subdirectory corresponding into your compiler
|
|
||||||
# choice to `mujoco/lib/glfw3dll.lib`.
|
|
||||||
# - Copy glfw3.dll from the same subdirectory into `mujoco/bin/glfw3.dll`.
|
|
||||||
|
|
||||||
COMMON=/O2 /MT /EHsc /arch:AVX /I../include /Fe../bin/
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all:
|
|
||||||
cl $(COMMON) testspeed.cc ../lib/mujoco.lib
|
|
||||||
cl $(COMMON) compile.cc ../lib/mujoco.lib
|
|
||||||
cl $(COMMON) basic.cc ../lib/glfw3dll.lib ../lib/mujoco.lib
|
|
||||||
cl $(COMMON) record.cc ../lib/glfw3dll.lib ../lib/mujoco.lib
|
|
||||||
del *.obj
|
|
||||||
@@ -104,6 +104,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_INTERPROCEDURAL_OPTIMIZATION AND (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(MujocoHarden)
|
include(MujocoHarden)
|
||||||
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
||||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
||||||
|
|||||||
+12
-10
@@ -34,18 +34,17 @@ mjData* d[maxthread];
|
|||||||
// per-thread statistics
|
// per-thread statistics
|
||||||
int contacts[maxthread];
|
int contacts[maxthread];
|
||||||
int constraints[maxthread];
|
int constraints[maxthread];
|
||||||
double simtime[maxthread];
|
mjtNum simtime[maxthread];
|
||||||
|
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
std::chrono::steady_clock::time_point tm_start;
|
|
||||||
mjtNum gettm(void) {
|
mjtNum gettm(void) {
|
||||||
std::chrono::duration<double, std::micro> elapsed;
|
using std::chrono::steady_clock;
|
||||||
elapsed = std::chrono::steady_clock::now() - tm_start;
|
using Microseconds = std::chrono::duration<double, std::micro>;
|
||||||
|
static steady_clock::time_point tm_start = steady_clock::now();
|
||||||
|
auto elapsed = Microseconds(steady_clock::now() - tm_start);
|
||||||
return elapsed.count();
|
return elapsed.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// deallocate and print message
|
// deallocate and print message
|
||||||
int finish(const char* msg = NULL, mjModel* m = NULL) {
|
int finish(const char* msg = NULL, mjModel* m = NULL) {
|
||||||
// deallocate model
|
// deallocate model
|
||||||
@@ -87,7 +86,7 @@ void simulate(int id, int nstep, mjtNum* ctrl) {
|
|||||||
constraints[id] = 0;
|
constraints[id] = 0;
|
||||||
|
|
||||||
// run and time
|
// run and time
|
||||||
double start = gettm();
|
mjtNum start = gettm();
|
||||||
for (int i=0; i < nstep; i++) {
|
for (int i=0; i < nstep; i++) {
|
||||||
// inject pseudo-random control noise
|
// inject pseudo-random control noise
|
||||||
mju_copy(d[id]->ctrl, ctrl + i*m->nu, m->nu);
|
mju_copy(d[id]->ctrl, ctrl + i*m->nu, m->nu);
|
||||||
@@ -126,7 +125,7 @@ int main(int argc, char** argv) {
|
|||||||
// read arguments
|
// read arguments
|
||||||
int nstep = 10000, nthread = 0, npoolthread = 0;
|
int nstep = 10000, nthread = 0, npoolthread = 0;
|
||||||
// inject small noise by default, to avoid fixed contact state
|
// inject small noise by default, to avoid fixed contact state
|
||||||
mjtNum ctrlnoise = 0.01;
|
double ctrlnoise = 0.01;
|
||||||
if (argc > 2 && (std::sscanf(argv[2], "%d", &nstep) != 1 || nstep <= 0)) {
|
if (argc > 2 && (std::sscanf(argv[2], "%d", &nstep) != 1 || nstep <= 0)) {
|
||||||
return finish("Invalid nstep argument");
|
return finish("Invalid nstep argument");
|
||||||
}
|
}
|
||||||
@@ -149,7 +148,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
// get filename, determine file type
|
// get filename, determine file type
|
||||||
std::string filename(argv[1]);
|
std::string filename(argv[1]);
|
||||||
bool binary = (filename.find(".mjb") != std::string::npos);
|
bool binary = (filename.find(".mjb") != std::string::npos); // NOLINT
|
||||||
|
|
||||||
// load model
|
// load model
|
||||||
char error[1000] = "Could not load binary model";
|
char error[1000] = "Could not load binary model";
|
||||||
@@ -191,8 +190,11 @@ int main(int argc, char** argv) {
|
|||||||
nstep,
|
nstep,
|
||||||
nthread > 1 ? " per thread" : "",
|
nthread > 1 ? " per thread" : "",
|
||||||
m->opt.timestep);
|
m->opt.timestep);
|
||||||
|
if (sizeof(mjtNum) == 4) {
|
||||||
|
std::printf(", using single-precision");
|
||||||
|
}
|
||||||
if (npoolthread > 1) {
|
if (npoolthread > 1) {
|
||||||
std::printf(", using %d threads for engine-internal threadpool", npoolthread);
|
std::printf(", using %d threads", npoolthread);
|
||||||
}
|
}
|
||||||
std::printf("...\n\n");
|
std::printf("...\n\n");
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
# This Makefile assumes that you have GLFW libraries and headers installed on,
|
|
||||||
# which is commonly available through your distro's package manager.
|
|
||||||
# On Debian and Ubuntu, GLFW can be installed via `apt install libglfw3-dev`.
|
|
||||||
|
|
||||||
COMMON=-O2 -I../include -L../lib -pthread -Wl,-no-as-needed -Wl,-rpath,'$$ORIGIN'/../lib
|
|
||||||
|
|
||||||
all:
|
|
||||||
$(CXX) $(COMMON) -std=c++17 -c simulate.cc
|
|
||||||
$(CC) $(COMMON) -std=c11 -c uitools.c
|
|
||||||
$(CXX) $(COMMON) -std=c++17 main.cc simulate.o uitools.o -lmujoco -lglfw -o ../bin/simulate
|
|
||||||
rm uitools.o simulate.o
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# This Makefile assumes that GLFW is installed via Homebrew.
|
|
||||||
# If your setup is different, you will need to set GLFWROOT manually.
|
|
||||||
|
|
||||||
# This Makefile also assumes that MuJoCo.app is present in /Applications.
|
|
||||||
|
|
||||||
GLFWROOT?=$(shell brew --prefix)
|
|
||||||
MUJOCOPATH?=/Applications/MuJoCo.app/Contents/Frameworks
|
|
||||||
|
|
||||||
CFLAGS=-O2 -F$(MUJOCOPATH) -I$(GLFWROOT)/include -pthread
|
|
||||||
CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++
|
|
||||||
ALLFLAGS=$(CXXFLAGS) -L$(GLFWROOT)/lib -Wl,-rpath,$(MUJOCOPATH)
|
|
||||||
|
|
||||||
all:
|
|
||||||
clang++ $(CXXFLAGS) -c macos_gui.mm
|
|
||||||
clang++ $(CXXFLAGS) -c simulate.cc
|
|
||||||
clang $(CFLAGS) -std=c11 -c uitools.c
|
|
||||||
clang++ $(CXXFLAGS) main.cc macos_gui.o simulate.o uitools.o -framework mujoco -framework Cocoa -lglfw -o simulate
|
|
||||||
rm *.o
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# A copy of the GLFW library is required to build some sample programs.
|
|
||||||
# If this is not already installed on your system, download the WIN64 archive
|
|
||||||
# from https://github.com/glfw/glfw/releases, and copy files as follows:
|
|
||||||
# - Copy the entire `include/GLFW` subdirectory to `mujoco/include/GLFW`.
|
|
||||||
# - Copy glfw3dll.lib from the subdirectory corresponding into your compiler
|
|
||||||
# choice to `mujoco/lib/glfw3dll.lib`.
|
|
||||||
# - Copy glfw3.dll from the same subdirectory into `mujoco/bin/glfw3.dll`.
|
|
||||||
|
|
||||||
COMMON=/O2 /MT /EHsc /arch:AVX /I../include /Fe../bin/
|
|
||||||
|
|
||||||
all:
|
|
||||||
cl $(COMMON) main.cc simulate.cc uitools.c ../lib/glfw3dll.lib ../lib/mujoco.lib
|
|
||||||
del *.obj
|
|
||||||
@@ -104,6 +104,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_INTERPROCEDURAL_OPTIMIZATION AND (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(MujocoHarden)
|
include(MujocoHarden)
|
||||||
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
set(EXTRA_COMPILE_OPTIONS ${EXTRA_COMPILE_OPTIONS} ${MUJOCO_HARDEN_COMPILE_OPTIONS})
|
||||||
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
set(EXTRA_LINK_OPTIONS ${EXTRA_LINK_OPTIONS} ${MUJOCO_HARDEN_LINK_OPTIONS})
|
||||||
|
|||||||
+2
-1
@@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@@ -334,7 +335,7 @@ void PhysicsLoop(mj::Simulate& sim) {
|
|||||||
|
|
||||||
// misalignment condition: distance from target sim time is bigger than syncmisalign
|
// misalignment condition: distance from target sim time is bigger than syncmisalign
|
||||||
bool misaligned =
|
bool misaligned =
|
||||||
mju_abs(Seconds(elapsedCPU).count()/slowdown - elapsedSim) > syncMisalign;
|
std::abs(Seconds(elapsedCPU).count()/slowdown - elapsedSim) > syncMisalign;
|
||||||
|
|
||||||
// out-of-sync (for any reason): reset sync times, step
|
// out-of-sync (for any reason): reset sync times, step
|
||||||
if (elapsedSim < 0 || elapsedCPU.count() < 0 || syncCPU.time_since_epoch().count() == 0 ||
|
if (elapsedSim < 0 || elapsedCPU.count() < 0 || syncCPU.time_since_epoch().count() == 0 ||
|
||||||
|
|||||||
+105
-97
@@ -117,13 +117,13 @@ enum {
|
|||||||
|
|
||||||
// file section of UI
|
// file section of UI
|
||||||
const mjuiDef defFile[] = {
|
const mjuiDef defFile[] = {
|
||||||
{mjITEM_SECTION, "File", 1, nullptr, "AF"},
|
{mjITEM_SECTION, "File", mjPRESERVE, nullptr, "AF"},
|
||||||
{mjITEM_BUTTON, "Save xml", 2, nullptr, ""},
|
{mjITEM_BUTTON, "Save xml", 2, nullptr, ""},
|
||||||
{mjITEM_BUTTON, "Save mjb", 2, nullptr, ""},
|
{mjITEM_BUTTON, "Save mjb", 2, nullptr, ""},
|
||||||
{mjITEM_BUTTON, "Print model", 2, nullptr, "CM"},
|
{mjITEM_BUTTON, "Print model", 2, nullptr, "CM"},
|
||||||
{mjITEM_BUTTON, "Print data", 2, nullptr, "CD"},
|
{mjITEM_BUTTON, "Print data", 2, nullptr, "CD"},
|
||||||
{mjITEM_BUTTON, "Quit", 1, nullptr, "CQ"},
|
{mjITEM_BUTTON, "Quit", 1, nullptr, "CQ"},
|
||||||
{mjITEM_BUTTON, "Screenshot", 2, nullptr, "CP"},
|
{mjITEM_BUTTON, "Screenshot", 2, nullptr, "CP"},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -674,15 +674,15 @@ void UpdateWatch(mj::Simulate* sim, const mjModel* m, const mjData* d) {
|
|||||||
//---------------------------------- UI construction -----------------------------------------------
|
//---------------------------------- UI construction -----------------------------------------------
|
||||||
|
|
||||||
// make physics section of UI
|
// make physics section of UI
|
||||||
void MakePhysicsSection(mj::Simulate* sim, int oldstate) {
|
void MakePhysicsSection(mj::Simulate* sim) {
|
||||||
mjOption* opt = sim->is_passive_ ? &sim->scnstate_.model.opt : &sim->m_->opt;
|
mjOption* opt = sim->is_passive_ ? &sim->scnstate_.model.opt : &sim->m_->opt;
|
||||||
mjuiDef defPhysics[] = {
|
mjuiDef defPhysics[] = {
|
||||||
{mjITEM_SECTION, "Physics", oldstate, nullptr, "AP"},
|
{mjITEM_SECTION, "Physics", mjPRESERVE, nullptr, "AP"},
|
||||||
{mjITEM_SELECT, "Integrator", 2, &(opt->integrator), "Euler\nRK4\nimplicit\nimplicitfast"},
|
{mjITEM_SELECT, "Integrator", 2, &(opt->integrator), "Euler\nRK4\nimplicit\nimplicitfast"},
|
||||||
{mjITEM_SELECT, "Cone", 2, &(opt->cone), "Pyramidal\nElliptic"},
|
{mjITEM_SELECT, "Cone", 2, &(opt->cone), "Pyramidal\nElliptic"},
|
||||||
{mjITEM_SELECT, "Jacobian", 2, &(opt->jacobian), "Dense\nSparse\nAuto"},
|
{mjITEM_SELECT, "Jacobian", 2, &(opt->jacobian), "Dense\nSparse\nAuto"},
|
||||||
{mjITEM_SELECT, "Solver", 2, &(opt->solver), "PGS\nCG\nNewton"},
|
{mjITEM_SELECT, "Solver", 2, &(opt->solver), "PGS\nCG\nNewton"},
|
||||||
{mjITEM_SEPARATOR, "Algorithmic Parameters", 1},
|
{mjITEM_SEPARATOR, "Algorithmic Parameters", mjPRESERVE},
|
||||||
{mjITEM_EDITNUM, "Timestep", 2, &(opt->timestep), "1 0 1"},
|
{mjITEM_EDITNUM, "Timestep", 2, &(opt->timestep), "1 0 1"},
|
||||||
{mjITEM_EDITINT, "Iterations", 2, &(opt->iterations), "1 0 1000"},
|
{mjITEM_EDITINT, "Iterations", 2, &(opt->iterations), "1 0 1000"},
|
||||||
{mjITEM_EDITNUM, "Tolerance", 2, &(opt->tolerance), "1 0 1"},
|
{mjITEM_EDITNUM, "Tolerance", 2, &(opt->tolerance), "1 0 1"},
|
||||||
@@ -695,22 +695,22 @@ void MakePhysicsSection(mj::Simulate* sim, int oldstate) {
|
|||||||
{mjITEM_EDITNUM, "API Rate", 2, &(opt->apirate), "1 0 1000"},
|
{mjITEM_EDITNUM, "API Rate", 2, &(opt->apirate), "1 0 1000"},
|
||||||
{mjITEM_EDITINT, "SDF Iter", 2, &(opt->sdf_iterations), "1 1 20"},
|
{mjITEM_EDITINT, "SDF Iter", 2, &(opt->sdf_iterations), "1 1 20"},
|
||||||
{mjITEM_EDITINT, "SDF Init", 2, &(opt->sdf_initpoints), "1 1 100"},
|
{mjITEM_EDITINT, "SDF Init", 2, &(opt->sdf_initpoints), "1 1 100"},
|
||||||
{mjITEM_SEPARATOR, "Physical Parameters", 1},
|
{mjITEM_SEPARATOR, "Physical Parameters", mjPRESERVE},
|
||||||
{mjITEM_EDITNUM, "Gravity", 2, opt->gravity, "3"},
|
{mjITEM_EDITNUM, "Gravity", 2, opt->gravity, "3"},
|
||||||
{mjITEM_EDITNUM, "Wind", 2, opt->wind, "3"},
|
{mjITEM_EDITNUM, "Wind", 2, opt->wind, "3"},
|
||||||
{mjITEM_EDITNUM, "Magnetic", 2, opt->magnetic, "3"},
|
{mjITEM_EDITNUM, "Magnetic", 2, opt->magnetic, "3"},
|
||||||
{mjITEM_EDITNUM, "Density", 2, &(opt->density), "1"},
|
{mjITEM_EDITNUM, "Density", 2, &(opt->density), "1"},
|
||||||
{mjITEM_EDITNUM, "Viscosity", 2, &(opt->viscosity), "1"},
|
{mjITEM_EDITNUM, "Viscosity", 2, &(opt->viscosity), "1"},
|
||||||
{mjITEM_EDITNUM, "Imp Ratio", 2, &(opt->impratio), "1"},
|
{mjITEM_EDITNUM, "Imp Ratio", 2, &(opt->impratio), "1"},
|
||||||
{mjITEM_SEPARATOR, "Disable Flags", 1},
|
{mjITEM_SEPARATOR, "Disable Flags", mjPRESERVE},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
mjuiDef defEnableFlags[] = {
|
mjuiDef defEnableFlags[] = {
|
||||||
{mjITEM_SEPARATOR, "Enable Flags", 1},
|
{mjITEM_SEPARATOR, "Enable Flags", mjPRESERVE},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
mjuiDef defOverride[] = {
|
mjuiDef defOverride[] = {
|
||||||
{mjITEM_SEPARATOR, "Contact Override", 1},
|
{mjITEM_SEPARATOR, "Contact Override", mjPRESERVE},
|
||||||
{mjITEM_EDITNUM, "Margin", 2, &(opt->o_margin), "1"},
|
{mjITEM_EDITNUM, "Margin", 2, &(opt->o_margin), "1"},
|
||||||
{mjITEM_EDITNUM, "Sol Imp", 2, &(opt->o_solimp), "5"},
|
{mjITEM_EDITNUM, "Sol Imp", 2, &(opt->o_solimp), "5"},
|
||||||
{mjITEM_EDITNUM, "Sol Ref", 2, &(opt->o_solref), "2"},
|
{mjITEM_EDITNUM, "Sol Ref", 2, &(opt->o_solref), "2"},
|
||||||
@@ -718,7 +718,7 @@ void MakePhysicsSection(mj::Simulate* sim, int oldstate) {
|
|||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
mjuiDef defDisableActuator[] = {
|
mjuiDef defDisableActuator[] = {
|
||||||
{mjITEM_SEPARATOR, "Actuator Group Enable", 1},
|
{mjITEM_SEPARATOR, "Actuator Group Enable", mjPRESERVE},
|
||||||
{mjITEM_CHECKBYTE, "Act Group 0", 2, sim->enableactuator+0, ""},
|
{mjITEM_CHECKBYTE, "Act Group 0", 2, sim->enableactuator+0, ""},
|
||||||
{mjITEM_CHECKBYTE, "Act Group 1", 2, sim->enableactuator+1, ""},
|
{mjITEM_CHECKBYTE, "Act Group 1", 2, sim->enableactuator+1, ""},
|
||||||
{mjITEM_CHECKBYTE, "Act Group 2", 2, sim->enableactuator+2, ""},
|
{mjITEM_CHECKBYTE, "Act Group 2", 2, sim->enableactuator+2, ""},
|
||||||
@@ -752,57 +752,39 @@ void MakePhysicsSection(mj::Simulate* sim, int oldstate) {
|
|||||||
|
|
||||||
// add actuator group enable/disable
|
// add actuator group enable/disable
|
||||||
mjui_add(&sim->ui0, defDisableActuator);
|
mjui_add(&sim->ui0, defDisableActuator);
|
||||||
|
|
||||||
|
// make some subsections closed by default
|
||||||
|
for (int i=0; i < sim->ui0.sect[SECT_PHYSICS].nitem; i++) {
|
||||||
|
mjuiItem* it = sim->ui0.sect[SECT_PHYSICS].item + i;
|
||||||
|
|
||||||
|
// close less useful subsections
|
||||||
|
if (it->type == mjITEM_SEPARATOR) {
|
||||||
|
if (mju::strcmp_arr(it->name, "Actuator Group Enable") &&
|
||||||
|
mju::strcmp_arr(it->name, "Contact Override") &&
|
||||||
|
mju::strcmp_arr(it->name, "Physical Parameters")) {
|
||||||
|
it->state = mjSEPCLOSED+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// make rendering section of UI
|
// make rendering section of UI
|
||||||
void MakeRenderingSection(mj::Simulate* sim, const mjModel* m, int oldstate) {
|
void MakeRenderingSection(mj::Simulate* sim, const mjModel* m) {
|
||||||
mjuiDef defRendering[] = {
|
mjuiDef defRendering[] = {
|
||||||
{
|
{mjITEM_SECTION, "Rendering", mjPRESERVE, nullptr, "AR"},
|
||||||
mjITEM_SECTION,
|
{mjITEM_SELECT, "Camera", 2, &(sim->camera), "Free\nTracking"},
|
||||||
"Rendering",
|
{mjITEM_SELECT, "Label", 2, &(sim->opt.label),
|
||||||
oldstate,
|
|
||||||
nullptr,
|
|
||||||
"AR"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mjITEM_SELECT,
|
|
||||||
"Camera",
|
|
||||||
2,
|
|
||||||
&(sim->camera),
|
|
||||||
"Free\nTracking"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mjITEM_SELECT,
|
|
||||||
"Label",
|
|
||||||
2,
|
|
||||||
&(sim->opt.label),
|
|
||||||
"None\nBody\nJoint\nGeom\nSite\nCamera\nLight\nTendon\n"
|
"None\nBody\nJoint\nGeom\nSite\nCamera\nLight\nTendon\n"
|
||||||
"Actuator\nConstraint\nFlex\nSkin\nSelection\nSel Pnt\nContact\nForce\nIsland"
|
"Actuator\nConstraint\nFlex\nSkin\nSelection\nSel Pnt\nContact\nForce\nIsland"
|
||||||
},
|
},
|
||||||
{
|
{mjITEM_SELECT, "Frame", 2, &(sim->opt.frame),
|
||||||
mjITEM_SELECT,
|
|
||||||
"Frame",
|
|
||||||
2,
|
|
||||||
&(sim->opt.frame),
|
|
||||||
"None\nBody\nGeom\nSite\nCamera\nLight\nContact\nWorld"
|
"None\nBody\nGeom\nSite\nCamera\nLight\nContact\nWorld"
|
||||||
},
|
},
|
||||||
{
|
{mjITEM_BUTTON, "Copy camera", 2, nullptr, ""},
|
||||||
mjITEM_BUTTON,
|
{mjITEM_SEPARATOR, "Model Elements", 1},
|
||||||
"Copy camera",
|
{mjITEM_END}
|
||||||
2,
|
|
||||||
nullptr,
|
|
||||||
""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mjITEM_SEPARATOR,
|
|
||||||
"Model Elements",
|
|
||||||
1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
mjITEM_END
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
mjuiDef defOpenGL[] = {
|
mjuiDef defOpenGL[] = {
|
||||||
{mjITEM_SEPARATOR, "OpenGL Effects", 1},
|
{mjITEM_SEPARATOR, "OpenGL Effects", 1},
|
||||||
@@ -876,18 +858,18 @@ void MakeRenderingSection(mj::Simulate* sim, const mjModel* m, int oldstate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make visualization section of UI
|
// make visualization section of UI
|
||||||
void MakeVisualizationSection(mj::Simulate* sim, const mjModel* m, int oldstate) {
|
void MakeVisualizationSection(mj::Simulate* sim, const mjModel* m) {
|
||||||
mjStatistic* stat = sim->is_passive_ ? &sim->scnstate_.model.stat : &sim->m_->stat;
|
mjStatistic* stat = sim->is_passive_ ? &sim->scnstate_.model.stat : &sim->m_->stat;
|
||||||
mjVisual* vis = sim->is_passive_ ? &sim->scnstate_.model.vis : &sim->m_->vis;
|
mjVisual* vis = sim->is_passive_ ? &sim->scnstate_.model.vis : &sim->m_->vis;
|
||||||
|
|
||||||
mjuiDef defVisualization[] = {
|
mjuiDef defVisualization[] = {
|
||||||
{mjITEM_SECTION, "Visualization", oldstate, nullptr, "AV"},
|
{mjITEM_SECTION, "Visualization", mjPRESERVE, nullptr, "AV"},
|
||||||
{mjITEM_SEPARATOR, "Headlight", 1},
|
{mjITEM_SEPARATOR, "Headlight", 1},
|
||||||
{mjITEM_RADIO, "Active", 5, &(vis->headlight.active), "Off\nOn"},
|
{mjITEM_RADIO, "Active", 5, &(vis->headlight.active), "Off\nOn"},
|
||||||
{mjITEM_EDITFLOAT, "Ambient", 2, &(vis->headlight.ambient), "3"},
|
{mjITEM_EDITFLOAT, "Ambient", 2, &(vis->headlight.ambient), "3"},
|
||||||
{mjITEM_EDITFLOAT, "Diffuse", 2, &(vis->headlight.diffuse), "3"},
|
{mjITEM_EDITFLOAT, "Diffuse", 2, &(vis->headlight.diffuse), "3"},
|
||||||
{mjITEM_EDITFLOAT, "Specular", 2, &(vis->headlight.specular), "3"},
|
{mjITEM_EDITFLOAT, "Specular", 2, &(vis->headlight.specular), "3"},
|
||||||
{mjITEM_SEPARATOR, "Free Camera", 1},
|
{mjITEM_SEPARATOR, "Free Camera", 1},
|
||||||
{mjITEM_RADIO, "Orthographic", 2, &(vis->global.orthographic), "No\nYes"},
|
{mjITEM_RADIO, "Orthographic", 2, &(vis->global.orthographic), "No\nYes"},
|
||||||
{mjITEM_EDITFLOAT, "Field of view", 2, &(vis->global.fovy), "1"},
|
{mjITEM_EDITFLOAT, "Field of view", 2, &(vis->global.fovy), "1"},
|
||||||
{mjITEM_EDITNUM, "Center", 2, &(stat->center), "3"},
|
{mjITEM_EDITNUM, "Center", 2, &(stat->center), "3"},
|
||||||
@@ -911,8 +893,8 @@ void MakeVisualizationSection(mj::Simulate* sim, const mjModel* m, int oldstate)
|
|||||||
{mjITEM_EDITFLOAT, "Haze", 2, &(vis->map.haze), "1"},
|
{mjITEM_EDITFLOAT, "Haze", 2, &(vis->map.haze), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Shadow clip", 2, &(vis->map.shadowclip), "1"},
|
{mjITEM_EDITFLOAT, "Shadow clip", 2, &(vis->map.shadowclip), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Shadow scale", 2, &(vis->map.shadowscale), "1"},
|
{mjITEM_EDITFLOAT, "Shadow scale", 2, &(vis->map.shadowscale), "1"},
|
||||||
{mjITEM_SEPARATOR, "Scale", 1},
|
{mjITEM_SEPARATOR, "Scale", mjPRESERVE},
|
||||||
{mjITEM_EDITNUM, "All [meansize]", 2, &(stat->meansize), "1"},
|
{mjITEM_EDITNUM, "All (meansize)", 2, &(stat->meansize), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Force width", 2, &(vis->scale.forcewidth), "1"},
|
{mjITEM_EDITFLOAT, "Force width", 2, &(vis->scale.forcewidth), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Contact width", 2, &(vis->scale.contactwidth), "1"},
|
{mjITEM_EDITFLOAT, "Contact width", 2, &(vis->scale.contactwidth), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Contact height", 2, &(vis->scale.contactheight), "1"},
|
{mjITEM_EDITFLOAT, "Contact height", 2, &(vis->scale.contactheight), "1"},
|
||||||
@@ -929,17 +911,43 @@ void MakeVisualizationSection(mj::Simulate* sim, const mjModel* m, int oldstate)
|
|||||||
{mjITEM_EDITFLOAT, "Frame width", 2, &(vis->scale.framewidth), "1"},
|
{mjITEM_EDITFLOAT, "Frame width", 2, &(vis->scale.framewidth), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Constraint", 2, &(vis->scale.constraint), "1"},
|
{mjITEM_EDITFLOAT, "Constraint", 2, &(vis->scale.constraint), "1"},
|
||||||
{mjITEM_EDITFLOAT, "Slider-crank", 2, &(vis->scale.slidercrank), "1"},
|
{mjITEM_EDITFLOAT, "Slider-crank", 2, &(vis->scale.slidercrank), "1"},
|
||||||
|
{mjITEM_SEPARATOR, "RGBA", mjPRESERVE},
|
||||||
|
{mjITEM_EDITFLOAT, "fog", 2, &(vis->rgba.fog), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "haze", 2, &(vis->rgba.haze), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "force", 2, &(vis->rgba.force), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "inertia", 2, &(vis->rgba.inertia), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "joint", 2, &(vis->rgba.joint), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "actuator", 2, &(vis->rgba.actuator), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "actnegative", 2, &(vis->rgba.actuatornegative), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "actpositive", 2, &(vis->rgba.actuatorpositive), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "com", 2, &(vis->rgba.com), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "camera", 2, &(vis->rgba.camera), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "light", 2, &(vis->rgba.light), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "selectpoint", 2, &(vis->rgba.selectpoint), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "connect", 2, &(vis->rgba.connect), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "contactpoint", 2, &(vis->rgba.contactpoint), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "contactforce", 2, &(vis->rgba.contactforce), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "contactfriction", 2, &(vis->rgba.contactfriction), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "contacttorque", 2, &(vis->rgba.contacttorque), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "contactgap", 2, &(vis->rgba.contactgap), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "rangefinder", 2, &(vis->rgba.rangefinder), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "constraint", 2, &(vis->rgba.constraint), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "slidercrank", 2, &(vis->rgba.slidercrank), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "crankbroken", 2, &(vis->rgba.crankbroken), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "frustum", 2, &(vis->rgba.frustum), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "bv", 2, &(vis->rgba.bv), "4"},
|
||||||
|
{mjITEM_EDITFLOAT, "bvactive", 2, &(vis->rgba.bvactive), "4"},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
|
|
||||||
// add rendering standard
|
// add visualization section
|
||||||
mjui_add(&sim->ui0, defVisualization);
|
mjui_add(&sim->ui0, defVisualization);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make group section of UI
|
// make group section of UI
|
||||||
void MakeGroupSection(mj::Simulate* sim, int oldstate) {
|
void MakeGroupSection(mj::Simulate* sim) {
|
||||||
mjuiDef defGroup[] = {
|
mjuiDef defGroup[] = {
|
||||||
{mjITEM_SECTION, "Group enable", oldstate, nullptr, "AG"},
|
{mjITEM_SECTION, "Group enable", mjPRESERVE, nullptr, "AG"},
|
||||||
{mjITEM_SEPARATOR, "Geom groups", 1},
|
{mjITEM_SEPARATOR, "Geom groups", 1},
|
||||||
{mjITEM_CHECKBYTE, "Geom 0", 2, sim->opt.geomgroup, " 0"},
|
{mjITEM_CHECKBYTE, "Geom 0", 2, sim->opt.geomgroup, " 0"},
|
||||||
{mjITEM_CHECKBYTE, "Geom 1", 2, sim->opt.geomgroup+1, " 1"},
|
{mjITEM_CHECKBYTE, "Geom 1", 2, sim->opt.geomgroup+1, " 1"},
|
||||||
@@ -997,9 +1005,9 @@ void MakeGroupSection(mj::Simulate* sim, int oldstate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make joint section of UI
|
// make joint section of UI
|
||||||
void MakeJointSection(mj::Simulate* sim, int oldstate) {
|
void MakeJointSection(mj::Simulate* sim) {
|
||||||
mjuiDef defJoint[] = {
|
mjuiDef defJoint[] = {
|
||||||
{mjITEM_SECTION, "Joint", oldstate, nullptr, "AJ"},
|
{mjITEM_SECTION, "Joint", mjPRESERVE, nullptr, "AJ"},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
mjuiDef defSlider[] = {
|
mjuiDef defSlider[] = {
|
||||||
@@ -1050,9 +1058,9 @@ void MakeJointSection(mj::Simulate* sim, int oldstate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make control section of UI
|
// make control section of UI
|
||||||
void MakeControlSection(mj::Simulate* sim, int oldstate) {
|
void MakeControlSection(mj::Simulate* sim) {
|
||||||
mjuiDef defControl[] = {
|
mjuiDef defControl[] = {
|
||||||
{mjITEM_SECTION, "Control", oldstate, nullptr, "AC"},
|
{mjITEM_SECTION, "Control", mjPRESERVE, nullptr, "AC"},
|
||||||
{mjITEM_BUTTON, "Clear all", 2},
|
{mjITEM_BUTTON, "Clear all", 2},
|
||||||
{mjITEM_END}
|
{mjITEM_END}
|
||||||
};
|
};
|
||||||
@@ -1107,35 +1115,17 @@ void MakeControlSection(mj::Simulate* sim, int oldstate) {
|
|||||||
|
|
||||||
// make model-dependent UI sections
|
// make model-dependent UI sections
|
||||||
void MakeUiSections(mj::Simulate* sim, const mjModel* m, const mjData* d) {
|
void MakeUiSections(mj::Simulate* sim, const mjModel* m, const mjData* d) {
|
||||||
// get section open-close state, UI 0
|
|
||||||
int oldstate0[NSECT0];
|
|
||||||
for (int i=0; i<NSECT0; i++) {
|
|
||||||
oldstate0[i] = 0;
|
|
||||||
if (sim->ui0.nsect>i) {
|
|
||||||
oldstate0[i] = sim->ui0.sect[i].state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get section open-close state, UI 1
|
|
||||||
int oldstate1[NSECT1];
|
|
||||||
for (int i=0; i<NSECT1; i++) {
|
|
||||||
oldstate1[i] = 0;
|
|
||||||
if (sim->ui1.nsect>i) {
|
|
||||||
oldstate1[i] = sim->ui1.sect[i].state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear model-dependent sections of UI
|
// clear model-dependent sections of UI
|
||||||
sim->ui0.nsect = SECT_PHYSICS;
|
sim->ui0.nsect = SECT_PHYSICS;
|
||||||
sim->ui1.nsect = 0;
|
sim->ui1.nsect = 0;
|
||||||
|
|
||||||
// make
|
// make
|
||||||
MakePhysicsSection(sim, oldstate0[SECT_PHYSICS]);
|
MakePhysicsSection(sim);
|
||||||
MakeRenderingSection(sim, m, oldstate0[SECT_RENDERING]);
|
MakeRenderingSection(sim, m);
|
||||||
MakeVisualizationSection(sim, m, oldstate0[SECT_VISUALIZATION]);
|
MakeVisualizationSection(sim, m);
|
||||||
MakeGroupSection(sim, oldstate0[SECT_GROUP]);
|
MakeGroupSection(sim);
|
||||||
MakeJointSection(sim, oldstate1[SECT_JOINT]);
|
MakeJointSection(sim);
|
||||||
MakeControlSection(sim, oldstate1[SECT_CONTROL]);
|
MakeControlSection(sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------- utility functions ---------------------------------------------
|
//---------------------------------- utility functions ---------------------------------------------
|
||||||
@@ -1165,7 +1155,9 @@ void CopyPose(mj::Simulate* sim, const mjModel* m, const mjData* d) {
|
|||||||
|
|
||||||
// millisecond timer, for MuJoCo built-in profiler
|
// millisecond timer, for MuJoCo built-in profiler
|
||||||
mjtNum Timer() {
|
mjtNum Timer() {
|
||||||
return Milliseconds(mj::Simulate::Clock::now().time_since_epoch()).count();
|
static auto start = mj::Simulate::Clock::now();
|
||||||
|
auto elapsed = Milliseconds(mj::Simulate::Clock::now() - start);
|
||||||
|
return elapsed.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear all times
|
// clear all times
|
||||||
@@ -1263,7 +1255,7 @@ int ComputeFontScale(const mj::PlatformUIAdapter& platform_ui) {
|
|||||||
fs = 150;
|
fs = 150;
|
||||||
}
|
}
|
||||||
fs = mju_round(fs * 0.02) * 50;
|
fs = mju_round(fs * 0.02) * 50;
|
||||||
fs = mjMIN(250, mjMAX(100, fs));
|
fs = mjMIN(300, mjMAX(100, fs));
|
||||||
|
|
||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
@@ -1320,9 +1312,22 @@ void UiLayout(mjuiState* state) {
|
|||||||
rect[3].height = rect[0].height;
|
rect[3].height = rect[0].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// modify UI
|
||||||
void UiModify(mjUI* ui, mjuiState* state, mjrContext* con) {
|
void UiModify(mjUI* ui, mjuiState* state, mjrContext* con) {
|
||||||
mjui_resize(ui, con);
|
mjui_resize(ui, con);
|
||||||
mjr_addAux(ui->auxid, ui->width, ui->maxheight, ui->spacing.samples, con);
|
|
||||||
|
// remake aux buffer only if missing or different
|
||||||
|
int id = ui->auxid;
|
||||||
|
if (con->auxFBO[id] == 0 ||
|
||||||
|
con->auxFBO_r[id] == 0 ||
|
||||||
|
con->auxColor[id] == 0 ||
|
||||||
|
con->auxColor_r[id] == 0 ||
|
||||||
|
con->auxWidth[id] != ui->width ||
|
||||||
|
con->auxHeight[id] != ui->maxheight ||
|
||||||
|
con->auxSamples[id] != ui->spacing.samples) {
|
||||||
|
mjr_addAux(id, ui->width, ui->maxheight, ui->spacing.samples, con);
|
||||||
|
}
|
||||||
|
|
||||||
UiLayout(state);
|
UiLayout(state);
|
||||||
mjui_update(-1, -1, ui, state, con);
|
mjui_update(-1, -1, ui, state, con);
|
||||||
}
|
}
|
||||||
@@ -1502,7 +1507,7 @@ void UiEvent(mjuiState* state) {
|
|||||||
// remake joint section if joint group changed
|
// remake joint section if joint group changed
|
||||||
if (it->name[0]=='J' && it->name[1]=='o') {
|
if (it->name[0]=='J' && it->name[1]=='o') {
|
||||||
sim->ui1.nsect = SECT_JOINT;
|
sim->ui1.nsect = SECT_JOINT;
|
||||||
MakeJointSection(sim, sim->ui1.sect[SECT_JOINT].state);
|
MakeJointSection(sim);
|
||||||
sim->ui1.nsect = NSECT1;
|
sim->ui1.nsect = NSECT1;
|
||||||
UiModify(&sim->ui1, state, &sim->platform_ui->mjr_context());
|
UiModify(&sim->ui1, state, &sim->platform_ui->mjr_context());
|
||||||
}
|
}
|
||||||
@@ -2455,7 +2460,7 @@ void Simulate::Render() {
|
|||||||
if (pending_.ui_remake_ctrl) {
|
if (pending_.ui_remake_ctrl) {
|
||||||
if (this->ui1_enable && this->ui1.sect[SECT_CONTROL].state) {
|
if (this->ui1_enable && this->ui1.sect[SECT_CONTROL].state) {
|
||||||
this->ui1.nsect = SECT_CONTROL;
|
this->ui1.nsect = SECT_CONTROL;
|
||||||
MakeControlSection(this, this->ui1.sect[SECT_CONTROL].state);
|
MakeControlSection(this);
|
||||||
this->ui1.nsect = NSECT1;
|
this->ui1.nsect = NSECT1;
|
||||||
UiModify(&this->ui1, &this->uistate, &this->platform_ui->mjr_context());
|
UiModify(&this->ui1, &this->uistate, &this->platform_ui->mjr_context());
|
||||||
}
|
}
|
||||||
@@ -2643,12 +2648,15 @@ void Simulate::RenderLoop() {
|
|||||||
this->platform_ui->SetEventCallback(UiEvent);
|
this->platform_ui->SetEventCallback(UiEvent);
|
||||||
this->platform_ui->SetLayoutCallback(UiLayout);
|
this->platform_ui->SetLayoutCallback(UiLayout);
|
||||||
|
|
||||||
// populate uis with standard sections
|
// populate uis with standard sections, open some sections initially
|
||||||
this->ui0.userdata = this;
|
this->ui0.userdata = this;
|
||||||
this->ui1.userdata = this;
|
this->ui1.userdata = this;
|
||||||
mjui_add(&this->ui0, defFile);
|
mjui_add(&this->ui0, defFile);
|
||||||
mjui_add(&this->ui0, this->def_option);
|
mjui_add(&this->ui0, this->def_option);
|
||||||
mjui_add(&this->ui0, this->def_simulation);
|
mjui_add(&this->ui0, this->def_simulation);
|
||||||
|
this->ui0.sect[0].state = 1;
|
||||||
|
this->ui0.sect[1].state = 1;
|
||||||
|
this->ui0.sect[2].state = 1;
|
||||||
mjui_add(&this->ui0, this->def_watch);
|
mjui_add(&this->ui0, this->def_watch);
|
||||||
UiModify(&this->ui0, &this->uistate, &this->platform_ui->mjr_context());
|
UiModify(&this->ui0, &this->uistate, &this->platform_ui->mjr_context());
|
||||||
UiModify(&this->ui1, &this->uistate, &this->platform_ui->mjr_context());
|
UiModify(&this->ui1, &this->uistate, &this->platform_ui->mjr_context());
|
||||||
|
|||||||
+3
-3
@@ -265,7 +265,7 @@ class Simulate {
|
|||||||
// Constant arrays needed for the option section of UI and the UI interface
|
// Constant arrays needed for the option section of UI and the UI interface
|
||||||
// TODO setting the size here is not ideal
|
// TODO setting the size here is not ideal
|
||||||
const mjuiDef def_option[13] = {
|
const mjuiDef def_option[13] = {
|
||||||
{mjITEM_SECTION, "Option", 1, nullptr, "AO"},
|
{mjITEM_SECTION, "Option", mjPRESERVE, nullptr, "AO"},
|
||||||
{mjITEM_CHECKINT, "Help", 2, &this->help, " #290"},
|
{mjITEM_CHECKINT, "Help", 2, &this->help, " #290"},
|
||||||
{mjITEM_CHECKINT, "Info", 2, &this->info, " #291"},
|
{mjITEM_CHECKINT, "Info", 2, &this->info, " #291"},
|
||||||
{mjITEM_CHECKINT, "Profiler", 2, &this->profiler, " #292"},
|
{mjITEM_CHECKINT, "Profiler", 2, &this->profiler, " #292"},
|
||||||
@@ -287,7 +287,7 @@ class Simulate {
|
|||||||
|
|
||||||
// simulation section of UI
|
// simulation section of UI
|
||||||
const mjuiDef def_simulation[14] = {
|
const mjuiDef def_simulation[14] = {
|
||||||
{mjITEM_SECTION, "Simulation", 1, nullptr, "AS"},
|
{mjITEM_SECTION, "Simulation", mjPRESERVE, nullptr, "AS"},
|
||||||
{mjITEM_RADIO, "", 5, &this->run, "Pause\nRun"},
|
{mjITEM_RADIO, "", 5, &this->run, "Pause\nRun"},
|
||||||
{mjITEM_BUTTON, "Reset", 2, nullptr, " #259"},
|
{mjITEM_BUTTON, "Reset", 2, nullptr, " #259"},
|
||||||
{mjITEM_BUTTON, "Reload", 5, nullptr, "CL"},
|
{mjITEM_BUTTON, "Reload", 5, nullptr, "CL"},
|
||||||
@@ -306,7 +306,7 @@ class Simulate {
|
|||||||
|
|
||||||
// watch section of UI
|
// watch section of UI
|
||||||
const mjuiDef def_watch[5] = {
|
const mjuiDef def_watch[5] = {
|
||||||
{mjITEM_SECTION, "Watch", 0, nullptr, "AW"},
|
{mjITEM_SECTION, "Watch", mjPRESERVE, nullptr, "AW"},
|
||||||
{mjITEM_EDITTXT, "Field", 2, this->field, "qpos"},
|
{mjITEM_EDITTXT, "Field", 2, this->field, "qpos"},
|
||||||
{mjITEM_EDITINT, "Index", 2, &this->index, "1"},
|
{mjITEM_EDITINT, "Index", 2, &this->index, "1"},
|
||||||
{mjITEM_STATIC, "Value", 2, nullptr, " "},
|
{mjITEM_STATIC, "Value", 2, nullptr, " "},
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ set(MUJOCO_ENGINE_SRCS
|
|||||||
engine_collision_convex.h
|
engine_collision_convex.h
|
||||||
engine_collision_driver.c
|
engine_collision_driver.c
|
||||||
engine_collision_driver.h
|
engine_collision_driver.h
|
||||||
|
engine_collision_gjk.c
|
||||||
|
engine_collision_gjk.h
|
||||||
engine_collision_primitive.c
|
engine_collision_primitive.c
|
||||||
engine_collision_primitive.h
|
engine_collision_primitive.h
|
||||||
engine_collision_sdf.c
|
engine_collision_sdf.c
|
||||||
@@ -45,6 +47,8 @@ set(MUJOCO_ENGINE_SRCS
|
|||||||
engine_io.c
|
engine_io.c
|
||||||
engine_io.h
|
engine_io.h
|
||||||
engine_macro.h
|
engine_macro.h
|
||||||
|
engine_name.c
|
||||||
|
engine_name.h
|
||||||
engine_passive.c
|
engine_passive.c
|
||||||
engine_passive.h
|
engine_passive.h
|
||||||
engine_plugin.cc
|
engine_plugin.cc
|
||||||
|
|||||||
@@ -806,8 +806,8 @@ int mjc_BoxBox(const mjModel* M, const mjData* D, mjContact* con, int g1, int g2
|
|||||||
if (q2) {
|
if (q2) {
|
||||||
mju_mulMatMatT3(r, rotmore, rot);
|
mju_mulMatMatT3(r, rotmore, rot);
|
||||||
|
|
||||||
// mju_rotVecMat(p,pos12,rotmore);
|
// mju_mulMatVec3(p,rotmore,pos12);
|
||||||
// mju_rotVecMat(tmp1,size2,rotmore);
|
// mju_mulMatVec3(tmp1,rotmore,size2);
|
||||||
|
|
||||||
rotaxis(p, pos12);
|
rotaxis(p, pos12);
|
||||||
rotaxis(tmp1, size2);
|
rotaxis(tmp1, size2);
|
||||||
@@ -818,8 +818,8 @@ int mjc_BoxBox(const mjModel* M, const mjData* D, mjContact* con, int g1, int g2
|
|||||||
|
|
||||||
rotmatx(r, rot);
|
rotmatx(r, rot);
|
||||||
|
|
||||||
// mju_rotVecMat(p,pos21,rotmore);
|
// mju_mulMatVec3(p,rotmore,pos21);
|
||||||
// mju_rotVecMat(tmp1,size1,rotmore);
|
// mju_mulMatVec3(tmp1,rotmore,size1);
|
||||||
|
|
||||||
rotaxis(p, pos21);
|
rotaxis(p, pos21);
|
||||||
rotaxis(tmp1, size1);
|
rotaxis(tmp1, size1);
|
||||||
@@ -1074,8 +1074,8 @@ edgeedge:
|
|||||||
f2 = -1;
|
f2 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mju_rotVecMat(p,pos21,rotmore);
|
// mju_mulMatVec3(p,rotmore,pos21);
|
||||||
// mju_rotVecMat(rnorm,clnorm,rotmore);
|
// mju_mulMatVec3(rnorm,rotmore,clnorm);
|
||||||
rotaxis(p, pos21);
|
rotaxis(p, pos21);
|
||||||
rotaxis(rnorm, clnorm);
|
rotaxis(rnorm, clnorm);
|
||||||
|
|
||||||
|
|||||||
@@ -34,25 +34,31 @@
|
|||||||
|
|
||||||
// ccd center function
|
// ccd center function
|
||||||
void mjccd_center(const void *obj, ccd_vec3_t *center) {
|
void mjccd_center(const void *obj, ccd_vec3_t *center) {
|
||||||
const mjtCCD* ccd = (const mjtCCD*)obj;
|
mjc_center(center->v, (const mjCCDObj*) obj);
|
||||||
int g = ccd->geom;
|
}
|
||||||
int f = ccd->flex;
|
|
||||||
int e = ccd->elem;
|
|
||||||
int v = ccd->vert;
|
|
||||||
|
// center function for convex collision algorithms
|
||||||
|
void mjc_center(mjtNum res[3], const mjCCDObj *obj) {
|
||||||
|
int g = obj->geom;
|
||||||
|
int f = obj->flex;
|
||||||
|
int e = obj->elem;
|
||||||
|
int v = obj->vert;
|
||||||
|
|
||||||
// return geom position
|
// return geom position
|
||||||
if (g >= 0) {
|
if (g >= 0) {
|
||||||
mju_copy3(center->v, ccd->data->geom_xpos + 3*g);
|
mju_copy3(res, obj->data->geom_xpos + 3*g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return flex element position
|
// return flex element position
|
||||||
else if (e >= 0) {
|
else if (e >= 0) {
|
||||||
mju_copy3(center->v, ccd->data->flexelem_aabb + 6*(ccd->model->flex_elemadr[f]+e));
|
mju_copy3(res, obj->data->flexelem_aabb + 6*(obj->model->flex_elemadr[f]+e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// return flex vertex position
|
// return flex vertex position
|
||||||
else {
|
else {
|
||||||
mju_copy3(center->v, ccd->data->flexvert_xpos + 3*(ccd->model->flex_vertadr[f]+v));
|
mju_copy3(res, obj->data->flexvert_xpos + 3*(obj->model->flex_vertadr[f]+v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,21 +66,25 @@ void mjccd_center(const void *obj, ccd_vec3_t *center) {
|
|||||||
|
|
||||||
// ccd support function
|
// ccd support function
|
||||||
void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
||||||
const mjtCCD* ccd = (const mjtCCD*)obj;
|
mjc_support(vec->v, (mjCCDObj*) obj, _dir->v);
|
||||||
const mjModel* m = ccd->model;
|
}
|
||||||
const mjData* d = ccd->data;
|
|
||||||
int g = ccd->geom;
|
|
||||||
|
|
||||||
|
// support function for convex collision algorithms
|
||||||
|
void mjc_support(mjtNum res[3], mjCCDObj* obj, const mjtNum dir[3]) {
|
||||||
|
const mjModel* m = obj->model;
|
||||||
|
const mjData* d = obj->data;
|
||||||
|
int g = obj->geom;
|
||||||
|
|
||||||
//-------------------------- flex element or vertex -----------------------------
|
//-------------------------- flex element or vertex -----------------------------
|
||||||
if (g < 0) {
|
if (g < 0) {
|
||||||
int f = ccd->flex;
|
int f = obj->flex;
|
||||||
int dim = m->flex_dim[f];
|
int dim = m->flex_dim[f];
|
||||||
mjtNum *res = vec->v;
|
|
||||||
const mjtNum *dir = _dir->v;
|
|
||||||
|
|
||||||
// flex element
|
// flex element
|
||||||
if (ccd->elem >= 0) {
|
if (obj->elem >= 0) {
|
||||||
int e = ccd->elem;
|
int e = obj->elem;
|
||||||
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
const int* edata = m->flex_elem + m->flex_elemdataadr[f] + e*(dim+1);
|
||||||
const mjtNum* vert = d->flexvert_xpos + 3*m->flex_vertadr[f];
|
const mjtNum* vert = d->flexvert_xpos + 3*m->flex_vertadr[f];
|
||||||
|
|
||||||
@@ -92,14 +102,14 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add radius and margin/2
|
// add radius and margin/2
|
||||||
mju_addToScl3(res, dir, m->flex_radius[f] + 0.5*ccd->margin);
|
mju_addToScl3(res, dir, m->flex_radius[f] + 0.5*obj->margin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// flex vertex
|
// flex vertex
|
||||||
else {
|
else {
|
||||||
const mjtNum* vert = d->flexvert_xpos + 3*(m->flex_vertadr[f] + ccd->vert);
|
const mjtNum* vert = d->flexvert_xpos + 3*(m->flex_vertadr[f] + obj->vert);
|
||||||
mju_addScl3(res, vert, dir, m->flex_radius[f] + 0.5*ccd->margin);
|
mju_addScl3(res, vert, dir, m->flex_radius[f] + 0.5*obj->margin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,30 +121,29 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
mjtNum tmp, vdot;
|
mjtNum tmp, vdot;
|
||||||
|
|
||||||
const mjtNum* size = m->geom_size+3*g; // geom sizes
|
const mjtNum* size = m->geom_size+3*g; // geom sizes
|
||||||
mjtNum dir[3]; // direction in geom local frame
|
mjtNum local_dir[3]; // direction in geom local frame
|
||||||
mjtNum res[3]; // result in geom local frame
|
|
||||||
|
|
||||||
// rotate dir to geom local frame
|
// rotate dir to geom local frame
|
||||||
mju_mulMatTVec3(dir, d->geom_xmat+9*g, _dir->v);
|
mju_mulMatTVec3(local_dir, d->geom_xmat+9*g, dir);
|
||||||
|
|
||||||
// compute result according to geom type
|
// compute result according to geom type
|
||||||
switch ((mjtGeom) m->geom_type[g]) {
|
switch ((mjtGeom) m->geom_type[g]) {
|
||||||
case mjGEOM_SPHERE:
|
case mjGEOM_SPHERE:
|
||||||
mju_scl3(res, dir, size[0]);
|
mju_scl3(res, local_dir, size[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjGEOM_CAPSULE:
|
case mjGEOM_CAPSULE:
|
||||||
// start with sphere
|
// start with sphere
|
||||||
mju_scl3(res, dir, size[0]);
|
mju_scl3(res, local_dir, size[0]);
|
||||||
|
|
||||||
// add cylinder contribution
|
// add cylinder contribution
|
||||||
res[2] += mju_sign(dir[2]) * size[1];
|
res[2] += mju_sign(local_dir[2]) * size[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjGEOM_ELLIPSOID:
|
case mjGEOM_ELLIPSOID:
|
||||||
// find support point on unit sphere: scale dir by ellipsoid sizes and renormalize
|
// find support point on unit sphere: scale dir by ellipsoid sizes and renormalize
|
||||||
for (int i=0; i < 3; i++) {
|
for (int i=0; i < 3; i++) {
|
||||||
res[i] = dir[i] * size[i];
|
res[i] = local_dir[i] * size[i];
|
||||||
}
|
}
|
||||||
mju_normalize3(res);
|
mju_normalize3(res);
|
||||||
|
|
||||||
@@ -146,21 +155,21 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
|
|
||||||
case mjGEOM_CYLINDER:
|
case mjGEOM_CYLINDER:
|
||||||
// set result in XY plane: support on circle
|
// set result in XY plane: support on circle
|
||||||
tmp = mju_sqrt(dir[0]*dir[0] + dir[1]*dir[1]);
|
tmp = mju_sqrt(local_dir[0]*local_dir[0] + local_dir[1]*local_dir[1]);
|
||||||
if (tmp > mjMINVAL) {
|
if (tmp > mjMINVAL) {
|
||||||
res[0] = dir[0]/tmp*size[0];
|
res[0] = local_dir[0]/tmp*size[0];
|
||||||
res[1] = dir[1]/tmp*size[0];
|
res[1] = local_dir[1]/tmp*size[0];
|
||||||
} else {
|
} else {
|
||||||
res[0] = res[1] = 0;
|
res[0] = res[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set result in Z direction
|
// set result in Z direction
|
||||||
res[2] = mju_sign(dir[2]) * size[1];
|
res[2] = mju_sign(local_dir[2]) * size[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjGEOM_BOX:
|
case mjGEOM_BOX:
|
||||||
for (int i=0; i < 3; i++) {
|
for (int i=0; i < 3; i++) {
|
||||||
res[i] = mju_sign(dir[i]) * size[i];
|
res[i] = mju_sign(local_dir[i]) * size[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -176,9 +185,9 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
// search all vertices, find best
|
// search all vertices, find best
|
||||||
for (int i=0; i < m->mesh_vertnum[m->geom_dataid[g]]; i++) {
|
for (int i=0; i < m->mesh_vertnum[m->geom_dataid[g]]; i++) {
|
||||||
// vdot = dot(vertex, dir)
|
// vdot = dot(vertex, dir)
|
||||||
vdot = dir[0] * (mjtNum)vertdata[3*i] +
|
vdot = local_dir[0] * (mjtNum)vertdata[3*i] +
|
||||||
dir[1] * (mjtNum)vertdata[3*i+1] +
|
local_dir[1] * (mjtNum)vertdata[3*i+1] +
|
||||||
dir[2] * (mjtNum)vertdata[3*i+2];
|
local_dir[2] * (mjtNum)vertdata[3*i+2];
|
||||||
|
|
||||||
// update best
|
// update best
|
||||||
if (vdot > tmp) {
|
if (vdot > tmp) {
|
||||||
@@ -188,7 +197,7 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record best vertex index, in globalid format
|
// record best vertex index, in globalid format
|
||||||
((mjtCCD*)ccd)->meshindex = ibest;
|
obj->meshindex = ibest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hill-climb using graph data
|
// hill-climb using graph data
|
||||||
@@ -202,9 +211,9 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
|
|
||||||
// init with first vertex in convex hull
|
// init with first vertex in convex hull
|
||||||
ibest = 0;
|
ibest = 0;
|
||||||
tmp = dir[0] * (mjtNum)vertdata[3*vert_globalid[0]] +
|
tmp = local_dir[0] * (mjtNum)vertdata[3*vert_globalid[0]] +
|
||||||
dir[1] * (mjtNum)vertdata[3*vert_globalid[0]+1] +
|
local_dir[1] * (mjtNum)vertdata[3*vert_globalid[0]+1] +
|
||||||
dir[2] * (mjtNum)vertdata[3*vert_globalid[0]+2];
|
local_dir[2] * (mjtNum)vertdata[3*vert_globalid[0]+2];
|
||||||
|
|
||||||
// hill-climb until no change
|
// hill-climb until no change
|
||||||
change = 1;
|
change = 1;
|
||||||
@@ -213,10 +222,10 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
change = 0;
|
change = 0;
|
||||||
int i = vert_edgeadr[ibest];
|
int i = vert_edgeadr[ibest];
|
||||||
while ((locid=edge_localid[i]) >= 0) {
|
while ((locid=edge_localid[i]) >= 0) {
|
||||||
// vdot = dot(vertex, dir)
|
// vdot = dot(vertex, local_dir)
|
||||||
vdot = dir[0] * (mjtNum)vertdata[3*vert_globalid[locid]] +
|
vdot = local_dir[0] * (mjtNum)vertdata[3*vert_globalid[locid]] +
|
||||||
dir[1] * (mjtNum)vertdata[3*vert_globalid[locid]+1] +
|
local_dir[1] * (mjtNum)vertdata[3*vert_globalid[locid]+1] +
|
||||||
dir[2] * (mjtNum)vertdata[3*vert_globalid[locid]+2];
|
local_dir[2] * (mjtNum)vertdata[3*vert_globalid[locid]+2];
|
||||||
|
|
||||||
// update best
|
// update best
|
||||||
if (vdot > tmp) {
|
if (vdot > tmp) {
|
||||||
@@ -231,7 +240,7 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record best vertex index, in locid format
|
// record best vertex index, in locid format
|
||||||
((mjtCCD*)ccd)->meshindex = ibest;
|
obj->meshindex = ibest;
|
||||||
|
|
||||||
// map best index to globalid
|
// map best index to globalid
|
||||||
ibest = vert_globalid[ibest];
|
ibest = vert_globalid[ibest];
|
||||||
@@ -255,16 +264,16 @@ void mjccd_support(const void *obj, const ccd_vec3_t *_dir, ccd_vec3_t *vec) {
|
|||||||
mjERROR("ccd support function is undefined for geom type %d", m->geom_type[g]);
|
mjERROR("ccd support function is undefined for geom type %d", m->geom_type[g]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add dir*margin/2 to result
|
// add local_dir*margin/2 to result
|
||||||
for (int i=0; i < 3; i++) {
|
for (int i=0; i < 3; i++) {
|
||||||
res[i] += dir[i] * ccd->margin/2;
|
res[i] += local_dir[i] * obj->margin/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotate result to global frame
|
// rotate result to global frame
|
||||||
mju_mulMatVec3(vec->v, d->geom_xmat+9*g, res);
|
mju_mulMatVec3(res, d->geom_xmat+9*g, res);
|
||||||
|
|
||||||
// add geom position
|
// add geom position
|
||||||
mju_addTo3(vec->v, d->geom_xpos+3*g);
|
mju_addTo3(res, d->geom_xpos+3*g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -280,7 +289,7 @@ static void mjc_initCCD(ccd_t* ccd, const mjModel* m) {
|
|||||||
|
|
||||||
|
|
||||||
// find single convex-convex collision, using libccd
|
// find single convex-convex collision, using libccd
|
||||||
static int mjc_MPRIteration(mjtCCD* obj1, mjtCCD* obj2, const ccd_t* ccd,
|
static int mjc_MPRIteration(mjCCDObj* obj1, mjCCDObj* obj2, const ccd_t* ccd,
|
||||||
const mjModel* m, const mjData* d,
|
const mjModel* m, const mjData* d,
|
||||||
mjContact* con, mjtNum margin) {
|
mjContact* con, mjtNum margin) {
|
||||||
ccd_vec3_t dir, pos;
|
ccd_vec3_t dir, pos;
|
||||||
@@ -351,8 +360,8 @@ static void mju_rotateFrame(const mjtNum origin[3], const mjtNum rot[9],
|
|||||||
int mjc_Convex(const mjModel* m, const mjData* d,
|
int mjc_Convex(const mjModel* m, const mjData* d,
|
||||||
mjContact* con, int g1, int g2, mjtNum margin) {
|
mjContact* con, int g1, int g2, mjtNum margin) {
|
||||||
ccd_t ccd;
|
ccd_t ccd;
|
||||||
mjtCCD obj1 = {m, d, g1, -1, -1, -1, -1, margin, {1, 0, 0, 0}};
|
mjCCDObj obj1 = {m, d, g1, -1, -1, -1, -1, margin, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
mjtCCD obj2 = {m, d, g2, -1, -1, -1, -1, margin, {1, 0, 0, 0}};
|
mjCCDObj obj2 = {m, d, g2, -1, -1, -1, -1, margin, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
|
|
||||||
// init ccd structure
|
// init ccd structure
|
||||||
mjc_initCCD(&ccd, m);
|
mjc_initCCD(&ccd, m);
|
||||||
@@ -480,7 +489,7 @@ int mjc_PlaneConvex(const mjModel* m, const mjData* d,
|
|||||||
mjGETINFO
|
mjGETINFO
|
||||||
mjtNum dist, dif[3], normal[3] = {mat1[2], mat1[5], mat1[8]};
|
mjtNum dist, dif[3], normal[3] = {mat1[2], mat1[5], mat1[8]};
|
||||||
ccd_vec3_t dir, vec;
|
ccd_vec3_t dir, vec;
|
||||||
mjtCCD obj = {m, d, g2, -1, -1, -1, -1, 0, {1, 0, 0, 0}};
|
mjCCDObj obj = {m, d, g2, -1, -1, -1, -1, 0, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
|
|
||||||
// get support point in -normal direction
|
// get support point in -normal direction
|
||||||
ccdVec3Set(&dir, -mat1[2], -mat1[5], -mat1[8]);
|
ccdVec3Set(&dir, -mat1[2], -mat1[5], -mat1[8]);
|
||||||
@@ -661,7 +670,7 @@ int mjc_ConvexHField(const mjModel* m, const mjData* d,
|
|||||||
// ccd-related
|
// ccd-related
|
||||||
ccd_vec3_t dirccd, vecccd;
|
ccd_vec3_t dirccd, vecccd;
|
||||||
ccd_real_t depth;
|
ccd_real_t depth;
|
||||||
mjtCCD obj = {m, d, g2, -1, -1, -1, -1, 0, {1, 0, 0, 0}};
|
mjCCDObj obj = {m, d, g2, -1, -1, -1, -1, 0, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
ccd_t ccd;
|
ccd_t ccd;
|
||||||
|
|
||||||
// point size1 to hfield size instead of geom1 size
|
// point size1 to hfield size instead of geom1 size
|
||||||
@@ -1094,8 +1103,8 @@ void mjc_fixNormal(const mjModel* m, const mjData* d, mjContact* con, int g1, in
|
|||||||
int mjc_ConvexElem(const mjModel* m, const mjData* d, mjContact* con,
|
int mjc_ConvexElem(const mjModel* m, const mjData* d, mjContact* con,
|
||||||
int g1, int f1, int e1, int v1, int f2, int e2, mjtNum margin) {
|
int g1, int f1, int e1, int v1, int f2, int e2, mjtNum margin) {
|
||||||
ccd_t ccd;
|
ccd_t ccd;
|
||||||
mjtCCD obj1 = {m, d, g1, -1, f1, e1, v1, margin, {1, 0, 0, 0}};
|
mjCCDObj obj1 = {m, d, g1, -1, f1, e1, v1, margin, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
mjtCCD obj2 = {m, d, -1, -1, f2, e2, -1, margin, {1, 0, 0, 0}};
|
mjCCDObj obj2 = {m, d, -1, -1, f2, e2, -1, margin, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
|
|
||||||
// init ccd structure
|
// init ccd structure
|
||||||
mjc_initCCD(&ccd, m);
|
mjc_initCCD(&ccd, m);
|
||||||
@@ -1142,7 +1151,7 @@ int mjc_HFieldElem(const mjModel* m, const mjData* d, mjContact* con,
|
|||||||
// ccd-related
|
// ccd-related
|
||||||
ccd_vec3_t dirccd, vecccd;
|
ccd_vec3_t dirccd, vecccd;
|
||||||
ccd_real_t depth;
|
ccd_real_t depth;
|
||||||
mjtCCD obj = {m, d, -1, -1, f, e, -1, margin, {1, 0, 0, 0}};
|
mjCCDObj obj = {m, d, -1, -1, f, e, -1, margin, {1, 0, 0, 0}, {0, 0, 0}};
|
||||||
ccd_t ccd;
|
ccd_t ccd;
|
||||||
|
|
||||||
//------------------------------------- AABB computation, box-box test
|
//------------------------------------- AABB computation, box-box test
|
||||||
|
|||||||
@@ -23,8 +23,10 @@
|
|||||||
|
|
||||||
#include <ccd/vec3.h>
|
#include <ccd/vec3.h>
|
||||||
|
|
||||||
|
#include <mujoco/mjexport.h>
|
||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
|
#include <mujoco/mjtnum.h>
|
||||||
|
|
||||||
#define mjGETINFO_HFIELD \
|
#define mjGETINFO_HFIELD \
|
||||||
const mjtNum* pos1 = d->geom_xpos + 3*g1; \
|
const mjtNum* pos1 = d->geom_xpos + 3*g1; \
|
||||||
@@ -38,8 +40,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ccd general object type
|
// internal object type for convex collision detection
|
||||||
struct _mjtCCD {
|
struct _mjCCDObj {
|
||||||
const mjModel* model;
|
const mjModel* model;
|
||||||
const mjData* data;
|
const mjData* data;
|
||||||
int geom;
|
int geom;
|
||||||
@@ -49,14 +51,19 @@ struct _mjtCCD {
|
|||||||
int vert;
|
int vert;
|
||||||
mjtNum margin;
|
mjtNum margin;
|
||||||
mjtNum rotate[4];
|
mjtNum rotate[4];
|
||||||
|
mjtNum x0[3]; // initial guess of the witness point
|
||||||
};
|
};
|
||||||
typedef struct _mjtCCD mjtCCD;
|
typedef struct _mjCCDObj mjCCDObj;
|
||||||
|
|
||||||
|
// support function for convex collision algorithms
|
||||||
|
MJAPI void mjc_support(mjtNum res[3], mjCCDObj* obj, const mjtNum dir[3]);
|
||||||
|
|
||||||
|
// center function for convex collision algorithms
|
||||||
|
MJAPI void mjc_center(mjtNum res[3], const mjCCDObj *obj);
|
||||||
|
|
||||||
// ccd support function
|
// ccd support function
|
||||||
void mjccd_support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec);
|
void mjccd_support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec);
|
||||||
|
|
||||||
|
|
||||||
// pairwise geom collision functions using ccd
|
// pairwise geom collision functions using ccd
|
||||||
int mjc_PlaneConvex (const mjModel* m, const mjData* d,
|
int mjc_PlaneConvex (const mjModel* m, const mjData* d,
|
||||||
mjContact* con, int g1, int g2, mjtNum margin);
|
mjContact* con, int g1, int g2, mjtNum margin);
|
||||||
|
|||||||
@@ -0,0 +1,475 @@
|
|||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
#include "engine/engine_collision_gjk.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <mujoco/mjtnum.h>
|
||||||
|
#include <mujoco/mjmodel.h>
|
||||||
|
#include "engine/engine_util_blas.h"
|
||||||
|
#include "engine/engine_util_spatial.h"
|
||||||
|
#include "engine/engine_collision_convex.h"
|
||||||
|
|
||||||
|
// Computes the shortest distance between the origin and an n-simplex (n <= 3) and returns the
|
||||||
|
// barycentric coordinates of the closest point in the simplex. This is the so called distance
|
||||||
|
// sub-algorithm of the original 1988 GJK algorithm.
|
||||||
|
//
|
||||||
|
// We have adapted the Signed Volume method for our approach from the paper:
|
||||||
|
// Improving the GJK Algorithm for Faster and More Reliable Distance Queries Between Two
|
||||||
|
// Convex Objects, Montanari et al, ToG 2017.
|
||||||
|
static void signedVolume(mjtNum lambda[4], const mjtNum simplex[12], int n);
|
||||||
|
|
||||||
|
// these internal functions compute the barycentric coordinates of the closest point
|
||||||
|
// to the origin in the n-simplex, where n = 3, 2, 1 respectively
|
||||||
|
static void S3D(mjtNum lambda[4], const mjtNum simplex[12]);
|
||||||
|
static void S2D(mjtNum lambda[3], const mjtNum simplex[9]);
|
||||||
|
static void S1D(mjtNum lambda[2], const mjtNum simplex[6]);
|
||||||
|
|
||||||
|
// helper function to compute the support point in the Minkowski difference
|
||||||
|
static void support(mjtNum s1[3], mjtNum s2[3], mjCCDObj* obj1, mjCCDObj* obj2,
|
||||||
|
const mjtNum x_k[3]);
|
||||||
|
|
||||||
|
// linear algebra utility functions
|
||||||
|
static mjtNum det3(const mjtNum v1[3], const mjtNum v2[3], const mjtNum v3[3]);
|
||||||
|
static void lincomb(mjtNum res[3], const mjtNum* coef, const mjtNum* v, int n);
|
||||||
|
|
||||||
|
// returns the distance between the two objects. The witness points are
|
||||||
|
// recoverable from x_0 in obj1 and obj2.
|
||||||
|
mjtNum mj_gjk(const mjCCDConfig* config, mjCCDObj* obj1, mjCCDObj* obj2) {
|
||||||
|
mjtNum simplex[12]; // our current simplex with max 4 vertices due to only 3 dimensions
|
||||||
|
int n = 0; // number of vertices in the simplex
|
||||||
|
mjtNum x_k[3]; // the kth approximation point with initial value x_0
|
||||||
|
|
||||||
|
// segregated simplices and points for the two objects to recover witness points
|
||||||
|
mjtNum simplex1[12], simplex2[12];
|
||||||
|
mjtNum* x1_k = obj1->x0;
|
||||||
|
mjtNum* x2_k = obj2->x0;
|
||||||
|
mju_sub3(x_k, x1_k, x2_k);
|
||||||
|
|
||||||
|
int N = config->max_iterations;
|
||||||
|
for (size_t k = 0; k < N; k++) {
|
||||||
|
mjtNum s1[3], s2[3]; // the support points in obj1 and obj2
|
||||||
|
mjtNum s_k[3]; // the kth support point of Minkowski difference
|
||||||
|
mjtNum lambda[4]; // barycentric coordinates for x_k
|
||||||
|
|
||||||
|
// compute the kth support point
|
||||||
|
support(s1, s2, obj1, obj2, x_k);
|
||||||
|
mju_sub3(s_k, s1, s2);
|
||||||
|
|
||||||
|
// the stopping criteria relies on the Frank-Wolfe duality gap given by
|
||||||
|
// f(x_k) - f(x_min) <= < grad f(x_k), (x_k - s_k) >
|
||||||
|
mjtNum diff[3];
|
||||||
|
mju_sub3(diff, x_k, s_k);
|
||||||
|
if (2*mju_dot3(x_k, diff) < config->tolerance) {
|
||||||
|
return mju_norm3(x_k);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(kylebayes): signedVolume has been written to assume the first vertex is the latest
|
||||||
|
// support to be added. Once the logic has been updated, then this hack should be removed.
|
||||||
|
for (int i = n; i > 0; i--) {
|
||||||
|
// shift the simplex vertices to the right
|
||||||
|
mju_copy3(simplex + 3*i, simplex + 3*(i-1));
|
||||||
|
mju_copy3(simplex1 + 3*i, simplex1 + 3*(i-1));
|
||||||
|
mju_copy3(simplex2 + 3*i, simplex2 + 3*(i-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy new support point into the simplex
|
||||||
|
mju_copy3(simplex, s_k);
|
||||||
|
|
||||||
|
// copy new support point into the individual simplexes
|
||||||
|
mju_copy3(simplex1, s1);
|
||||||
|
mju_copy3(simplex2, s2);
|
||||||
|
|
||||||
|
// run the distance subalgorithm to compute the barycentric coordinates
|
||||||
|
// of the closest point to the origin in the simplex
|
||||||
|
signedVolume(lambda, simplex, ++n);
|
||||||
|
lincomb(x_k, lambda, simplex, 4);
|
||||||
|
|
||||||
|
// compute the approximate witness points
|
||||||
|
lincomb(x1_k, lambda, simplex1, 4);
|
||||||
|
lincomb(x2_k, lambda, simplex2, 4);
|
||||||
|
|
||||||
|
// for lambda[i] == 0, remove the ith vertex from the simplex
|
||||||
|
n = 0;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (lambda[i] == 0) continue;
|
||||||
|
// recover simplex for the two objects
|
||||||
|
mju_copy3(simplex1 + 3*n, simplex1 + 3*i);
|
||||||
|
mju_copy3(simplex2 + 3*n, simplex2 + 3*i);
|
||||||
|
|
||||||
|
// simplex in Minkowski difference
|
||||||
|
mju_copy3(simplex + 3*n++, simplex + 3*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mju_norm3(x_k);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// computes the support points in obj1 and obj2 for the kth approximation point
|
||||||
|
static void support(mjtNum s1[3], mjtNum s2[3], mjCCDObj* obj1, mjCCDObj* obj2,
|
||||||
|
const mjtNum x_k[3]) {
|
||||||
|
mjtNum dir[3], dir_neg[3];
|
||||||
|
mju_copy3(dir_neg, x_k);
|
||||||
|
mju_normalize3(dir_neg); // mjc_support assumes a normalized direction
|
||||||
|
mju_scl3(dir, dir_neg, -1);
|
||||||
|
|
||||||
|
// compute S_{A-B}(dir) = S_A(dir) - S_B(-dir)
|
||||||
|
mjc_support(s1, obj1, dir);
|
||||||
|
mjc_support(s2, obj2, dir_neg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// linear combination of n 3D vectors:
|
||||||
|
// res = coef[0]*v[0] + ... + coef[n-1]*v[3*(n-1)]
|
||||||
|
static void lincomb(mjtNum res[3], const mjtNum* coef, const mjtNum* v, int n) {
|
||||||
|
mju_zero3(res);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (coef[i] == 0) continue;
|
||||||
|
res[0] += coef[i] * v[3*i + 0];
|
||||||
|
res[1] += coef[i] * v[3*i + 1];
|
||||||
|
res[2] += coef[i] * v[3*i + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// returns determinant of the 3x3 matrix with columns v1, v2, v3
|
||||||
|
static mjtNum det3(const mjtNum v1[3], const mjtNum v2[3], const mjtNum v3[3]) {
|
||||||
|
mjtNum temp[3];
|
||||||
|
mju_cross(temp, v2, v3);
|
||||||
|
return mju_dot3(v1, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// returns true only when a and b are both strictly positive or both strictly negative
|
||||||
|
static int compareSigns(mjtNum a, mjtNum b) {
|
||||||
|
if (a > 0 && b > 0) return 1;
|
||||||
|
if (a < 0 && b < 0) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// computes the barycentric coordinates of the closest point to the origin in the n-simplex
|
||||||
|
void signedVolume(mjtNum lambda[4], const mjtNum simplex[12], int n) {
|
||||||
|
int r = n - 1; // spatial dimension of the simplex
|
||||||
|
mju_zero4(lambda);
|
||||||
|
|
||||||
|
if (r == 3) {
|
||||||
|
S3D(lambda, simplex);
|
||||||
|
} else if (r == 2) {
|
||||||
|
S2D(lambda, simplex);
|
||||||
|
} else if (r == 1) {
|
||||||
|
S1D(lambda, simplex);
|
||||||
|
} else {
|
||||||
|
lambda[0] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void S3D(mjtNum lambda[4], const mjtNum simplex[12]) {
|
||||||
|
// the four vertices of the 3-simplex that correspond to 4 support points
|
||||||
|
const mjtNum* s1 = simplex;
|
||||||
|
const mjtNum* s2 = simplex + 3;
|
||||||
|
const mjtNum* s3 = simplex + 6;
|
||||||
|
const mjtNum* s4 = simplex + 9;
|
||||||
|
|
||||||
|
// the matrix M is given by
|
||||||
|
// [[ s1_x, s2_x, s3_x, s4_x ],
|
||||||
|
// [ s1_y, s2_y, s3_y, s4_y ],
|
||||||
|
// [ s1_z, s2_z, s3_z, s4_z ],
|
||||||
|
// [ 1, 1, 1, 1 ]]
|
||||||
|
// we want to solve M*lambda = P, where P = [p_x, p_y, p_z, 1] with [p_x, p_y, p_z] is the
|
||||||
|
// origin projected onto the simplex
|
||||||
|
|
||||||
|
// compute cofactors to find det(M)
|
||||||
|
mjtNum C41 = -det3(s2, s3, s4);
|
||||||
|
mjtNum C42 = det3(s1, s3, s4);
|
||||||
|
mjtNum C43 = -det3(s1, s2, s4);
|
||||||
|
mjtNum C44 = det3(s1, s2, s3);
|
||||||
|
|
||||||
|
// note that m_det = 6*SignVol(simplex) with C4i corresponding to the volume of the 3-simplex
|
||||||
|
// with vertices {s1, s2, s3, 0} - si
|
||||||
|
mjtNum m_det = C41 + C42 + C43 + C44;
|
||||||
|
|
||||||
|
int comp1 = compareSigns(m_det, C41),
|
||||||
|
comp2 = compareSigns(m_det, C42),
|
||||||
|
comp3 = compareSigns(m_det, C43),
|
||||||
|
comp4 = compareSigns(m_det, C44);
|
||||||
|
|
||||||
|
// if all signs are the same then the origin is inside the simplex
|
||||||
|
if (comp1 && comp2 && comp3 && comp4) {
|
||||||
|
lambda[0] = C41 / m_det;
|
||||||
|
lambda[1] = C42 / m_det;
|
||||||
|
lambda[2] = C43 / m_det;
|
||||||
|
lambda[3] = C44 / m_det;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the smallest distance, and use the corresponding barycentric coordinates
|
||||||
|
mjtNum dist = mjMAXVAL;
|
||||||
|
|
||||||
|
if (!comp2) {
|
||||||
|
mjtNum lambda_2d[3], verts[9], x[3];
|
||||||
|
mju_copy3(verts, s1);
|
||||||
|
mju_copy3(verts + 3, s3);
|
||||||
|
mju_copy3(verts + 6, s4);
|
||||||
|
S2D(lambda_2d, verts);
|
||||||
|
lincomb(x, lambda_2d, verts, 3);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
lambda[0] = lambda_2d[0];
|
||||||
|
lambda[1] = 0;
|
||||||
|
lambda[2] = lambda_2d[1];
|
||||||
|
lambda[3] = lambda_2d[2];
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp3) {
|
||||||
|
mjtNum lambda_2d[3], verts[9], x[3];
|
||||||
|
mju_copy3(verts, s1);
|
||||||
|
mju_copy3(verts + 3, s2);
|
||||||
|
mju_copy3(verts + 6, s4);
|
||||||
|
S2D(lambda_2d, verts);
|
||||||
|
lincomb(x, lambda_2d, verts, 3);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
if (d < dist) {
|
||||||
|
lambda[0] = lambda_2d[0];
|
||||||
|
lambda[1] = lambda_2d[1];
|
||||||
|
lambda[2] = 0;
|
||||||
|
lambda[3] = lambda_2d[2];
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp4) {
|
||||||
|
mjtNum lambda_2d[3], verts[9], x[3];
|
||||||
|
mju_copy3(verts, s1);
|
||||||
|
mju_copy3(verts + 3, s2);
|
||||||
|
mju_copy3(verts + 6, s3);
|
||||||
|
S2D(lambda_2d, verts);
|
||||||
|
lincomb(x, lambda_2d, verts, 3);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
if (d < dist) {
|
||||||
|
lambda[0] = lambda_2d[0];
|
||||||
|
lambda[1] = lambda_2d[1];
|
||||||
|
lambda[2] = lambda_2d[2];
|
||||||
|
lambda[3] = 0;
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp1) {
|
||||||
|
mjtNum lambda_2d[3], verts[9], x[3];
|
||||||
|
mju_copy3(verts, s2);
|
||||||
|
mju_copy3(verts + 3, s3);
|
||||||
|
mju_copy3(verts + 6, s4);
|
||||||
|
S2D(lambda_2d, verts);
|
||||||
|
lincomb(x, lambda_2d, verts, 3);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
if (d < dist) {
|
||||||
|
lambda[0] = 0;
|
||||||
|
lambda[1] = lambda_2d[0];
|
||||||
|
lambda[2] = lambda_2d[1];
|
||||||
|
lambda[3] = lambda_2d[2];
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void S2D(mjtNum lambda[3], const mjtNum simplex[9]) {
|
||||||
|
// the three vertices of the 2-simplex that correspond to 3 support points
|
||||||
|
const mjtNum* s1 = simplex;
|
||||||
|
const mjtNum* s2 = simplex + 3;
|
||||||
|
const mjtNum* s3 = simplex + 6;
|
||||||
|
|
||||||
|
// compute normal
|
||||||
|
mjtNum diff1[3], diff2[3], n[3];
|
||||||
|
mju_sub3(diff1, s2, s1);
|
||||||
|
mju_sub3(diff2, s3, s1);
|
||||||
|
mju_cross(n, diff1, diff2);
|
||||||
|
|
||||||
|
// project origin
|
||||||
|
mjtNum p_o[3];
|
||||||
|
mju_scl3(p_o, n, mju_dot3(n, s1) / mju_dot3(n, n));
|
||||||
|
|
||||||
|
mjtNum mu_max = 0;
|
||||||
|
|
||||||
|
// Below are the minors M_i4 of the matrix M given by
|
||||||
|
// [[ s1_x, s2_x, s3_x, s4_x ],
|
||||||
|
// [ s1_y, s2_y, s3_y, s4_y ],
|
||||||
|
// [ s1_z, s2_z, s3_z, s4_z ],
|
||||||
|
// [ 1, 1, 1, 1 ]]
|
||||||
|
mjtNum M_14 = s2[1]*s3[2] - s2[2]*s3[1] - s1[1]*s3[2] + s1[2]*s3[1] + s1[1]*s2[2] - s1[2]*s2[1];
|
||||||
|
mjtNum M_24 = s2[0]*s3[2] - s2[2]*s3[0] - s1[0]*s3[2] + s1[2]*s3[0] + s1[0]*s2[2] - s1[2]*s2[0];
|
||||||
|
mjtNum M_34 = s2[0]*s3[1] - s2[1]*s3[0] - s1[0]*s3[1] + s1[1]*s3[0] + s1[0]*s2[1] - s1[1]*s2[0];
|
||||||
|
|
||||||
|
// exclude one of the axes with the largest projection of the simplex using the computed minors
|
||||||
|
mjtNum s1_2D[2], s2_2D[2], s3_2D[2], p_o_2D[2];
|
||||||
|
mjtNum mu1 = mju_abs(M_14), mu2 = mju_abs(M_24), mu3 = mju_abs(M_34);
|
||||||
|
if (mu1 >= mu2 && mu1 >= mu3) {
|
||||||
|
mu_max = mu1;
|
||||||
|
s1_2D[0] = s1[1];
|
||||||
|
s1_2D[1] = s1[2];
|
||||||
|
|
||||||
|
s2_2D[0] = s2[1];
|
||||||
|
s2_2D[1] = s2[2];
|
||||||
|
|
||||||
|
s3_2D[0] = s3[1];
|
||||||
|
s3_2D[1] = s3[2];
|
||||||
|
|
||||||
|
p_o_2D[0] = p_o[1];
|
||||||
|
p_o_2D[1] = p_o[2];
|
||||||
|
} else if (mu2 >= mu3) {
|
||||||
|
mu_max = mu2;
|
||||||
|
s1_2D[0] = s1[0];
|
||||||
|
s1_2D[1] = s1[2];
|
||||||
|
|
||||||
|
s2_2D[0] = s2[0];
|
||||||
|
s2_2D[1] = s2[2];
|
||||||
|
|
||||||
|
s3_2D[0] = s3[0];
|
||||||
|
s3_2D[1] = s3[2];
|
||||||
|
|
||||||
|
p_o_2D[0] = p_o[0];
|
||||||
|
p_o_2D[1] = p_o[2];
|
||||||
|
} else {
|
||||||
|
mu_max = mu3;
|
||||||
|
s1_2D[0] = s1[0];
|
||||||
|
s1_2D[1] = s1[1];
|
||||||
|
|
||||||
|
s2_2D[0] = s2[0];
|
||||||
|
s2_2D[1] = s2[1];
|
||||||
|
|
||||||
|
s3_2D[0] = s3[0];
|
||||||
|
s3_2D[1] = s3[1];
|
||||||
|
|
||||||
|
p_o_2D[0] = p_o[0];
|
||||||
|
p_o_2D[1] = p_o[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// substitute p_o as a vertex in simplex
|
||||||
|
mjtNum C1 = p_o_2D[0]*s2_2D[1] + p_o_2D[1]*s3_2D[0] + s2_2D[0]*s3_2D[1]
|
||||||
|
- p_o_2D[0]*s3_2D[1] - p_o_2D[1]*s2_2D[0] - s3_2D[0]*s2_2D[1];
|
||||||
|
|
||||||
|
mjtNum C2 = p_o_2D[0]*s3_2D[1] + p_o_2D[1]*s1_2D[0] + s3_2D[0]*s1_2D[1]
|
||||||
|
- p_o_2D[0]*s1_2D[1] - p_o_2D[1]*s3_2D[0] - s1_2D[0]*s3_2D[1];
|
||||||
|
|
||||||
|
mjtNum C3 = p_o_2D[0]*s1_2D[1] + p_o_2D[1]*s2_2D[0] + s1_2D[0]*s2_2D[1]
|
||||||
|
- p_o_2D[0]*s2_2D[1] - p_o_2D[1]*s1_2D[0] - s2_2D[0]*s1_2D[1];
|
||||||
|
|
||||||
|
int comp1 = compareSigns(mu_max, C1),
|
||||||
|
comp2 = compareSigns(mu_max, C2),
|
||||||
|
comp3 = compareSigns(mu_max, C3);
|
||||||
|
|
||||||
|
// inside the simplex
|
||||||
|
if (comp1 && comp2 && comp3) {
|
||||||
|
lambda[0] = C1 / mu_max;
|
||||||
|
lambda[1] = C2 / mu_max;
|
||||||
|
lambda[2] = C3 / mu_max;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the smallest distance, and use the corresponding barycentric coordinates
|
||||||
|
mjtNum dist = mjMAXVAL;
|
||||||
|
|
||||||
|
if (!comp2) {
|
||||||
|
mjtNum lambda_1d[2], verts[6], x[3];
|
||||||
|
mju_copy3(verts, s1);
|
||||||
|
mju_copy3(verts + 3, s3);
|
||||||
|
S1D(lambda_1d, verts);
|
||||||
|
lincomb(x, lambda_1d, verts, 2);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
lambda[0] = lambda_1d[0];
|
||||||
|
lambda[1] = 0;
|
||||||
|
lambda[2] = lambda_1d[1];
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp3) {
|
||||||
|
mjtNum lambda_1d[2], verts[6], x[3];
|
||||||
|
mju_copy3(verts, s1);
|
||||||
|
mju_copy3(verts + 3, s2);
|
||||||
|
S1D(lambda_1d, verts);
|
||||||
|
lincomb(x, lambda_1d, verts, 2);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
if (d < dist) {
|
||||||
|
lambda[0] = lambda_1d[0];
|
||||||
|
lambda[1] = lambda_1d[1];
|
||||||
|
lambda[2] = 0;
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp1) {
|
||||||
|
mjtNum lambda_1d[2], verts[6], x[3];
|
||||||
|
mju_copy3(verts, s2);
|
||||||
|
mju_copy3(verts + 3, s3);
|
||||||
|
S1D(lambda_1d, verts);
|
||||||
|
lincomb(x, lambda_1d, verts, 2);
|
||||||
|
mjtNum d = mju_norm3(x);
|
||||||
|
if (d < dist) {
|
||||||
|
lambda[1] = lambda_1d[0];
|
||||||
|
lambda[2] = lambda_1d[1];
|
||||||
|
lambda[0] = 0;
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void S1D(mjtNum lambda[2], const mjtNum simplex[6]) {
|
||||||
|
// the two vertices of the 1-simplex correspond to 2 support points
|
||||||
|
const mjtNum* s1 = simplex;
|
||||||
|
const mjtNum* s2 = simplex + 3;
|
||||||
|
|
||||||
|
// find projection of origin onto the 1-simplex:
|
||||||
|
// p_o = s2 - <s2, s2 - s1> / <s2 - s1, s2 - s1> * (s2 - s1)
|
||||||
|
mjtNum p_o[3];
|
||||||
|
mjtNum diff[3];
|
||||||
|
mju_sub3(diff, s2, s1);
|
||||||
|
mjtNum temp1 = mju_dot3(s2, diff);
|
||||||
|
mjtNum temp2 = mju_dot3(diff, diff);
|
||||||
|
mju_addScl3(p_o, s2, diff, - temp1 / temp2);
|
||||||
|
|
||||||
|
// find the axis with the largest projection "shadow" of the simplex
|
||||||
|
mjtNum mu_max = 0;
|
||||||
|
int index;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
mjtNum mu = s1[i] - s2[i];
|
||||||
|
if (mju_abs(mu) >= mju_abs(mu_max)) {
|
||||||
|
mu_max = mu;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mjtNum C1 = p_o[index] - s2[index];
|
||||||
|
mjtNum C2 = s1[index] - p_o[index];
|
||||||
|
|
||||||
|
// inside the simplex
|
||||||
|
if (compareSigns(mu_max, C1) && compareSigns(mu_max, C2)) {
|
||||||
|
lambda[0] = C1 / mu_max;
|
||||||
|
lambda[1] = C2 / mu_max;
|
||||||
|
} else {
|
||||||
|
lambda[0] = 1;
|
||||||
|
lambda[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2024 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_SRC_ENGINE_ENGINE_COLLISION_GJK_H_
|
||||||
|
#define MUJOCO_SRC_ENGINE_ENGINE_COLLISION_GJK_H_
|
||||||
|
|
||||||
|
#include <mujoco/mjexport.h>
|
||||||
|
#include <mujoco/mjtnum.h>
|
||||||
|
#include "engine/engine_collision_convex.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// internal configuration for convex collision detection
|
||||||
|
struct _mjCCDConfig {
|
||||||
|
int max_iterations;
|
||||||
|
mjtNum tolerance;
|
||||||
|
};
|
||||||
|
typedef struct _mjCCDConfig mjCCDConfig;
|
||||||
|
|
||||||
|
// Returns the distance between the two objects. The witness points are
|
||||||
|
// recoverable from x_0 in obj1 and obj2.
|
||||||
|
MJAPI mjtNum mj_gjk(const mjCCDConfig* config, mjCCDObj* obj1, mjCCDObj* obj2);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MUJOCO_SRC_ENGINE_ENGINE_COLLISION_GJK_H_
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#endif // defined(__AVX__) && defined(mjUSEDOUBLE)
|
#endif // defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#endif // mjUSEPLATFORMSIMD
|
#endif // mjUSEPLATFORMSIMD
|
||||||
|
|
||||||
|
|
||||||
@@ -818,7 +818,10 @@ void mj_instantiateLimit(const mjModel* m, mjData* d) {
|
|||||||
// BALL joint
|
// BALL joint
|
||||||
else if (m->jnt_type[i] == mjJNT_BALL) {
|
else if (m->jnt_type[i] == mjJNT_BALL) {
|
||||||
// convert joint quaternion to axis-angle
|
// convert joint quaternion to axis-angle
|
||||||
mju_quat2Vel(angleAxis, d->qpos+m->jnt_qposadr[i], 1);
|
int adr = m->jnt_qposadr[i];
|
||||||
|
mjtNum quat[4] = {d->qpos[adr], d->qpos[adr+1], d->qpos[adr+2], d->qpos[adr+3]};
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_quat2Vel(angleAxis, quat, 1);
|
||||||
|
|
||||||
// get rotation angle, normalize
|
// get rotation angle, normalize
|
||||||
value = mju_normalize3(angleAxis);
|
value = mju_normalize3(angleAxis);
|
||||||
@@ -1767,7 +1770,10 @@ static int mj_nl(const mjModel* m, const mjData* d, int *nnz) {
|
|||||||
}
|
}
|
||||||
else if (m->jnt_type[i] == mjJNT_BALL) {
|
else if (m->jnt_type[i] == mjJNT_BALL) {
|
||||||
mjtNum angleAxis[3];
|
mjtNum angleAxis[3];
|
||||||
mju_quat2Vel(angleAxis, d->qpos+m->jnt_qposadr[i], 1);
|
int adr = m->jnt_qposadr[i];
|
||||||
|
mjtNum quat[4] = {d->qpos[adr], d->qpos[adr+1], d->qpos[adr+2], d->qpos[adr+3]};
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_quat2Vel(angleAxis, quat, 1);
|
||||||
value = mju_normalize3(angleAxis);
|
value = mju_normalize3(angleAxis);
|
||||||
dist = mju_max(m->jnt_range[2*i], m->jnt_range[2*i+1]) - value;
|
dist = mju_max(m->jnt_range[2*i], m->jnt_range[2*i+1]) - value;
|
||||||
if (dist < margin) {
|
if (dist < margin) {
|
||||||
|
|||||||
@@ -44,14 +44,6 @@ void mj_kinematics(const mjModel* m, mjData* d) {
|
|||||||
d->xmat[0] = d->xmat[4] = d->xmat[8] = 1;
|
d->xmat[0] = d->xmat[4] = d->xmat[8] = 1;
|
||||||
d->ximat[0] = d->ximat[4] = d->ximat[8] = 1;
|
d->ximat[0] = d->ximat[4] = d->ximat[8] = 1;
|
||||||
|
|
||||||
// normalize all quaternions in qpos
|
|
||||||
mj_normalizeQuat(m, d->qpos);
|
|
||||||
|
|
||||||
// normalize mocap quaternions
|
|
||||||
for (int i=0; i < m->nmocap; i++) {
|
|
||||||
mju_normalize4(d->mocap_quat+4*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute global cartesian positions and orientations of all bodies
|
// compute global cartesian positions and orientations of all bodies
|
||||||
for (int i=1; i < m->nbody; i++) {
|
for (int i=1; i < m->nbody; i++) {
|
||||||
mjtNum xpos[3], xquat[4];
|
mjtNum xpos[3], xquat[4];
|
||||||
@@ -66,6 +58,7 @@ void mj_kinematics(const mjModel* m, mjData* d) {
|
|||||||
// copy pos and quat from qpos
|
// copy pos and quat from qpos
|
||||||
mju_copy3(xpos, d->qpos+qadr);
|
mju_copy3(xpos, d->qpos+qadr);
|
||||||
mju_copy4(xquat, d->qpos+qadr+3);
|
mju_copy4(xquat, d->qpos+qadr+3);
|
||||||
|
mju_normalize4(xquat);
|
||||||
|
|
||||||
// assign xanchor and xaxis
|
// assign xanchor and xaxis
|
||||||
mju_copy3(d->xanchor+3*jntadr, xpos);
|
mju_copy3(d->xanchor+3*jntadr, xpos);
|
||||||
@@ -77,10 +70,12 @@ void mj_kinematics(const mjModel* m, mjData* d) {
|
|||||||
int pid = m->body_parentid[i];
|
int pid = m->body_parentid[i];
|
||||||
|
|
||||||
// get body pos and quat: from model or mocap
|
// get body pos and quat: from model or mocap
|
||||||
mjtNum *bodypos, *bodyquat;
|
mjtNum *bodypos, *bodyquat, quat[4];
|
||||||
if (m->body_mocapid[i] >= 0) {
|
if (m->body_mocapid[i] >= 0) {
|
||||||
bodypos = d->mocap_pos + 3*m->body_mocapid[i];
|
bodypos = d->mocap_pos + 3*m->body_mocapid[i];
|
||||||
bodyquat = d->mocap_quat + 4*m->body_mocapid[i];
|
mju_copy4(quat, d->mocap_quat + 4*m->body_mocapid[i]);
|
||||||
|
mju_normalize4(quat);
|
||||||
|
bodyquat = quat;
|
||||||
} else {
|
} else {
|
||||||
bodypos = m->body_pos+3*i;
|
bodypos = m->body_pos+3*i;
|
||||||
bodyquat = m->body_quat+4*i;
|
bodyquat = m->body_quat+4*i;
|
||||||
@@ -125,6 +120,7 @@ void mj_kinematics(const mjModel* m, mjData* d) {
|
|||||||
mjtNum qloc[4];
|
mjtNum qloc[4];
|
||||||
if (jtype == mjJNT_BALL) {
|
if (jtype == mjJNT_BALL) {
|
||||||
mju_copy4(qloc, d->qpos+qadr);
|
mju_copy4(qloc, d->qpos+qadr);
|
||||||
|
mju_normalize4(qloc);
|
||||||
} else {
|
} else {
|
||||||
mju_axisAngle2Quat(qloc, m->jnt_axis+3*jid, d->qpos[qadr] - m->qpos0[qadr]);
|
mju_axisAngle2Quat(qloc, m->jnt_axis+3*jid, d->qpos[qadr] - m->qpos0[qadr]);
|
||||||
}
|
}
|
||||||
@@ -890,13 +886,15 @@ void mj_transmission(const mjModel* m, mjData* d) {
|
|||||||
int j = m->jnt_qposadr[id];
|
int j = m->jnt_qposadr[id];
|
||||||
|
|
||||||
// axis: expmap representation of quaternion
|
// axis: expmap representation of quaternion
|
||||||
mju_quat2Vel(axis, d->qpos+j, 1);
|
mju_copy4(quat, d->qpos+j);
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_quat2Vel(axis, quat, 1);
|
||||||
|
|
||||||
// gearAxis: rotate to parent frame if necessary
|
// gearAxis: rotate to parent frame if necessary
|
||||||
if (m->actuator_trntype[i] == mjTRN_JOINT) {
|
if (m->actuator_trntype[i] == mjTRN_JOINT) {
|
||||||
mju_copy3(gearAxis, gear);
|
mju_copy3(gearAxis, gear);
|
||||||
} else {
|
} else {
|
||||||
mju_negQuat(quat, d->qpos+j);
|
mju_negQuat(quat, quat);
|
||||||
mju_rotVecQuat(gearAxis, gear, quat);
|
mju_rotVecQuat(gearAxis, gear, quat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -923,12 +921,15 @@ void mj_transmission(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
// axis: expmap representation of quaternion
|
// axis: expmap representation of quaternion
|
||||||
mju_quat2Vel(axis, d->qpos+j+3, 1);
|
mju_quat2Vel(axis, d->qpos+j+3, 1);
|
||||||
|
mju_copy4(quat, d->qpos+j+3);
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_quat2Vel(axis, quat, 1);
|
||||||
|
|
||||||
// gearAxis: rotate to world frame if necessary
|
// gearAxis: rotate to world frame if necessary
|
||||||
if (m->actuator_trntype[i] == mjTRN_JOINT) {
|
if (m->actuator_trntype[i] == mjTRN_JOINT) {
|
||||||
mju_copy3(gearAxis, gear+3);
|
mju_copy3(gearAxis, gear+3);
|
||||||
} else {
|
} else {
|
||||||
mju_negQuat(quat, d->qpos+j+3);
|
mju_negQuat(quat, quat);
|
||||||
mju_rotVecQuat(gearAxis, gear+3, quat);
|
mju_rotVecQuat(gearAxis, gear+3, quat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,284 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#include "engine/engine_name.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <mujoco/mjmodel.h>
|
||||||
|
#include "engine/engine_crossplatform.h"
|
||||||
|
#include "engine/engine_io.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------- name functions --------------------------------------------------------
|
||||||
|
// get number of objects and name addresses for given object type
|
||||||
|
static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) {
|
||||||
|
int num = -1;
|
||||||
|
// map address starts at the end, subtract with explicit switch fallthrough below
|
||||||
|
*mapadr = m->nnames_map;
|
||||||
|
|
||||||
|
// get address list and size for object type
|
||||||
|
switch (type) {
|
||||||
|
case mjOBJ_BODY:
|
||||||
|
case mjOBJ_XBODY:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nbody;
|
||||||
|
*padr = m->name_bodyadr;
|
||||||
|
num = m->nbody;
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_JOINT:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->njnt;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_jntadr;
|
||||||
|
num = m->njnt;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_GEOM:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ngeom;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_geomadr;
|
||||||
|
num = m->ngeom;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_SITE:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nsite;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_siteadr;
|
||||||
|
num = m->nsite;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_CAMERA:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ncam;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_camadr;
|
||||||
|
num = m->ncam;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_LIGHT:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nlight;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_lightadr;
|
||||||
|
num = m->nlight;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_FLEX:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nflex;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_flexadr;
|
||||||
|
num = m->nflex;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_MESH:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nmesh;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_meshadr;
|
||||||
|
num = m->nmesh;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_SKIN:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nskin;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_skinadr;
|
||||||
|
num = m->nskin;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_HFIELD:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nhfield;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_hfieldadr;
|
||||||
|
num = m->nhfield;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_TEXTURE:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ntex;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_texadr;
|
||||||
|
num = m->ntex;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_MATERIAL:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nmat;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_matadr;
|
||||||
|
num = m->nmat;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_PAIR:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->npair;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_pairadr;
|
||||||
|
num = m->npair;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_EXCLUDE:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nexclude;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_excludeadr;
|
||||||
|
num = m->nexclude;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_EQUALITY:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->neq;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_eqadr;
|
||||||
|
num = m->neq;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_TENDON:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ntendon;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_tendonadr;
|
||||||
|
num = m->ntendon;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_ACTUATOR:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nu;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_actuatoradr;
|
||||||
|
num = m->nu;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_SENSOR:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nsensor;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_sensoradr;
|
||||||
|
num = m->nsensor;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_NUMERIC:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nnumeric;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_numericadr;
|
||||||
|
num = m->nnumeric;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_TEXT:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ntext;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_textadr;
|
||||||
|
num = m->ntext;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_TUPLE:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->ntuple;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_tupleadr;
|
||||||
|
num = m->ntuple;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_KEY:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nkey;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_keyadr;
|
||||||
|
num = m->nkey;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
case mjOBJ_PLUGIN:
|
||||||
|
*mapadr -= mjLOAD_MULTIPLE*m->nplugin;
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = m->name_pluginadr;
|
||||||
|
num = m->nplugin;
|
||||||
|
}
|
||||||
|
mjFALLTHROUGH;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (num < 0) {
|
||||||
|
*padr = 0;
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get string hash, see http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
uint64_t mj_hashString(const char* s, uint64_t n) {
|
||||||
|
uint64_t h = 5381;
|
||||||
|
int c;
|
||||||
|
while ((c = *s++)) {
|
||||||
|
h = ((h << 5) + h) ^ c;
|
||||||
|
}
|
||||||
|
return h % n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get id of object with the specified mjtObj type and name,
|
||||||
|
// returns -1 if id not found
|
||||||
|
int mj_name2id(const mjModel* m, int type, const char* name) {
|
||||||
|
int mapadr;
|
||||||
|
int* adr = 0;
|
||||||
|
|
||||||
|
// get number of objects and name addresses
|
||||||
|
int num = mjLOAD_MULTIPLE*_getnumadr(m, type, &adr, &mapadr);
|
||||||
|
|
||||||
|
// search
|
||||||
|
if (num) { // look up at hash address
|
||||||
|
uint64_t hash = mj_hashString(name, num);
|
||||||
|
uint64_t i = hash;
|
||||||
|
|
||||||
|
do {
|
||||||
|
int j = m->names_map[mapadr + i];
|
||||||
|
if (j < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(name, m->names+adr[j], m->nnames-adr[j])) {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
if ((++i) == num)i = 0;
|
||||||
|
} while (i != hash);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// get name of object with the specified mjtObj type and id,
|
||||||
|
// returns NULL if name not found
|
||||||
|
const char* mj_id2name(const mjModel* m, int type, int id) {
|
||||||
|
int mapadr;
|
||||||
|
int* adr = 0;
|
||||||
|
|
||||||
|
// get number of objects and name addresses
|
||||||
|
int num = _getnumadr(m, type, &adr, &mapadr);
|
||||||
|
|
||||||
|
// id is in [0, num) and the found name is not the empty string "\0"
|
||||||
|
if (id >= 0 && id < num && m->names[adr[id]]) {
|
||||||
|
return m->names+adr[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// 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_SRC_ENGINE_ENGINE_NAME_H_
|
||||||
|
#define MUJOCO_SRC_ENGINE_ENGINE_NAME_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <mujoco/mjexport.h>
|
||||||
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------- name functions --------------------------------------------------------
|
||||||
|
|
||||||
|
// get string hash, see http://www.cse.yorku.ca/~oz/hash.html
|
||||||
|
uint64_t mj_hashString(const char* s, uint64_t n);
|
||||||
|
|
||||||
|
// get id of object with the specified mjtObj type and name, returns -1 if id not found
|
||||||
|
MJAPI int mj_name2id(const mjModel* m, int type, const char* name);
|
||||||
|
|
||||||
|
// get name of object with the specified mjtObj type and id, returns NULL if name not found
|
||||||
|
MJAPI const char* mj_id2name(const mjModel* m, int type, int id);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MUJOCO_SRC_ENGINE_ENGINE_NAME_H_
|
||||||
@@ -64,9 +64,11 @@ static void mj_springdamper(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
case mjJNT_BALL:
|
case mjJNT_BALL:
|
||||||
{
|
{
|
||||||
mjtNum dif[3];
|
|
||||||
// convert quatertion difference into angular "velocity"
|
// convert quatertion difference into angular "velocity"
|
||||||
mju_subQuat(dif, d->qpos + padr, m->qpos_spring + padr);
|
mjtNum dif[3], quat[4];
|
||||||
|
mju_copy4(quat, d->qpos+padr);
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_subQuat(dif, quat, m->qpos_spring + padr);
|
||||||
|
|
||||||
// apply torque
|
// apply torque
|
||||||
d->qfrc_spring[dadr+0] = -stiffness*dif[0];
|
d->qfrc_spring[dadr+0] = -stiffness*dif[0];
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <mujoco/mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "engine/engine_core_constraint.h"
|
#include "engine/engine_core_constraint.h"
|
||||||
#include "engine/engine_io.h"
|
#include "engine/engine_io.h"
|
||||||
|
#include "engine/engine_name.h"
|
||||||
#include "engine/engine_support.h"
|
#include "engine/engine_support.h"
|
||||||
#include "engine/engine_util_errmem.h"
|
#include "engine/engine_util_errmem.h"
|
||||||
#include "engine/engine_util_misc.h"
|
#include "engine/engine_util_misc.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "engine/engine_resource.h"
|
#include "engine/engine_resource.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -41,7 +42,6 @@ static void* _fileToMemory(FILE* fp, const char* filename, size_t* filesize);
|
|||||||
|
|
||||||
// file buffer used internally for the OS filesystem
|
// file buffer used internally for the OS filesystem
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE* fp; // file handle
|
|
||||||
int is_read; // set to nonzero if buffer was read into
|
int is_read; // set to nonzero if buffer was read into
|
||||||
uint8_t* buffer; // raw bytes from file
|
uint8_t* buffer; // raw bytes from file
|
||||||
size_t nbuffer; // size of buffer in bytes
|
size_t nbuffer; // size of buffer in bytes
|
||||||
@@ -100,20 +100,16 @@ mjResource* mju_openResource(const char* name, char* error, size_t error_sz) {
|
|||||||
spec->is_read = 0;
|
spec->is_read = 0;
|
||||||
spec->buffer = NULL;
|
spec->buffer = NULL;
|
||||||
spec->nbuffer = 0;
|
spec->nbuffer = 0;
|
||||||
spec->fp = fopen(name, "rb");
|
|
||||||
if (!spec->fp) {
|
|
||||||
if (error) {
|
|
||||||
snprintf(error, error_sz,
|
|
||||||
"resource not found via provider or OS filesystem: '%s'", name);
|
|
||||||
}
|
|
||||||
mju_closeResource(resource);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct stat file_stat;
|
struct stat file_stat;
|
||||||
|
errno = 0;
|
||||||
if (stat(name, &file_stat) == 0) {
|
if (stat(name, &file_stat) == 0) {
|
||||||
memcpy(&spec->mtime, &file_stat.st_mtime, sizeof(time_t));
|
memcpy(&spec->mtime, &file_stat.st_mtime, sizeof(time_t));
|
||||||
} else {
|
} else {
|
||||||
memset(&spec->mtime, 0, sizeof(time_t));
|
if (error) {
|
||||||
|
snprintf(error, error_sz, "Error opening file '%s': %s", name, strerror(errno));
|
||||||
|
}
|
||||||
|
mju_closeResource(resource);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
mju_encodeBase64(resource->timestamp, (uint8_t*) &spec->mtime, sizeof(time_t));
|
mju_encodeBase64(resource->timestamp, (uint8_t*) &spec->mtime, sizeof(time_t));
|
||||||
return resource;
|
return resource;
|
||||||
@@ -157,17 +153,12 @@ int mju_readResource(mjResource* resource, const void** buffer) {
|
|||||||
return resource->provider->read(resource, buffer);
|
return resource->provider->read(resource, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if provider is NULL, then OS filesystem is used
|
// if provider is NULL, then OS filesystem is used
|
||||||
file_spec* spec = (file_spec*) resource->data;
|
file_spec* spec = (file_spec*) resource->data;
|
||||||
if (!spec->fp && !spec->is_read) {
|
|
||||||
mjERROR("internal error FILE pointer undefined"); // should not occur
|
|
||||||
}
|
|
||||||
|
|
||||||
// only read once from file
|
// only read once from file
|
||||||
if (!spec->is_read) {
|
if (!spec->is_read) {
|
||||||
spec->buffer = _fileToMemory(spec->fp, resource->name, &(spec->nbuffer));
|
spec->buffer = mju_fileToMemory(resource->name, &(spec->nbuffer));
|
||||||
spec->fp = NULL; // closed by _fileToMemory
|
|
||||||
spec->is_read = 1;
|
spec->is_read = 1;
|
||||||
}
|
}
|
||||||
*buffer = spec->buffer;
|
*buffer = spec->buffer;
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ void mj_sensorPos(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
case mjSENS_BALLQUAT: // ballquat
|
case mjSENS_BALLQUAT: // ballquat
|
||||||
mju_copy4(d->sensordata+adr, d->qpos+m->jnt_qposadr[objid]);
|
mju_copy4(d->sensordata+adr, d->qpos+m->jnt_qposadr[objid]);
|
||||||
|
mju_normalize4(d->sensordata+adr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case mjSENS_JOINTLIMITPOS: // jointlimitpos
|
case mjSENS_JOINTLIMITPOS: // jointlimitpos
|
||||||
@@ -899,7 +900,7 @@ void mj_sensorAcc(const mjModel* m, mjData* d) {
|
|||||||
// position-dependent energy (potential)
|
// position-dependent energy (potential)
|
||||||
void mj_energyPos(const mjModel* m, mjData* d) {
|
void mj_energyPos(const mjModel* m, mjData* d) {
|
||||||
int padr;
|
int padr;
|
||||||
mjtNum dif[3], stiffness;
|
mjtNum dif[3], quat[4], stiffness;
|
||||||
|
|
||||||
// disabled: clear and return
|
// disabled: clear and return
|
||||||
if (!mjENABLED(mjENBL_ENERGY)) {
|
if (!mjENABLED(mjENBL_ENERGY)) {
|
||||||
@@ -923,7 +924,9 @@ void mj_energyPos(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
switch ((mjtJoint) m->jnt_type[i]) {
|
switch ((mjtJoint) m->jnt_type[i]) {
|
||||||
case mjJNT_FREE:
|
case mjJNT_FREE:
|
||||||
mju_sub3(dif, d->qpos+padr, m->qpos_spring+padr);
|
mju_copy4(quat, d->qpos+padr);
|
||||||
|
mju_normalize4(quat);
|
||||||
|
mju_sub3(dif, quat, m->qpos_spring+padr);
|
||||||
d->energy[0] += 0.5*stiffness*mju_dot3(dif, dif);
|
d->energy[0] += 0.5*stiffness*mju_dot3(dif, dif);
|
||||||
|
|
||||||
// continue with rotations
|
// continue with rotations
|
||||||
@@ -932,6 +935,8 @@ void mj_energyPos(const mjModel* m, mjData* d) {
|
|||||||
|
|
||||||
case mjJNT_BALL:
|
case mjJNT_BALL:
|
||||||
// covert quatertion difference into angular "velocity"
|
// covert quatertion difference into angular "velocity"
|
||||||
|
mju_copy4(quat, d->qpos+padr);
|
||||||
|
mju_normalize4(quat);
|
||||||
mju_subQuat(dif, d->qpos + padr, m->qpos_spring + padr);
|
mju_subQuat(dif, d->qpos + padr, m->qpos_spring + padr);
|
||||||
d->energy[0] += 0.5*stiffness*mju_dot3(dif, dif);
|
d->energy[0] += 0.5*stiffness*mju_dot3(dif, dif);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+1
-265
@@ -15,7 +15,6 @@
|
|||||||
#include "engine/engine_support.h"
|
#include "engine/engine_support.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
#include "engine/engine_util_spatial.h"
|
#include "engine/engine_util_spatial.h"
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#include "immintrin.h"
|
#include "immintrin.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -868,269 +867,6 @@ void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- name functions --------------------------------------------------------
|
|
||||||
|
|
||||||
// get number of objects and name addresses for given object type
|
|
||||||
static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) {
|
|
||||||
int num = -1;
|
|
||||||
// map address starts at the end, subtract with explicit switch fallthrough below
|
|
||||||
*mapadr = m->nnames_map;
|
|
||||||
|
|
||||||
// get address list and size for object type
|
|
||||||
switch (type) {
|
|
||||||
case mjOBJ_BODY:
|
|
||||||
case mjOBJ_XBODY:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nbody;
|
|
||||||
*padr = m->name_bodyadr;
|
|
||||||
num = m->nbody;
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_JOINT:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->njnt;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_jntadr;
|
|
||||||
num = m->njnt;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_GEOM:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ngeom;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_geomadr;
|
|
||||||
num = m->ngeom;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_SITE:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nsite;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_siteadr;
|
|
||||||
num = m->nsite;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_CAMERA:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ncam;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_camadr;
|
|
||||||
num = m->ncam;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_LIGHT:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nlight;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_lightadr;
|
|
||||||
num = m->nlight;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_FLEX:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nflex;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_flexadr;
|
|
||||||
num = m->nflex;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_MESH:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nmesh;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_meshadr;
|
|
||||||
num = m->nmesh;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_SKIN:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nskin;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_skinadr;
|
|
||||||
num = m->nskin;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_HFIELD:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nhfield;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_hfieldadr;
|
|
||||||
num = m->nhfield;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_TEXTURE:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ntex;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_texadr;
|
|
||||||
num = m->ntex;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_MATERIAL:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nmat;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_matadr;
|
|
||||||
num = m->nmat;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_PAIR:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->npair;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_pairadr;
|
|
||||||
num = m->npair;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_EXCLUDE:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nexclude;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_excludeadr;
|
|
||||||
num = m->nexclude;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_EQUALITY:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->neq;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_eqadr;
|
|
||||||
num = m->neq;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_TENDON:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ntendon;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_tendonadr;
|
|
||||||
num = m->ntendon;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_ACTUATOR:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nu;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_actuatoradr;
|
|
||||||
num = m->nu;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_SENSOR:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nsensor;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_sensoradr;
|
|
||||||
num = m->nsensor;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_NUMERIC:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nnumeric;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_numericadr;
|
|
||||||
num = m->nnumeric;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_TEXT:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ntext;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_textadr;
|
|
||||||
num = m->ntext;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_TUPLE:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->ntuple;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_tupleadr;
|
|
||||||
num = m->ntuple;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_KEY:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nkey;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_keyadr;
|
|
||||||
num = m->nkey;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
case mjOBJ_PLUGIN:
|
|
||||||
*mapadr -= mjLOAD_MULTIPLE*m->nplugin;
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = m->name_pluginadr;
|
|
||||||
num = m->nplugin;
|
|
||||||
}
|
|
||||||
mjFALLTHROUGH;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (num < 0) {
|
|
||||||
*padr = 0;
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get string hash, see http://www.cse.yorku.ca/~oz/hash.html
|
|
||||||
uint64_t mj_hashString(const char* s, uint64_t n) {
|
|
||||||
uint64_t h = 5381;
|
|
||||||
int c;
|
|
||||||
while ((c = *s++)) {
|
|
||||||
h = ((h << 5) + h) ^ c;
|
|
||||||
}
|
|
||||||
return h % n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get id of object with the specified mjtObj type and name,
|
|
||||||
// returns -1 if id not found
|
|
||||||
int mj_name2id(const mjModel* m, int type, const char* name) {
|
|
||||||
int mapadr;
|
|
||||||
int* adr = 0;
|
|
||||||
|
|
||||||
// get number of objects and name addresses
|
|
||||||
int num = mjLOAD_MULTIPLE*_getnumadr(m, type, &adr, &mapadr);
|
|
||||||
|
|
||||||
// search
|
|
||||||
if (num) { // look up at hash address
|
|
||||||
uint64_t hash = mj_hashString(name, num);
|
|
||||||
uint64_t i = hash;
|
|
||||||
|
|
||||||
do {
|
|
||||||
int j = m->names_map[mapadr + i];
|
|
||||||
if (j < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(name, m->names+adr[j], m->nnames-adr[j])) {
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
if ((++i) == num)i = 0;
|
|
||||||
} while (i != hash);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// get name of object with the specified mjtObj type and id,
|
|
||||||
// returns NULL if name not found
|
|
||||||
const char* mj_id2name(const mjModel* m, int type, int id) {
|
|
||||||
int mapadr;
|
|
||||||
int* adr = 0;
|
|
||||||
|
|
||||||
// get number of objects and name addresses
|
|
||||||
int num = _getnumadr(m, type, &adr, &mapadr);
|
|
||||||
|
|
||||||
// id is in [0, num) and the found name is not the empty string "\0"
|
|
||||||
if (id >= 0 && id < num && m->names[adr[id]]) {
|
|
||||||
return m->names+adr[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- inertia functions -----------------------------------------------------
|
//-------------------------- inertia functions -----------------------------------------------------
|
||||||
|
|
||||||
// convert sparse inertia matrix M into full matrix
|
// convert sparse inertia matrix M into full matrix
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
#ifndef MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_
|
#ifndef MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_
|
||||||
#define MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_
|
#define MUJOCO_SRC_ENGINE_ENGINE_SUPPORT_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
#include <mujoco/mjexport.h>
|
#include <mujoco/mjexport.h>
|
||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
@@ -113,18 +111,6 @@ int mj_jacSum(const mjModel* m, mjData* d, int* chain,
|
|||||||
MJAPI void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body);
|
MJAPI void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body);
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- name functions --------------------------------------------------------
|
|
||||||
|
|
||||||
// get string hash, see http://www.cse.yorku.ca/~oz/hash.html
|
|
||||||
uint64_t mj_hashString(const char* s, uint64_t n);
|
|
||||||
|
|
||||||
// get id of object with the specified mjtObj type and name, returns -1 if id not found
|
|
||||||
MJAPI int mj_name2id(const mjModel* m, int type, const char* name);
|
|
||||||
|
|
||||||
// get name of object with the specified mjtObj type and id, returns NULL if name not found
|
|
||||||
MJAPI const char* mj_id2name(const mjModel* m, int type, int id);
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- inertia functions -----------------------------------------------------
|
//-------------------------- inertia functions -----------------------------------------------------
|
||||||
|
|
||||||
// convert sparse inertia matrix M into full matrix
|
// convert sparse inertia matrix M into full matrix
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <mujoco/mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#include "immintrin.h"
|
#include "immintrin.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -609,7 +609,7 @@ void mju_addToScl(mjtNum* res, const mjtNum* vec, mjtNum scl, int n) {
|
|||||||
void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n) {
|
void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#if defined(__AVX__) && defined(mjUSEAVX) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && defined(mjUSEAVX) && !defined(mjUSESINGLE)
|
||||||
int n_4 = n - 4;
|
int n_4 = n - 4;
|
||||||
|
|
||||||
// vector part
|
// vector part
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ extern "C" {
|
|||||||
|
|
||||||
//------------------------------ standard library functions ----------------------------------------
|
//------------------------------ standard library functions ----------------------------------------
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
#if !defined(mjUSESINGLE)
|
||||||
#define mju_sqrt sqrt
|
#define mju_sqrt sqrt
|
||||||
#define mju_exp exp
|
#define mju_exp exp
|
||||||
#define mju_sin sin
|
#define mju_sin sin
|
||||||
@@ -59,7 +59,7 @@ extern "C" {
|
|||||||
#define mju_log10 log10f
|
#define mju_log10 log10f
|
||||||
#define mju_floor floorf
|
#define mju_floor floorf
|
||||||
#define mju_ceil ceilf
|
#define mju_ceil ceilf
|
||||||
#endif
|
#endif // !defined(mjUSESINGLE)
|
||||||
|
|
||||||
|
|
||||||
//------------------------------ 3D vector and matrix-vector operations ----------------------------
|
//------------------------------ 3D vector and matrix-vector operations ----------------------------
|
||||||
|
|||||||
@@ -1407,51 +1407,6 @@ char* mju_strncpy(char *dst, const char *src, int n) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// assemble full filename from directory and filename, return 0 on success
|
|
||||||
int mju_makefullname(char* full, size_t nfull, const char* dir, const char* file) {
|
|
||||||
int dirlen = (!dir) ? 0 : strlen(dir);
|
|
||||||
int filelen = (!file) ? 0 : strlen(file);
|
|
||||||
char* filepos = full + dirlen;
|
|
||||||
|
|
||||||
// missing filename
|
|
||||||
if (!filelen) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no directory then just copy filename over
|
|
||||||
if (!dirlen) {
|
|
||||||
// make sure full has space
|
|
||||||
if (filelen >= nfull) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
strcpy(full, file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure full has space
|
|
||||||
if (dirlen + filelen >= nfull) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dir doesn't end with a slash
|
|
||||||
if (dir[dirlen - 1] != '\\' && dir[dirlen - 1] != '/') {
|
|
||||||
// need extra space for forward slash
|
|
||||||
if ((dirlen + filelen + 1) >= nfull) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add forward slash
|
|
||||||
*filepos++ = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy directory and file over
|
|
||||||
memcpy(full, dir, sizeof(char) * dirlen);
|
|
||||||
strcpy(filepos, file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sigmoid function over 0<=x<=1 using quintic polynomial
|
// sigmoid function over 0<=x<=1 using quintic polynomial
|
||||||
mjtNum mju_sigmoid(mjtNum x) {
|
mjtNum mju_sigmoid(mjtNum x) {
|
||||||
// fast return
|
// fast return
|
||||||
|
|||||||
@@ -164,10 +164,6 @@ MJAPI mjtNum mju_Halton(int index, int base);
|
|||||||
// call strncpy, then set dst[n-1] = 0
|
// call strncpy, then set dst[n-1] = 0
|
||||||
MJAPI char* mju_strncpy(char *dst, const char *src, int n);
|
MJAPI char* mju_strncpy(char *dst, const char *src, int n);
|
||||||
|
|
||||||
// assemble full filename from directory and filename, return 0 on success
|
|
||||||
MJAPI int mju_makefullname(char* full, size_t nfull,
|
|
||||||
const char* dir, const char* file);
|
|
||||||
|
|
||||||
// sigmoid function over 0<=x<=1 using quintic polynomial
|
// sigmoid function over 0<=x<=1 using quintic polynomial
|
||||||
MJAPI mjtNum mju_sigmoid(mjtNum x);
|
MJAPI mjtNum mju_sigmoid(mjtNum x);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#define MUJOCO_SRC_ENGINE_ENGINE_UTIL_SPARSE_AVX_H_
|
#define MUJOCO_SRC_ENGINE_ENGINE_UTIL_SPARSE_AVX_H_
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
|
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ int mju_compare_avx(const int* vec1, const int* vec2, int n) {
|
|||||||
return !memcmp(vec1+i, vec2+i, (n-i)*sizeof(int));
|
return !memcmp(vec1+i, vec2+i, (n-i)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(__AVX__) && defined(mjUSEDOUBLE)
|
#endif // defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
|
|
||||||
#endif // mjUSEPLATFORMSIMD
|
#endif // mjUSEPLATFORMSIMD
|
||||||
|
|
||||||
|
|||||||
@@ -247,8 +247,8 @@ void mju_quatIntegrate(mjtNum quat[4], const mjtNum vel[3], mjtNum scale) {
|
|||||||
mju_copy3(tmp, vel);
|
mju_copy3(tmp, vel);
|
||||||
angle = scale * mju_normalize3(tmp);
|
angle = scale * mju_normalize3(tmp);
|
||||||
mju_axisAngle2Quat(qrot, tmp, angle);
|
mju_axisAngle2Quat(qrot, tmp, angle);
|
||||||
mju_mulQuat(quat, quat, qrot);
|
|
||||||
mju_normalize4(quat);
|
mju_normalize4(quat);
|
||||||
|
mju_mulQuat(quat, quat, qrot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <mujoco/mjvisualize.h>
|
#include <mujoco/mjvisualize.h>
|
||||||
#include "engine/engine_array_safety.h"
|
#include "engine/engine_array_safety.h"
|
||||||
#include "engine/engine_io.h"
|
#include "engine/engine_io.h"
|
||||||
|
#include "engine/engine_name.h"
|
||||||
#include "engine/engine_plugin.h"
|
#include "engine/engine_plugin.h"
|
||||||
#include "engine/engine_support.h"
|
#include "engine/engine_support.h"
|
||||||
#include "engine/engine_util_blas.h"
|
#include "engine/engine_util_blas.h"
|
||||||
@@ -301,21 +302,13 @@ static void setMaterial(const mjModel* m, mjvGeom* geom, int matid, const float*
|
|||||||
const mjtByte* flags) {
|
const mjtByte* flags) {
|
||||||
// set material properties if given
|
// set material properties if given
|
||||||
if (matid >= 0) {
|
if (matid >= 0) {
|
||||||
f2f(geom->texrepeat, m->mat_texrepeat + 2*matid, 2);
|
|
||||||
f2f(geom->rgba, m->mat_rgba + 4*matid, 4);
|
f2f(geom->rgba, m->mat_rgba + 4*matid, 4);
|
||||||
geom->texuniform = m->mat_texuniform[matid];
|
|
||||||
geom->emission = m->mat_emission[matid];
|
geom->emission = m->mat_emission[matid];
|
||||||
geom->specular = m->mat_specular[matid];
|
geom->specular = m->mat_specular[matid];
|
||||||
geom->shininess = m->mat_shininess[matid];
|
geom->shininess = m->mat_shininess[matid];
|
||||||
geom->reflectance = m->mat_reflectance[matid];
|
geom->reflectance = m->mat_reflectance[matid];
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise clear texrepeat
|
|
||||||
else {
|
|
||||||
geom->texrepeat[0] = 0;
|
|
||||||
geom->texrepeat[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use rgba if different from default, or no material given
|
// use rgba if different from default, or no material given
|
||||||
if (rgba[0] != 0.5f || rgba[1] != 0.5f || rgba[2] != 0.5f || rgba[3] != 1.0f || matid < 0) {
|
if (rgba[0] != 0.5f || rgba[1] != 0.5f || rgba[2] != 0.5f || rgba[3] != 1.0f || matid < 0) {
|
||||||
f2f(geom->rgba, rgba, 4);
|
f2f(geom->rgba, rgba, 4);
|
||||||
@@ -323,7 +316,7 @@ static void setMaterial(const mjModel* m, mjvGeom* geom, int matid, const float*
|
|||||||
|
|
||||||
// set texture
|
// set texture
|
||||||
if (flags[mjVIS_TEXTURE] && matid >= 0) {
|
if (flags[mjVIS_TEXTURE] && matid >= 0) {
|
||||||
geom->texid = m->mat_texid[matid];
|
geom->matid = matid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale alpha for dynamic geoms only
|
// scale alpha for dynamic geoms only
|
||||||
@@ -457,11 +450,8 @@ void mjv_initGeom(mjvGeom* geom, int type, const mjtNum* size,
|
|||||||
|
|
||||||
// set defaults that cannot be assigned via this function
|
// set defaults that cannot be assigned via this function
|
||||||
geom->dataid = -1;
|
geom->dataid = -1;
|
||||||
geom->texid = -1;
|
geom->matid = -1;
|
||||||
geom->texuniform = 0;
|
|
||||||
geom->texcoord = 0;
|
geom->texcoord = 0;
|
||||||
geom->texrepeat[0] = 1;
|
|
||||||
geom->texrepeat[1] = 1;
|
|
||||||
geom->emission = 0;
|
geom->emission = 0;
|
||||||
geom->specular = 0.5;
|
geom->specular = 0.5;
|
||||||
geom->shininess = 0.5;
|
geom->shininess = 0.5;
|
||||||
@@ -570,7 +560,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
|
|||||||
thisgeom->texcoord = 1;
|
thisgeom->texcoord = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
thisgeom->texid = -1;
|
thisgeom->matid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// glow flex if selected
|
// glow flex if selected
|
||||||
|
|||||||
@@ -1294,6 +1294,43 @@ static void makeFont(mjrContext* con, int fontscale) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make materials, just for those that have textures
|
||||||
|
static void makeMaterial(const mjModel* m, mjrContext* con) {
|
||||||
|
memset(con->mat_texid, -1, sizeof(con->mat_texid));
|
||||||
|
memset(con->mat_texuniform, 0, sizeof(con->mat_texuniform));
|
||||||
|
memset(con->mat_texrepeat, 0, sizeof(con->mat_texrepeat));
|
||||||
|
if (!m->nmat || !m->ntex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->nmat >= mjMAXMATERIAL-1) {
|
||||||
|
mju_error("Maximum number of materials is %d", mjMAXMATERIAL);
|
||||||
|
}
|
||||||
|
for (int i=0; i < m->nmat; i++) {
|
||||||
|
if (m->mat_texid[i*mjNTEXMAT] >= 0) {
|
||||||
|
for (int j=0; j < mjNTEXMAT; j++) {
|
||||||
|
con->mat_texid[i*mjNTEXMAT + j] = m->mat_texid[i*mjNTEXMAT + j];
|
||||||
|
}
|
||||||
|
con->mat_texuniform[i] = m->mat_texuniform[i];
|
||||||
|
con->mat_texrepeat[2*i] = m->mat_texrepeat[2*i];
|
||||||
|
con->mat_texrepeat[2*i+1] = m->mat_texrepeat[2*i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// find skybox texture
|
||||||
|
for (int i=0; i < m->ntex; i++) {
|
||||||
|
if (m->tex_type[i] == mjTEXTURE_SKYBOX) {
|
||||||
|
if (m->nmat >= mjMAXMATERIAL-2) {
|
||||||
|
mju_error("With skybox, maximum number of materials is %d", mjMAXMATERIAL);
|
||||||
|
}
|
||||||
|
con->mat_texid[mjNTEXMAT * (mjMAXMATERIAL-1)] = i;
|
||||||
|
for (int j=1; j < mjNTEXMAT; j++) {
|
||||||
|
con->mat_texid[mjNTEXMAT * (mjMAXMATERIAL-1) + j] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// make textures
|
// make textures
|
||||||
@@ -1585,6 +1622,7 @@ void mjr_makeContext_offSize(const mjModel* m, mjrContext* con, int fontscale,
|
|||||||
// make everything
|
// make everything
|
||||||
makeOff(con);
|
makeOff(con);
|
||||||
makeShadow(m, con);
|
makeShadow(m, con);
|
||||||
|
makeMaterial(m, con);
|
||||||
makeTexture(m, con);
|
makeTexture(m, con);
|
||||||
makePlane(m, con);
|
makePlane(m, con);
|
||||||
makeMesh(m, con);
|
makeMesh(m, con);
|
||||||
|
|||||||
+19
-15
@@ -61,6 +61,10 @@ enum {
|
|||||||
// enable/disable texture mapping
|
// enable/disable texture mapping
|
||||||
static void settexture(int type, int state, const mjrContext* con, const mjvGeom* geom) {
|
static void settexture(int type, int state, const mjrContext* con, const mjvGeom* geom) {
|
||||||
float plane[4], scl[2];
|
float plane[4], scl[2];
|
||||||
|
int texid = -1;
|
||||||
|
if (geom) {
|
||||||
|
texid = (geom->matid == -1) ? -1 : con->mat_texid[mjNTEXMAT * geom->matid];
|
||||||
|
}
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
if (type == mjtexSHADOW) {
|
if (type == mjtexSHADOW) {
|
||||||
@@ -92,7 +96,7 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
|
|||||||
if (state) {
|
if (state) {
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, con->texture[geom->texid]);
|
glBindTexture(GL_TEXTURE_2D, con->texture[texid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable
|
// disable
|
||||||
@@ -103,18 +107,18 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2D
|
// 2D
|
||||||
else if (type == mjtexREGULAR && con->textureType[geom->texid] == mjTEXTURE_2D) {
|
else if (type == mjtexREGULAR && con->textureType[texid] == mjTEXTURE_2D) {
|
||||||
// enable
|
// enable
|
||||||
if (state) {
|
if (state) {
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_TEXTURE_GEN_S);
|
glEnable(GL_TEXTURE_GEN_S);
|
||||||
glEnable(GL_TEXTURE_GEN_T);
|
glEnable(GL_TEXTURE_GEN_T);
|
||||||
glBindTexture(GL_TEXTURE_2D, con->texture[geom->texid]);
|
glBindTexture(GL_TEXTURE_2D, con->texture[texid]);
|
||||||
|
|
||||||
// determine scaling, adjust for pre-scaled geoms
|
// determine scaling, adjust for pre-scaled geoms
|
||||||
scl[0] = geom->texrepeat[0];
|
scl[0] = con->mat_texrepeat[geom->matid*2];
|
||||||
scl[1] = geom->texrepeat[1];
|
scl[1] = con->mat_texrepeat[geom->matid*2+1];
|
||||||
if (geom->dataid >= 0) {
|
if (geom->dataid >= 0) {
|
||||||
if (geom->size[0] > 0) {
|
if (geom->size[0] > 0) {
|
||||||
scl[0] = scl[0] / mju_max(mjMINVAL, geom->size[0]);
|
scl[0] = scl[0] / mju_max(mjMINVAL, geom->size[0]);
|
||||||
@@ -126,7 +130,7 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
|
|||||||
}
|
}
|
||||||
|
|
||||||
// uniform: repeat relative to spatial units rather than object
|
// uniform: repeat relative to spatial units rather than object
|
||||||
if (geom->texuniform) {
|
if (con->mat_texuniform[geom->matid]) {
|
||||||
if (geom->size[0] > 0) {
|
if (geom->size[0] > 0) {
|
||||||
scl[0] = scl[0] * geom->size[0];
|
scl[0] = scl[0] * geom->size[0];
|
||||||
}
|
}
|
||||||
@@ -161,15 +165,15 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
|
|||||||
glEnable(GL_TEXTURE_GEN_S);
|
glEnable(GL_TEXTURE_GEN_S);
|
||||||
glEnable(GL_TEXTURE_GEN_T);
|
glEnable(GL_TEXTURE_GEN_T);
|
||||||
glEnable(GL_TEXTURE_GEN_R);
|
glEnable(GL_TEXTURE_GEN_R);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, con->texture[geom->texid]);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, con->texture[texid]);
|
||||||
|
|
||||||
// set mapping : cube
|
// set mapping : cube
|
||||||
if (type == mjtexREGULAR) {
|
if (type == mjtexREGULAR) {
|
||||||
mjr_setf4(plane, geom->texuniform ? geom->size[0] : 1, 0, 0, 0);
|
mjr_setf4(plane, con->mat_texuniform[geom->matid] ? geom->size[0] : 1, 0, 0, 0);
|
||||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
|
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
|
||||||
mjr_setf4(plane, 0, geom->texuniform ? geom->size[1] : 1, 0, 0);
|
mjr_setf4(plane, 0, con->mat_texuniform[geom->matid] ? geom->size[1] : 1, 0, 0);
|
||||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane);
|
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane);
|
||||||
mjr_setf4(plane, 0, 0, geom->texuniform ? geom->size[2] : 1, 0);
|
mjr_setf4(plane, 0, 0, con->mat_texuniform[geom->matid] ? geom->size[2] : 1, 0);
|
||||||
glTexGenfv(GL_R, GL_OBJECT_PLANE, plane);
|
glTexGenfv(GL_R, GL_OBJECT_PLANE, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +236,7 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
|
|||||||
behind = isBehind(headpos, geom->pos, geom->mat);
|
behind = isBehind(headpos, geom->pos, geom->mat);
|
||||||
|
|
||||||
// enable texture in normal and shadowmap mode
|
// enable texture in normal and shadowmap mode
|
||||||
if (geom->texid >= 0 && con->ntexture > 0 &&
|
if (geom->matid >= 0 &&
|
||||||
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
|
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
|
||||||
settexture(mjtexREGULAR, 1, con, geom);
|
settexture(mjtexREGULAR, 1, con, geom);
|
||||||
}
|
}
|
||||||
@@ -515,14 +519,14 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
|
|||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
glVertexPointer(3, GL_FLOAT, 0, scn->flexface + 9*scn->flexfaceadr[geom->objid]);
|
glVertexPointer(3, GL_FLOAT, 0, scn->flexface + 9*scn->flexfaceadr[geom->objid]);
|
||||||
glNormalPointer(GL_FLOAT, 0, scn->flexnormal + 9*scn->flexfaceadr[geom->objid]);
|
glNormalPointer(GL_FLOAT, 0, scn->flexnormal + 9*scn->flexfaceadr[geom->objid]);
|
||||||
if (geom->texcoord && geom->texid>=0) {
|
if (geom->texcoord && geom->matid>=0) {
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, scn->flextexcoord + 6*scn->flexfaceadr[geom->objid]);
|
glTexCoordPointer(2, GL_FLOAT, 0, scn->flextexcoord + 6*scn->flexfaceadr[geom->objid]);
|
||||||
}
|
}
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3*scn->flexfaceused[geom->objid]);
|
glDrawArrays(GL_TRIANGLES, 0, 3*scn->flexfaceused[geom->objid]);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
if (geom->texcoord && geom->texid>=0) {
|
if (geom->texcoord && geom->matid>=0) {
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,7 +572,7 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// disable texture if enabled
|
// disable texture if enabled
|
||||||
if (geom->texid >= 0 && con->ntexture > 0 &&
|
if (geom->matid >= 0 &&
|
||||||
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
|
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
|
||||||
settexture(mjtexREGULAR, 0, con, geom);
|
settexture(mjtexREGULAR, 0, con, geom);
|
||||||
}
|
}
|
||||||
@@ -1268,7 +1272,7 @@ void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con) {
|
|||||||
if (con->textureType[i] == mjTEXTURE_SKYBOX) {
|
if (con->textureType[i] == mjTEXTURE_SKYBOX) {
|
||||||
// save first skybox texture id in tempgeom
|
// save first skybox texture id in tempgeom
|
||||||
memset(&tempgeom, 0, sizeof(mjvGeom));
|
memset(&tempgeom, 0, sizeof(mjvGeom));
|
||||||
tempgeom.texid = i;
|
tempgeom.matid = mjMAXMATERIAL - 1;
|
||||||
|
|
||||||
// modify settings
|
// modify settings
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|||||||
+717
-371
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ set(MUJOCO_USER_SRCS
|
|||||||
user_objects.h
|
user_objects.h
|
||||||
user_util.cc
|
user_util.cc
|
||||||
user_util.h
|
user_util.h
|
||||||
user_vfs.c
|
user_vfs.cc
|
||||||
user_vfs.h
|
user_vfs.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+190
-10
@@ -437,10 +437,11 @@ mjsPlugin* mjs_addPlugin(mjSpec* s) {
|
|||||||
|
|
||||||
|
|
||||||
// add default to model
|
// add default to model
|
||||||
mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id) {
|
mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, const mjsDefault* parent) {
|
||||||
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
||||||
*id = (int)modelC->NumDefaults();
|
mjCDef* parentC = parent ? static_cast<mjCDef*>(parent->element) :
|
||||||
mjCDef* def = modelC->AddDefault(classname, parentid);
|
static_cast<mjCModel*>(s->element)->Defaults(0);
|
||||||
|
mjCDef* def = modelC->AddDefault(classname, parentC);
|
||||||
if (def) {
|
if (def) {
|
||||||
return &def->spec;
|
return &def->spec;
|
||||||
} else {
|
} else {
|
||||||
@@ -529,6 +530,15 @@ mjsFrame* mjs_findFrame(mjSpec* s, const char* name) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// find keyframe by name
|
||||||
|
mjsKey* mjs_findKeyframe(mjSpec* s, const char* name) {
|
||||||
|
mjCModel* model = static_cast<mjCModel*>(s->element);
|
||||||
|
mjCKey* key = (mjCKey*)model->FindObject(mjOBJ_KEY, std::string(name));
|
||||||
|
return key ? &(static_cast<mjCKey*>(key)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set frame
|
// set frame
|
||||||
void mjs_setFrame(mjsElement* dest, mjsFrame* frame) {
|
void mjs_setFrame(mjsElement* dest, mjsFrame* frame) {
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
@@ -580,6 +590,183 @@ mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return spec's first element of selected type
|
||||||
|
mjsElement* mjs_firstElement(mjSpec* s, mjtObj type) {
|
||||||
|
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
||||||
|
return modelC->NextObject(NULL, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return spec's next element; return NULL if element is last
|
||||||
|
mjsElement* mjs_nextElement(mjSpec* s, mjsElement* element) {
|
||||||
|
mjCModel* modelC = static_cast<mjCModel*>(s->element);
|
||||||
|
return modelC->NextObject(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return body given mjsElement
|
||||||
|
mjsBody* mjs_asBody(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_BODY ? &(static_cast<mjCBody*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return geom given mjsElement
|
||||||
|
mjsGeom* mjs_asGeom(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_GEOM ? &(static_cast<mjCGeom*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return joint given mjsElement
|
||||||
|
mjsJoint* mjs_asJoint(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_JOINT ? &(static_cast<mjCJoint*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Return site given mjsElement
|
||||||
|
mjsSite* mjs_asSite(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_SITE ? &(static_cast<mjCSite*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return camera given mjsElement
|
||||||
|
mjsCamera* mjs_asCamera(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_CAMERA ? &(static_cast<mjCCamera*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return light given mjsElement
|
||||||
|
mjsLight* mjs_asLight(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_LIGHT ? &(static_cast<mjCLight*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return frame given mjsElement
|
||||||
|
mjsFrame* mjs_asFrame(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_FRAME ? &(static_cast<mjCFrame*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return actuator given mjsElement
|
||||||
|
mjsActuator* mjs_asActuator(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_ACTUATOR ? &(static_cast<mjCActuator*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return sensor given mjsElement
|
||||||
|
mjsSensor* mjs_asSensor(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_SENSOR ? &(static_cast<mjCSensor*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return flex given mjsElement
|
||||||
|
mjsFlex* mjs_asFlex(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_FLEX ? &(static_cast<mjCFlex*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return pair given mjsElement
|
||||||
|
mjsPair* mjs_asPair(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_PAIR ? &(static_cast<mjCPair*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return equality given mjsElement
|
||||||
|
mjsEquality* mjs_asEquality(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_EQUALITY ? &(static_cast<mjCEquality*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return exclude given mjsElement
|
||||||
|
mjsExclude* mjs_asExclude(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_EXCLUDE ? &(static_cast<mjCBodyPair*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return tendon given mjsElement
|
||||||
|
mjsTendon* mjs_asTendon(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_TENDON ? &(static_cast<mjCTendon*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return numeric given mjsElement
|
||||||
|
mjsNumeric* mjs_asNumeric(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_NUMERIC ? &(static_cast<mjCNumeric*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return text given mjsElement
|
||||||
|
mjsText* mjs_asText(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_TEXT ? &(static_cast<mjCText*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return tuple given mjsElement
|
||||||
|
mjsTuple* mjs_asTuple(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_TUPLE ? &(static_cast<mjCTuple*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return key given mjsElement
|
||||||
|
mjsKey* mjs_asKey(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_KEY ? &(static_cast<mjCKey*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return mesh given mjsElement
|
||||||
|
mjsMesh* mjs_asMesh(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_MESH ? &(static_cast<mjCMesh*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return hfield given mjsElement
|
||||||
|
mjsHField* mjs_asHField(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_HFIELD ? &(static_cast<mjCHField*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return skin given mjsElement
|
||||||
|
mjsSkin* mjs_asSkin(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_SKIN ? &(static_cast<mjCSkin*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return texture given mjsElement
|
||||||
|
mjsTexture* mjs_asTexture(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_TEXTURE ? &(static_cast<mjCTexture*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return material given mjsElement
|
||||||
|
mjsMaterial* mjs_asMaterial(mjsElement* element) {
|
||||||
|
return element->elemtype == mjOBJ_MATERIAL ? &(static_cast<mjCMaterial*>(element)->spec) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// set string
|
// set string
|
||||||
void mjs_setString(mjString* dest, const char* text) {
|
void mjs_setString(mjString* dest, const char* text) {
|
||||||
std::string* str = static_cast<std::string*>(dest);
|
std::string* str = static_cast<std::string*>(dest);
|
||||||
@@ -696,13 +883,6 @@ void mjs_setActivePlugins(mjSpec* s, void* activeplugins) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// compute full inertia
|
|
||||||
const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]) {
|
|
||||||
return FullInertia(quat, inertia, fullinertia);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------- GLOBAL ASSET CACHE -------------------------------
|
// -------------------------- GLOBAL ASSET CACHE -------------------------------
|
||||||
|
|
||||||
void mj_setCacheSize(mjCache cache, std::size_t size) {
|
void mj_setCacheSize(mjCache cache, std::size_t size) {
|
||||||
|
|||||||
+79
-4
@@ -156,7 +156,7 @@ MJAPI mjsKey* mjs_addKey(mjSpec* s);
|
|||||||
MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s);
|
MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s);
|
||||||
|
|
||||||
// Add default.
|
// Add default.
|
||||||
MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id);
|
MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, const mjsDefault* parent);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Add assets ----------------------------------------------------
|
//---------------------------------- Add assets ----------------------------------------------------
|
||||||
@@ -194,6 +194,9 @@ MJAPI mjsMesh* mjs_findMesh(mjSpec* s, const char* name);
|
|||||||
// Find frame by name.
|
// Find frame by name.
|
||||||
MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name);
|
||||||
|
|
||||||
|
// Find keyframe by name.
|
||||||
|
MJAPI mjsKey* mjs_findKeyframe(mjSpec* s, const char* name);
|
||||||
|
|
||||||
// Get default corresponding to an element.
|
// Get default corresponding to an element.
|
||||||
MJAPI mjsDefault* mjs_getDefault(mjsElement* element);
|
MJAPI mjsDefault* mjs_getDefault(mjsElement* element);
|
||||||
|
|
||||||
@@ -215,6 +218,81 @@ MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type);
|
|||||||
// Return body's next child of the same type; return NULL if child is last.
|
// Return body's next child of the same type; return NULL if child is last.
|
||||||
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child);
|
||||||
|
|
||||||
|
// Return spec's first element of selected type.
|
||||||
|
MJAPI mjsElement* mjs_firstElement(mjSpec* s, mjtObj type);
|
||||||
|
|
||||||
|
// Return spec's next element; return NULL if element is last.
|
||||||
|
MJAPI mjsElement* mjs_nextElement(mjSpec* s, mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsBody, or return NULL if the element is not an mjsBody.
|
||||||
|
MJAPI mjsBody* mjs_asBody(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsGeom, or return NULL if the element is not an mjsGeom.
|
||||||
|
MJAPI mjsGeom* mjs_asGeom(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsJoint, or return NULL if the element is not an mjsJoint.
|
||||||
|
MJAPI mjsJoint* mjs_asJoint(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSite, or return NULL if the element is not an mjsSite.
|
||||||
|
MJAPI mjsSite* mjs_asSite(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsCamera, or return NULL if the element is not an mjsCamera.
|
||||||
|
MJAPI mjsCamera* mjs_asCamera(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsLight, or return NULL if the element is not an mjsLight.
|
||||||
|
MJAPI mjsLight* mjs_asLight(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsFrame, or return NULL if the element is not an mjsFrame.
|
||||||
|
MJAPI mjsFrame* mjs_asFrame(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsActuator, or return NULL if the element is not an mjsActuator.
|
||||||
|
MJAPI mjsActuator* mjs_asActuator(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSensor, or return NULL if the element is not an mjsSensor.
|
||||||
|
MJAPI mjsSensor* mjs_asSensor(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsFlex, or return NULL if the element is not an mjsFlex.
|
||||||
|
MJAPI mjsFlex* mjs_asFlex(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsPair, or return NULL if the element is not an mjsPair.
|
||||||
|
MJAPI mjsPair* mjs_asPair(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsEquality, or return NULL if the element is not an mjsEquality.
|
||||||
|
MJAPI mjsEquality* mjs_asEquality(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsExclude, or return NULL if the element is not an mjsExclude.
|
||||||
|
MJAPI mjsExclude* mjs_asExclude(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTendon, or return NULL if the element is not an mjsTendon.
|
||||||
|
MJAPI mjsTendon* mjs_asTendon(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsNumeric, or return NULL if the element is not an mjsNumeric.
|
||||||
|
MJAPI mjsNumeric* mjs_asNumeric(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsText, or return NULL if the element is not an mjsText.
|
||||||
|
MJAPI mjsText* mjs_asText(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTuple, or return NULL if the element is not an mjsTuple.
|
||||||
|
MJAPI mjsTuple* mjs_asTuple(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsKey, or return NULL if the element is not an mjsKey.
|
||||||
|
MJAPI mjsKey* mjs_asKey(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsMesh, or return NULL if the element is not an mjsMesh.
|
||||||
|
MJAPI mjsMesh* mjs_asMesh(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsHField, or return NULL if the element is not an mjsHField.
|
||||||
|
MJAPI mjsHField* mjs_asHField(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsSkin, or return NULL if the element is not an mjsSkin.
|
||||||
|
MJAPI mjsSkin* mjs_asSkin(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsTexture, or return NULL if the element is not an mjsTexture.
|
||||||
|
MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
|
||||||
|
|
||||||
|
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
|
||||||
|
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Attribute setters ---------------------------------------------
|
//---------------------------------- Attribute setters ---------------------------------------------
|
||||||
|
|
||||||
@@ -273,9 +351,6 @@ MJAPI void mjs_setFrame(mjsElement* dest, mjsFrame* frame);
|
|||||||
MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence,
|
||||||
const mjsOrientation* orientation);
|
const mjsOrientation* orientation);
|
||||||
|
|
||||||
// Compute quat and diag inertia from full inertia matrix, return error if any.
|
|
||||||
MJAPI const char* mjs_fullInertia(double quat[4], double inertia[3], const double fullinertia[6]);
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------- Initialization -----------------------------------------------
|
//---------------------------------- Initialization -----------------------------------------------
|
||||||
|
|
||||||
|
|||||||
+17
-16
@@ -31,7 +31,6 @@
|
|||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "cc/array_safety.h"
|
#include "cc/array_safety.h"
|
||||||
#include "engine/engine_io.h"
|
#include "engine/engine_io.h"
|
||||||
#include "engine/engine_util_blas.h"
|
|
||||||
#include "engine/engine_util_errmem.h"
|
#include "engine/engine_util_errmem.h"
|
||||||
#include "engine/engine_util_misc.h"
|
#include "engine/engine_util_misc.h"
|
||||||
#include "user/user_model.h"
|
#include "user/user_model.h"
|
||||||
@@ -428,12 +427,12 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compute volume
|
// compute volume
|
||||||
std::vector<mjtNum> volume(uservert.size()/3);
|
std::vector<double> volume(uservert.size()/3);
|
||||||
mjtNum t = 1;
|
double thickness = 1;
|
||||||
if (dim == 2 && plugin.active) {
|
if (dim == 2 && plugin.active) {
|
||||||
try {
|
try {
|
||||||
mjCPlugin* pplugin = static_cast<mjCPlugin*>(plugin.instance);
|
mjCPlugin* pplugin = static_cast<mjCPlugin*>(plugin.instance);
|
||||||
t = std::stod(pplugin->config_attribs["thickness"], nullptr);
|
thickness = std::stod(pplugin->config_attribs["thickness"], nullptr);
|
||||||
} catch (const std::invalid_argument& e) {
|
} catch (const std::invalid_argument& e) {
|
||||||
return comperr(error, "Invalid thickness attribute", error_sz);
|
return comperr(error, "Invalid thickness attribute", error_sz);
|
||||||
}
|
}
|
||||||
@@ -441,9 +440,9 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int
|
|||||||
if (!userface.empty()) {
|
if (!userface.empty()) {
|
||||||
face = mjXUtil::String2Vector<int>(userface);
|
face = mjXUtil::String2Vector<int>(userface);
|
||||||
for (int j=0; j<face.size()/3; j++) {
|
for (int j=0; j<face.size()/3; j++) {
|
||||||
mjtNum area[3];
|
double area[3];
|
||||||
mjtNum edge1[3];
|
double edge1[3];
|
||||||
mjtNum edge2[3];
|
double edge2[3];
|
||||||
|
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
edge1[i] = uservert[3*face[3*j+1]+i] - uservert[3*face[3*j]+i];
|
edge1[i] = uservert[3*face[3*j+1]+i] - uservert[3*face[3*j]+i];
|
||||||
@@ -452,12 +451,12 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int
|
|||||||
|
|
||||||
mjuu_crossvec(area, edge1, edge2);
|
mjuu_crossvec(area, edge1, edge2);
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
volume[face[3*j+i]] += sqrt(mjuu_dot3(area, area)) / 2 * t;
|
volume[face[3*j+i]] += sqrt(mjuu_dot3(area, area)) / 2 * thickness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i=0; i<uservert.size()/3; i++) {
|
for (int i=0; i<uservert.size()/3; i++) {
|
||||||
volume[i] = 6 * spacing * spacing / 2 * t;
|
volume[i] = 6 * spacing * spacing / 2 * thickness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,7 +753,7 @@ bool mjCComposite::MakeCable(mjCModel* model, mjsBody* body, char* error, int er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create frame
|
// create frame
|
||||||
mjtNum normal[3], prev_quat[4];
|
double normal[3], prev_quat[4];
|
||||||
mjuu_setvec(normal, 0, 1, 0);
|
mjuu_setvec(normal, 0, 1, 0);
|
||||||
mjuu_setvec(prev_quat, 1, 0, 0, 0);
|
mjuu_setvec(prev_quat, 1, 0, 0, 0);
|
||||||
|
|
||||||
@@ -780,10 +779,11 @@ bool mjCComposite::MakeCable(mjCModel* model, mjsBody* body, char* error, int er
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]) {
|
mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix,
|
||||||
|
double normal[3], double prev_quat[4]) {
|
||||||
char txt_geom[100], txt_site[100], txt_slide[100];
|
char txt_geom[100], txt_site[100], txt_slide[100];
|
||||||
char this_body[100], next_body[100], this_joint[100];
|
char this_body[100], next_body[100], this_joint[100];
|
||||||
mjtNum dquat[4], this_quat[4];
|
double dquat[4], this_quat[4];
|
||||||
|
|
||||||
// set flags
|
// set flags
|
||||||
int lastidx = count[0]-2;
|
int lastidx = count[0]-2;
|
||||||
@@ -792,7 +792,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtN
|
|||||||
bool secondlast = ix==lastidx-1;
|
bool secondlast = ix==lastidx-1;
|
||||||
|
|
||||||
// compute edge and tangent vectors
|
// compute edge and tangent vectors
|
||||||
mjtNum edge[3], tprev[3], tnext[3], length_prev = 0;
|
double edge[3], tprev[3], tnext[3], length_prev = 0;
|
||||||
mjuu_setvec(edge, uservert[3*(ix+1)+0]-uservert[3*ix+0],
|
mjuu_setvec(edge, uservert[3*(ix+1)+0]-uservert[3*ix+0],
|
||||||
uservert[3*(ix+1)+1]-uservert[3*ix+1],
|
uservert[3*(ix+1)+1]-uservert[3*ix+1],
|
||||||
uservert[3*(ix+1)+2]-uservert[3*ix+2]);
|
uservert[3*(ix+1)+2]-uservert[3*ix+2]);
|
||||||
@@ -810,7 +810,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtN
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update moving frame
|
// update moving frame
|
||||||
mjtNum length = mju_updateFrame(this_quat, normal, edge, tprev, tnext, first);
|
double length = mjuu_updateFrame(this_quat, normal, edge, tprev, tnext, first);
|
||||||
|
|
||||||
// create body, joint, and geom names
|
// create body, joint, and geom names
|
||||||
if (first) {
|
if (first) {
|
||||||
@@ -845,7 +845,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtN
|
|||||||
mjuu_copyvec(body->quat, this_quat, 4);
|
mjuu_copyvec(body->quat, this_quat, 4);
|
||||||
} else {
|
} else {
|
||||||
mjuu_setvec(body->pos, length_prev, 0, 0);
|
mjuu_setvec(body->pos, length_prev, 0, 0);
|
||||||
mjtNum negquat[4] = {prev_quat[0], -prev_quat[1], -prev_quat[2], -prev_quat[3]};
|
double negquat[4] = {prev_quat[0], -prev_quat[1], -prev_quat[2], -prev_quat[3]};
|
||||||
mjuu_mulquat(dquat, negquat, this_quat);
|
mjuu_mulquat(dquat, negquat, this_quat);
|
||||||
mjuu_copyvec(body->quat, dquat, 4);
|
mjuu_copyvec(body->quat, dquat, 4);
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1091,7 @@ void mjCComposite::BoxProject(double* pos) {
|
|||||||
|
|
||||||
// cylinder
|
// cylinder
|
||||||
else if (type==mjCOMPTYPE_CYLINDER) {
|
else if (type==mjCOMPTYPE_CYLINDER) {
|
||||||
double L0 = mju_max(mju_abs(pos[0]), mju_abs(pos[1]));
|
double L0 = std::max(std::abs(pos[0]), std::abs(pos[1]));
|
||||||
mjuu_normvec(pos, 2);
|
mjuu_normvec(pos, 2);
|
||||||
pos[0] *= size[0]*L0;
|
pos[0] *= size[0]*L0;
|
||||||
pos[1] *= size[1]*L0;
|
pos[1] *= size[1]*L0;
|
||||||
@@ -1156,6 +1156,7 @@ bool mjCComposite::MakeBox(mjCModel* model, mjsBody* body, char* error, int erro
|
|||||||
BoxProject(b->pos);
|
BoxProject(b->pos);
|
||||||
|
|
||||||
// reorient body
|
// reorient body
|
||||||
|
b->alt.type = mjORIENTATION_ZAXIS;
|
||||||
mjuu_copyvec(b->alt.zaxis, b->pos, 3);
|
mjuu_copyvec(b->alt.zaxis, b->pos, 3);
|
||||||
mjuu_normvec(b->alt.zaxis, 3);
|
mjuu_normvec(b->alt.zaxis, 3);
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class mjCComposite {
|
|||||||
std::string initial; // root boundary type
|
std::string initial; // root boundary type
|
||||||
std::vector<float> uservert; // user-specified vertex positions
|
std::vector<float> uservert; // user-specified vertex positions
|
||||||
std::string userface; // connectivity
|
std::string userface; // connectivity
|
||||||
mjtNum size[3]; // rope size (meaning depends on the shape)
|
double size[3]; // rope size (meaning depends on the shape)
|
||||||
mjtCompShape curve[3]; // geometric shape
|
mjtCompShape curve[3]; // geometric shape
|
||||||
|
|
||||||
// body names used in the skin
|
// body names used in the skin
|
||||||
@@ -137,7 +137,7 @@ class mjCComposite {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mjsBody* AddRopeBody(mjCModel* model, mjsBody* body, int ix, int ix1);
|
mjsBody* AddRopeBody(mjCModel* model, mjsBody* body, int ix, int ix1);
|
||||||
mjsBody* AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]);
|
mjsBody* AddCableBody(mjCModel* model, mjsBody* body, int ix, double normal[3], double prev_quat[4]);
|
||||||
|
|
||||||
// temporary skin vectors
|
// temporary skin vectors
|
||||||
void CopyIntoSkin(mjsSkin* skin);
|
void CopyIntoSkin(mjsSkin* skin);
|
||||||
|
|||||||
+16
-20
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -26,13 +27,11 @@
|
|||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
#include <mujoco/mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mujoco/mjplugin.h>
|
#include <mujoco/mjplugin.h>
|
||||||
|
#include <mujoco/mujoco.h>
|
||||||
#include "cc/array_safety.h"
|
#include "cc/array_safety.h"
|
||||||
#include "engine/engine_crossplatform.h"
|
#include "engine/engine_crossplatform.h"
|
||||||
#include "engine/engine_resource.h"
|
#include "engine/engine_resource.h"
|
||||||
#include "engine/engine_util_blas.h"
|
|
||||||
#include "engine/engine_util_errmem.h"
|
#include "engine/engine_util_errmem.h"
|
||||||
#include "engine/engine_util_misc.h"
|
|
||||||
#include "engine/engine_util_spatial.h"
|
|
||||||
#include "user/user_flexcomp.h"
|
#include "user/user_flexcomp.h"
|
||||||
#include <mujoco/mjspec.h>
|
#include <mujoco/mjspec.h>
|
||||||
#include "user/user_model.h"
|
#include "user/user_model.h"
|
||||||
@@ -147,7 +146,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compute orientation
|
// compute orientation
|
||||||
const char* alterr = mjs_resolveOrientation(quat, model->spec.degree, model->spec.euler, &alt);
|
const char* alterr = mjs_resolveOrientation(quat, model->spec.degree, model->spec.eulerseq, &alt);
|
||||||
if (alterr) {
|
if (alterr) {
|
||||||
return comperr(error, alterr, error_sz);
|
return comperr(error, alterr, error_sz);
|
||||||
}
|
}
|
||||||
@@ -250,12 +249,9 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply pose transform to points
|
// apply pose transform to points
|
||||||
mjtNum posn[3], quatn[4];
|
|
||||||
mju_d2n(posn, pos, 3);
|
|
||||||
mju_d2n(quatn, quat, 4);
|
|
||||||
for (int i=0; i < npnt; i++) {
|
for (int i=0; i < npnt; i++) {
|
||||||
mjtNum newp[3], oldp[3] = {point[3*i], point[3*i+1], point[3*i+2]};
|
double newp[3], oldp[3] = {point[3*i], point[3*i+1], point[3*i+2]};
|
||||||
mju_trnVecPose(newp, posn, quatn, oldp);
|
mjuu_trnVecPose(newp, pos, quat, oldp);
|
||||||
point[3*i] = newp[0];
|
point[3*i] = newp[0];
|
||||||
point[3*i+1] = newp[1];
|
point[3*i+1] = newp[1];
|
||||||
point[3*i+2] = newp[2];
|
point[3*i+2] = newp[2];
|
||||||
@@ -570,7 +566,7 @@ bool mjCFlexcomp::MakeGrid(char* error, int error_sz) {
|
|||||||
int quad2tri[2][3] = {{0, 1, 2}, {0, 2, 3}};
|
int quad2tri[2][3] = {{0, 1, 2}, {0, 2, 3}};
|
||||||
|
|
||||||
// add point
|
// add point
|
||||||
mjtNum pos[2] = {spacing[0]*(ix - 0.5*(count[0]-1)),
|
double pos[2] = {spacing[0]*(ix - 0.5*(count[0]-1)),
|
||||||
spacing[1]*(iy - 0.5*(count[1]-1))};
|
spacing[1]*(iy - 0.5*(count[1]-1))};
|
||||||
point.push_back(pos[0]);
|
point.push_back(pos[0]);
|
||||||
point.push_back(pos[1]);
|
point.push_back(pos[1]);
|
||||||
@@ -578,8 +574,8 @@ bool mjCFlexcomp::MakeGrid(char* error, int error_sz) {
|
|||||||
|
|
||||||
// add texture coordinates, if not specified explicitly
|
// add texture coordinates, if not specified explicitly
|
||||||
if (!hastex) {
|
if (!hastex) {
|
||||||
texcoord.push_back(ix/(mjtNum)mjMAX(count[0]-1, 1));
|
texcoord.push_back(ix/(double)std::max(count[0]-1, 1));
|
||||||
texcoord.push_back(iy/(mjtNum)mjMAX(count[1]-1, 1));
|
texcoord.push_back(iy/(double)std::max(count[1]-1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// flip triangles if radial projection is requested
|
// flip triangles if radial projection is requested
|
||||||
@@ -713,7 +709,7 @@ void mjCFlexcomp::BoxProject(double* pos, int ix, int iy, int iz) {
|
|||||||
|
|
||||||
// cylinder
|
// cylinder
|
||||||
else if (type==mjFCOMPTYPE_CYLINDER) {
|
else if (type==mjFCOMPTYPE_CYLINDER) {
|
||||||
double L0 = mjMAX(mju_abs(pos[0]), mju_abs(pos[1]));
|
double L0 = std::max(std::abs(pos[0]), std::abs(pos[1]));
|
||||||
mjuu_normvec(pos, 2);
|
mjuu_normvec(pos, 2);
|
||||||
pos[0] *= size[0]*L0;
|
pos[0] *= size[0]*L0;
|
||||||
pos[1] *= size[1]*L0;
|
pos[1] *= size[1]*L0;
|
||||||
@@ -749,8 +745,8 @@ bool mjCFlexcomp::MakeSquare(char* error, int error_sz) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (int i=0; i < point.size()/3; i++) {
|
for (int i=0; i < point.size()/3; i++) {
|
||||||
mjtNum* pos = point.data() + i*3;
|
double* pos = point.data() + i*3;
|
||||||
double L0 = mjMAX(mju_abs(pos[0]), mju_abs(pos[1]));
|
double L0 = std::max(std::abs(pos[0]), std::abs(pos[1]));
|
||||||
mjuu_normvec(pos, 2);
|
mjuu_normvec(pos, 2);
|
||||||
pos[0] *= size[0]*L0;
|
pos[0] *= size[0]*L0;
|
||||||
pos[1] *= size[1]*L0;
|
pos[1] *= size[1]*L0;
|
||||||
@@ -904,7 +900,7 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load resource
|
// load resource
|
||||||
std::string filename = mjuu_makefullname(mjs_getString(model->spec.modelfiledir),
|
std::string filename = mjuu_combinePaths(mjs_getString(model->spec.modelfiledir),
|
||||||
mjs_getString(model->spec.meshdir), file);
|
mjs_getString(model->spec.meshdir), file);
|
||||||
mjResource* resource = nullptr;
|
mjResource* resource = nullptr;
|
||||||
|
|
||||||
@@ -952,10 +948,10 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) {
|
|||||||
// copy faces
|
// copy faces
|
||||||
element = mesh.face_;
|
element = mesh.face_;
|
||||||
|
|
||||||
// copy vertices, convert from float to mjtNum
|
// copy vertices, convert from float to double
|
||||||
point = vector<mjtNum> (mesh.nvert()*3);
|
point = vector<double> (mesh.nvert()*3);
|
||||||
for (int i=0; i < mesh.nvert()*3; i++) {
|
for (int i=0; i < mesh.nvert()*3; i++) {
|
||||||
point[i] = (mjtNum) mesh.vert_[i];
|
point[i] = (double) mesh.vert_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1003,7 +999,7 @@ bool mjCFlexcomp::MakeGMSH(mjCModel* model, char* error, int error_sz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open resource
|
// open resource
|
||||||
std::string filename = mjuu_makefullname(mjs_getString(model->spec.modelfiledir),
|
std::string filename = mjuu_combinePaths(mjs_getString(model->spec.modelfiledir),
|
||||||
mjs_getString(model->spec.meshdir), file);
|
mjs_getString(model->spec.meshdir), file);
|
||||||
mjResource* resource = nullptr;
|
mjResource* resource = nullptr;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user