From 7a06bcfdaf109ef09a77f80a9ebacad11662bd1f Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Fri, 7 Jun 2024 22:27:10 -0700 Subject: [PATCH] Make model editing API public, fixes #364 Still missing: - Detailed documentation. - Python bindings. PiperOrigin-RevId: 641445626 Change-Id: I20e67b707cf1bebae7e0cc94d17f7b76a89171f0 --- CMakeLists.txt | 1 + doc/APIreference/APItypes.rst | 429 +++- doc/APIreference/functions.rst | 952 +++++++- doc/APIreference/functions_override.rst | 9 +- doc/changelog.rst | 29 +- doc/css/theme_overrides.css | 8 + doc/includes/references.h | 737 +++++- doc/modeling.rst | 28 +- doc/overview.rst | 38 +- doc/programming/index.rst | 21 +- doc/programming/modeledit.rst | 44 + doc/programming/simulation.rst | 4 +- include/mujoco/mjspec.h | 763 ++++++ include/mujoco/mujoco.h | 371 ++- introspect/codegen/generate_structs.py | 2 +- introspect/enums.py | 63 + introspect/functions.py | 1951 ++++++++++++++- introspect/structs.py | 2991 +++++++++++++++++++++++ src/user/user_api.cc | 28 +- src/user/user_api.h | 757 +----- src/user/user_composite.cc | 2 +- src/user/user_composite.h | 2 +- src/user/user_flexcomp.cc | 6 +- src/user/user_flexcomp.h | 2 +- src/user/user_init.c | 1 + src/user/user_mesh.cc | 7 +- src/user/user_model.cc | 3 +- src/user/user_model.h | 4 +- src/user/user_objects.cc | 49 +- src/user/user_objects.h | 8 +- src/xml/xml.cc | 6 +- src/xml/xml.h | 2 +- src/xml/xml_api.cc | 14 +- src/xml/xml_api.h | 2 +- src/xml/xml_base.cc | 4 +- src/xml/xml_base.h | 2 +- src/xml/xml_native_reader.cc | 2 +- src/xml/xml_native_reader.h | 2 +- src/xml/xml_native_writer.cc | 3 +- src/xml/xml_native_writer.h | 2 +- src/xml/xml_urdf.cc | 1 + src/xml/xml_urdf.h | 2 +- test/user/user_api_test.cc | 74 +- test/xml/xml_api_test.cc | 18 +- test/xml/xml_native_reader_test.cc | 4 +- unity/Runtime/Bindings/MjBindings.cs | 40 +- 46 files changed, 8508 insertions(+), 980 deletions(-) create mode 100644 doc/programming/modeledit.rst create mode 100644 include/mujoco/mjspec.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c13da243..e1de2b0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ set(MUJOCO_HEADERS include/mujoco/mjmodel.h include/mujoco/mjplugin.h include/mujoco/mjrender.h + include/mujoco/mjspec.h include/mujoco/mjthread.h include/mujoco/mjtnum.h include/mujoco/mjui.h diff --git a/doc/APIreference/APItypes.rst b/doc/APIreference/APItypes.rst index ee8de505..5ee07e6a 100644 --- a/doc/APIreference/APItypes.rst +++ b/doc/APIreference/APItypes.rst @@ -9,9 +9,11 @@ MuJoCo defines a large number of types: - Enums used in :ref:`mjModel`. - Enums used in :ref:`mjData`. - - Abstract :ref:`visualization enums`. + - Enums for abstract :ref:`visualization`. - Enums used by the :ref:`openGL renderer`. - Enums used by the :ref:`mjUI` user interface package. + - Enums used by :ref:`engine plugins`. + - Enums used for :ref:`procedural model manipulation`. Note that the API does not use these enum types directly. Instead it uses ints, and the documentation/comments state that certain ints correspond to certain enum types. This is because we want the API to be compiler-independent, and @@ -31,9 +33,10 @@ MuJoCo defines a large number of types: - Structs for :ref:`abstract visualization`. - Structs used by the :ref:`openGL renderer`. - Structs used by the :ref:`UI framework`. + - Structs used for :ref:`procedural model manipulation`. - Structs used by :ref:`engine plugins`. -- Several :ref:`tyFunction` for user-defined callbacks. +- Several :ref:`function types` for user-defined callbacks. - :ref:`tyNotes` regarding specific data structures that require detailed description. @@ -43,7 +46,7 @@ MuJoCo defines a large number of types: Primitive types --------------- -The two types below are defined in `mjtnum.h `_. +The two types below are defined in `mjtnum.h `__. .. _mjtNum: @@ -89,13 +92,14 @@ Byte type used to represent boolean variables. Enum types ---------- +All enum types use the ``mjt`` prefix. .. _tyModelEnums: Model ^^^^^ -The enums below are defined in `mjmodel.h `_. +The enums below are defined in `mjmodel.h `__. .. _mjtDisableBit: @@ -333,7 +337,7 @@ These are the possible sensor data types, used in ``mjData.sensor_datatype``. Data ^^^^ -The enums below are defined in `mjdata.h `_. +The enums below are defined in `mjdata.h `__. @@ -376,7 +380,7 @@ Timer types. The number of timer types is given by ``mjNTIMER`` which is also th Visualization ^^^^^^^^^^^^^ -The enums below are defined in `mjvisualize.h `_. +The enums below are defined in `mjvisualize.h `__. .. _mjtCatBit: @@ -480,7 +484,7 @@ These are the possible stereo rendering types. They are used in ``mjvScene.stere Rendering ^^^^^^^^^ -The enums below are defined in `mjrender.h `_. +The enums below are defined in `mjrender.h `__. .. _mjtGridPos: @@ -542,7 +546,7 @@ These are the possible font types. User Interface ^^^^^^^^^^^^^^ -The enums below are defined in `mjui.h `_. +The enums below are defined in `mjui.h `__. .. _mjtButton: @@ -574,13 +578,74 @@ Item types used in the UI framework. .. mujoco-include:: mjtItem +.. _tySpecEnums: + +Spec +^^^^ + +The enums below are defined in `mjspec.h `__. + +.. _mjtGeomInertia: + +mjtGeomInertia +~~~~~~~~~~~~~~ + +Type of inertia inference. + +.. mujoco-include:: mjtGeomInertia + +.. _mjtBuiltin: + +mjtBuiltin +~~~~~~~~~~ + +Type of built-in procedural texture. + +.. mujoco-include:: mjtBuiltin + +.. _mjtMark: + +mjtMark +~~~~~~~ + +Mark type for procedural textures. + +.. mujoco-include:: mjtMark + +.. _mjtLimited: + +mjtLimited +~~~~~~~~~~ + +Type of limit specification. + +.. mujoco-include:: mjtLimited + +.. _mjtInertiaFromGeom: + +mjtInertiaFromGeom +~~~~~~~~~~~~~~~~~~ + +Whether to infer body inertias from child geoms. + +.. mujoco-include:: mjtInertiaFromGeom + +.. _mjtOrientation: + +mjtOrientation +~~~~~~~~~~~~~~ + +Type of orientation specifier. + +.. mujoco-include:: mjtOrientation + .. _tyPluginEnums: Plugins ^^^^^^^ -The enums below are defined in `mjplugin.h `_. +The enums below are defined in `mjplugin.h `__. See :ref:`exPlugin` for details. @@ -994,6 +1059,348 @@ is initialized, others change at runtime. .. mujoco-include:: mjUI + +.. _tySpecStructure: + +mjSpec +^^^^^^ + +The strucs below are defined in `mjspec.h `__ +and, with the exception of the top level :ref:`mjSpec` struct, begin with the ``mjs`` prefix. +For more details, see the :doc:`Model Editing <../programming/modeledit>` chapter. + +.. _mjSpec: + +mjSpec +~~~~~~ + +Model specification. + +.. mujoco-include:: mjSpec + + +.. _mjsElement: + +mjsElement +~~~~~~~~~~ + +Special type corresponding to any element. + +.. mujoco-include:: mjsElement + + +.. _mjsOrientation: + +mjsOrientation +~~~~~~~~~~~~~~ + +Alternative orientation specifiers. + +.. mujoco-include:: mjsOrientation + + +.. _mjsBody: + +mjsBody +~~~~~~~ + +Body specification. + +.. mujoco-include:: mjsBody + + +.. _mjsFrame: + +mjsFrame +~~~~~~~~ + +Frame specification. + +.. mujoco-include:: mjsFrame + + +.. _mjsJoint: + +mjsJoint +~~~~~~~~ + +Joint specification. + +.. mujoco-include:: mjsJoint + + +.. _mjsGeom: + +mjsGeom +~~~~~~~ + +Geom specification. + +.. mujoco-include:: mjsGeom + + +.. _mjsSite: + +mjsSite +~~~~~~~ + +Site specification. + +.. mujoco-include:: mjsSite + + +.. _mjsCamera: + +mjsCamera +~~~~~~~~~ + +Camera specification. + +.. mujoco-include:: mjsCamera + + +.. _mjsLight: + +mjsLight +~~~~~~~~ + +Light specification. + +.. mujoco-include:: mjsLight + + +.. _mjsFlex: + +mjsFlex +~~~~~~~ + +Flex specification. + +.. mujoco-include:: mjsFlex + + +.. _mjsMesh: + +mjsMesh +~~~~~~~ + +Mesh specification. + +.. mujoco-include:: mjsMesh + + +.. _mjsHField: + +mjsHField +~~~~~~~~~ + +Height field specification. + +.. mujoco-include:: mjsHField + + +.. _mjsSkin: + +mjsSkin +~~~~~~~ + +Skin specification. + +.. mujoco-include:: mjsSkin + + +.. _mjsTexture: + +mjsTexture +~~~~~~~~~~ + +Texture specification. + +.. mujoco-include:: mjsTexture + + +.. _mjsMaterial: + +mjsMaterial +~~~~~~~~~~~ + +Material specification. + +.. mujoco-include:: mjsMaterial + + +.. _mjsPair: + +mjsPair +~~~~~~~ + +Pair specification. + +.. mujoco-include:: mjsPair + + +.. _mjsExclude: + +mjsExclude +~~~~~~~~~~ + +Exclude specification. + +.. mujoco-include:: mjsExclude + + +.. _mjsEquality: + +mjsEquality +~~~~~~~~~~~ + +Equality specification. + +.. mujoco-include:: mjsEquality + + +.. _mjsTendon: + +mjsTendon +~~~~~~~~~ + +Tendon specification. + +.. mujoco-include:: mjsTendon + + +.. _mjsWrap: + +mjsWrap +~~~~~~~ + +Wrapping object specification. + +.. mujoco-include:: mjsWrap + + +.. _mjsActuator: + +mjsActuator +~~~~~~~~~~~ + +Actuator specification. + +.. mujoco-include:: mjsActuator + + +.. _mjsSensor: + +mjsSensor +~~~~~~~~~ + +Sensor specification. + +.. mujoco-include:: mjsSensor + + +.. _mjsNumeric: + +mjsNumeric +~~~~~~~~~~ + +Custom numeric field specification. + +.. mujoco-include:: mjsNumeric + + +.. _mjsText: + +mjsText +~~~~~~~ + +Custom text specification. + +.. mujoco-include:: mjsText + + +.. _mjsTuple: + +mjsTuple +~~~~~~~~ + +Tuple specification. + +.. mujoco-include:: mjsTuple + + +.. _mjsKey: + +mjsKey +~~~~~~ + +Keyframe specification. + +.. mujoco-include:: mjsKey + + +.. _mjsDefault: + +mjsDefault +~~~~~~~~~~ + +Default specification. + +.. mujoco-include:: mjsDefault + + +.. _mjsPlugin: + +mjsPlugin +~~~~~~~~~ + +Plugin specification. + +.. mujoco-include:: mjsPlugin + + +.. _mjString: + +.. _mjStringVec: + +.. _mjIntVec: + +.. _mjIntVecVec: + +.. _mjFloatVec: + +.. _mjFloatVecVec: + +.. _mjDoubleVec: + +Array handles +~~~~~~~~~~~~~ + +Explain how handles work. + +.. code-block:: C++ + + #ifdef __cplusplus + // C++: defined to be compatible with corresponding std types + using mjString = std::string; + using mjStringVec = std::vector; + using mjIntVec = std::vector; + using mjIntVecVec = std::vector>; + using mjFloatVec = std::vector; + using mjFloatVecVec = std::vector>; + using mjDoubleVec = std::vector; + #else + // C: opaque types + typedef void mjString; + typedef void mjStringVec; + typedef void mjIntVec; + typedef void mjIntVecVec; + typedef void mjFloatVec; + typedef void mjFloatVecVec; + typedef void mjDoubleVec; + #endif + + .. _tyPluginStructure: Plugins @@ -1028,8 +1435,8 @@ Function types -------------- MuJoCo callbacks have corresponding function types. They are defined in `mjdata.h -`_ and in `mjui.h -`_. The actual callback functions are documented +`__ and in `mjui.h +`__. The actual callback functions are documented in the :doc:`globals` page. diff --git a/doc/APIreference/functions.rst b/doc/APIreference/functions.rst index 7bc60256..951795ee 100644 --- a/doc/APIreference/functions.rst +++ b/doc/APIreference/functions.rst @@ -22,6 +22,42 @@ Parse XML file in MJCF or URDF format, compile it, return low-level model. If vfs is not NULL, look up files in vfs before reading from disk. If error is not NULL, it must have size error_sz. +.. _mj_parseXML: + +mj_parseXML +~~~~~~~~~~~ + +.. mujoco-include:: mj_parseXML + +Parse spec from XML file. + +.. _mj_parseXMLString: + +mj_parseXMLString +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_parseXMLString + +Parse spec from XML string. + +.. _mj_compile: + +mj_compile +~~~~~~~~~~ + +.. mujoco-include:: mj_compile + +Compile spec to model. + +.. _mj_recompile: + +mj_recompile +~~~~~~~~~~~~ + +.. mujoco-include:: mj_recompile + +Recompile spec to model, preserving the state. + .. _mj_saveLastXML: mj_saveLastXML @@ -41,14 +77,32 @@ mj_freeLastXML Free last XML model if loaded. Called internally at each load. -.. _mj_printSchema: +.. _mj_copyBack: -mj_printSchema -~~~~~~~~~~~~~~ +mj_copyBack +~~~~~~~~~~~ -.. mujoco-include:: mj_printSchema +.. mujoco-include:: mj_copyBack -Print internal XML schema as plain text or HTML, with style-padding or `` ``. +Copy (possibly modified) model fields back into spec. + +.. _mj_saveXMLString: + +mj_saveXMLString +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_saveXMLString + +Save spec to XML string, return 1 on success, 0 otherwise. + +.. _mj_saveXML: + +mj_saveXML +~~~~~~~~~~ + +.. mujoco-include:: mj_saveXML + +Save spec to XML file, return 1 on success, 0 otherwise. .. _Mainsimulation: @@ -954,8 +1008,8 @@ If ``cost`` is not ``NULL``, set ``*cost = s(jar)`` where ``jar = Jac*qacc - are .. _Raycollisions: -Ray collisions -^^^^^^^^^^^^^^ +Ray casting +^^^^^^^^^^^ Ray collisions, also known as ray casting, find the distance ``x`` of a ray's intersection with a geom, where a ray is a line emanating from the 3D point ``p`` in the direction ``v`` i.e., ``(p + x*v, x >= 0)``. All functions in this @@ -1105,6 +1159,15 @@ mju_printMatSparse Print sparse matrix to screen. +.. _mj_printSchema: + +mj_printSchema +~~~~~~~~~~~~~~ + +.. mujoco-include:: mj_printSchema + +Print internal XML schema as plain text or HTML, with style-padding or `` ``. + .. _Virtualfilesystem: Virtual file system @@ -1408,6 +1471,33 @@ mj_setLengthRange Set actuator_lengthrange for specified actuator; return 1 if ok, 0 if error. +.. _mj_makeSpec: + +mj_makeSpec +~~~~~~~~~~~ + +.. mujoco-include:: mj_makeSpec + +Create empty spec. + +.. _mj_copySpec: + +mj_copySpec +~~~~~~~~~~~ + +.. mujoco-include:: mj_copySpec + +Copy spec. + +.. _mj_deleteSpec: + +mj_deleteSpec +~~~~~~~~~~~~~ + +.. mujoco-include:: mj_deleteSpec + +Free memory allocation in mjSpec. + .. _Interaction: Interaction @@ -2106,7 +2196,7 @@ mjui_render This function is called in the screen refresh loop. It copies the offscreen OpenGL buffer to the window framebuffer. If there are multiple UIs in the application, it should be called once for each UI. Thus ``mjui_render`` is called all the -time, while :ref:`mjui_update` is called only when changes in the UI take place. +time, while :ref:`mjui_update` is called only when changes in the UI take place. dsffsdg .. _Errorandmemory: @@ -2212,6 +2302,24 @@ mju_writeLog Write [datetime, type: message] to MUJOCO_LOG.TXT. +.. _mjs_getError: + +mjs_getError +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getError + +Get compiler error message from spec. + +.. _mjs_isWarning: + +mjs_isWarning +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_isWarning + +Return 1 if compiler error is a warning. + .. _Standardmath: Standard math @@ -3359,7 +3467,7 @@ Finite-differenced discrete-time transition matrices. Letting :math:`x, u` denote the current :ref:`state` and :ref:`control` vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor -values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`. +values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)` :ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing. These matrices and their dimensions are: @@ -3453,6 +3561,9 @@ to the inputs. Below, :math:`\bar q` denotes the pre-modified quaternion: Note that derivatives depend only on :math:`h` and :math:`v` (in fact, on :math:`s = h v`). All outputs are optional. + +These functions provide high level manipulation for :ref:`mjSpec` structs, which represent an uncompiled :ref:`mjModel`. + .. _Plugins-api: Plugins @@ -3558,8 +3669,8 @@ If invalid slot number, return NULL. .. _Thread: -Thread -^^^^^^ +Threads +^^^^^^^ .. _mju_threadPoolCreate: mju_threadPoolCreate @@ -3614,3 +3725,822 @@ mju_taskJoin Wait for a task to complete. +.. _Attachment: + +Attachment +^^^^^^^^^^ +.. _mjs_attachBody: + +mjs_attachBody +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_attachBody + +Attach child body to a parent frame, return 0 on success. + +.. _mjs_attachFrame: + +mjs_attachFrame +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_attachFrame + +Attach child frame to a parent body, return 0 on success. + +.. _mjs_detachBody: + +mjs_detachBody +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_detachBody + +Detach body from mjSpec, remove all references and delete the body, return 0 on success. + +.. _AddTreeElements: + +Tree elements +^^^^^^^^^^^^^ +.. _mjs_addBody: + +mjs_addBody +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addBody + +Add child body to body, return child. + +.. _mjs_addSite: + +mjs_addSite +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addSite + +Add site to body, return site spec. + +.. _mjs_addJoint: + +mjs_addJoint +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addJoint + +Add joint to body. + +.. _mjs_addFreeJoint: + +mjs_addFreeJoint +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addFreeJoint + +Add freejoint to body. + +.. _mjs_addGeom: + +mjs_addGeom +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addGeom + +Add geom to body. + +.. _mjs_addCamera: + +mjs_addCamera +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addCamera + +Add camera to body. + +.. _mjs_addLight: + +mjs_addLight +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addLight + +Add light to body. + +.. _mjs_addFrame: + +mjs_addFrame +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addFrame + +Add frame to body. + +.. _mjs_delete: + +mjs_delete +~~~~~~~~~~ + +.. mujoco-include:: mjs_delete + +Delete object corresponding to the given element. + +.. _AddNonTreeElements: + +Non-tree elements +^^^^^^^^^^^^^^^^^ +.. _mjs_addActuator: + +mjs_addActuator +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addActuator + +Add actuator. + +.. _mjs_addSensor: + +mjs_addSensor +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addSensor + +Add sensor. + +.. _mjs_addFlex: + +mjs_addFlex +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addFlex + +Add flex. + +.. _mjs_addPair: + +mjs_addPair +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addPair + +Add contact pair. + +.. _mjs_addExclude: + +mjs_addExclude +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addExclude + +Add excluded body pair. + +.. _mjs_addEquality: + +mjs_addEquality +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addEquality + +Add equality. + +.. _mjs_addTendon: + +mjs_addTendon +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addTendon + +Add tendon. + +.. _mjs_wrapSite: + +mjs_wrapSite +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_wrapSite + +Wrap site using tendon. + +.. _mjs_wrapGeom: + +mjs_wrapGeom +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_wrapGeom + +Wrap geom using tendon. + +.. _mjs_wrapJoint: + +mjs_wrapJoint +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_wrapJoint + +Wrap joint using tendon. + +.. _mjs_wrapPulley: + +mjs_wrapPulley +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_wrapPulley + +Wrap pulley using tendon. + +.. _mjs_addNumeric: + +mjs_addNumeric +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addNumeric + +Add numeric. + +.. _mjs_addText: + +mjs_addText +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addText + +Add text. + +.. _mjs_addTuple: + +mjs_addTuple +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addTuple + +Add tuple. + +.. _mjs_addKey: + +mjs_addKey +~~~~~~~~~~ + +.. mujoco-include:: mjs_addKey + +Add keyframe. + +.. _mjs_addPlugin: + +mjs_addPlugin +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addPlugin + +Add plugin. + +.. _mjs_addDefault: + +mjs_addDefault +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addDefault + +Add default. + +.. _AddAssets: + +Assets +^^^^^^ +.. _mjs_addMesh: + +mjs_addMesh +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addMesh + +Add mesh. + +.. _mjs_addHField: + +mjs_addHField +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addHField + +Add height field. + +.. _mjs_addSkin: + +mjs_addSkin +~~~~~~~~~~~ + +.. mujoco-include:: mjs_addSkin + +Add skin. + +.. _mjs_addTexture: + +mjs_addTexture +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addTexture + +Add texture. + +.. _mjs_addMaterial: + +mjs_addMaterial +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_addMaterial + +Add material. + +.. _FindAndGetUtilities: + +Find and get utilities +^^^^^^^^^^^^^^^^^^^^^^ +.. _mjs_getSpec: + +mjs_getSpec +~~~~~~~~~~~ + +.. mujoco-include:: mjs_getSpec + +Get spec from body. + +.. _mjs_findBody: + +mjs_findBody +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_findBody + +Find body in model by name. + +.. _mjs_findChild: + +mjs_findChild +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_findChild + +Find child body by name. + +.. _mjs_findMesh: + +mjs_findMesh +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_findMesh + +Find mesh by name. + +.. _mjs_findFrame: + +mjs_findFrame +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_findFrame + +Find frame by name. + +.. _mjs_getDefault: + +mjs_getDefault +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getDefault + +Get default corresponding to an element. + +.. _mjs_findDefault: + +mjs_findDefault +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_findDefault + +Find default in model by class name. + +.. _mjs_getSpecDefault: + +mjs_getSpecDefault +~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getSpecDefault + +Get global default from model. + +.. _mjs_getId: + +mjs_getId +~~~~~~~~~ + +.. mujoco-include:: mjs_getId + +Get element id. + +.. _mjs_firstChild: + +mjs_firstChild +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_firstChild + +Return body's first child of given type. + +.. _mjs_nextChild: + +mjs_nextChild +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_nextChild + +Return body's next child of the same type; return NULL if child is last. + +.. _AttributeSetters: + +Attribute setters +^^^^^^^^^^^^^^^^^ +.. _mjs_setString: + +mjs_setString +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setString + +Copy text to string. + +.. _mjs_setStringVec: + +mjs_setStringVec +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setStringVec + +Split text to entries and copy to string vector. + +.. _mjs_setInStringVec: + +mjs_setInStringVec +~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setInStringVec + +Set entry in string vector. + +.. _mjs_appendString: + +mjs_appendString +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_appendString + +Append text entry to string vector. + +.. _mjs_setInt: + +mjs_setInt +~~~~~~~~~~ + +.. mujoco-include:: mjs_setInt + +Copy int array to vector. + +.. _mjs_appendIntVec: + +mjs_appendIntVec +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_appendIntVec + +Append int array to vector of arrays. + +.. _mjs_setFloat: + +mjs_setFloat +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setFloat + +Copy float array to vector. + +.. _mjs_appendFloatVec: + +mjs_appendFloatVec +~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_appendFloatVec + +Append float array to vector of arrays. + +.. _mjs_setDouble: + +mjs_setDouble +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setDouble + +Copy double array to vector. + +.. _mjs_setPluginAttributes: + +mjs_setPluginAttributes +~~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setPluginAttributes + +Set plugin attributes. + +.. _AttributeGetters: + +Attribute getters +^^^^^^^^^^^^^^^^^ +.. _mjs_getString: + +mjs_getString +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getString + +Get string contents. + +.. _mjs_getDouble: + +mjs_getDouble +~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_getDouble + +Get double array contents and optionally its size. + +.. _SpecUtilities: + +Spec utilities +^^^^^^^^^^^^^^ +.. _mjs_setActivePlugins: + +mjs_setActivePlugins +~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setActivePlugins + +Set active plugins. + +.. _mjs_setDefault: + +mjs_setDefault +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setDefault + +Set element's default. + +.. _mjs_setFrame: + +mjs_setFrame +~~~~~~~~~~~~ + +.. mujoco-include:: mjs_setFrame + +Set element's enlcosing frame. + +.. _mjs_resolveOrientation: + +mjs_resolveOrientation +~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_resolveOrientation + +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: + +Element initialization +^^^^^^^^^^^^^^^^^^^^^^ +.. _mjs_defaultSpec: + +mjs_defaultSpec +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultSpec + +Default spec attributes. + +.. _mjs_defaultOrientation: + +mjs_defaultOrientation +~~~~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultOrientation + +Default orientation attributes. + +.. _mjs_defaultBody: + +mjs_defaultBody +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultBody + +Default body attributes. + +.. _mjs_defaultFrame: + +mjs_defaultFrame +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultFrame + +Default frame attributes. + +.. _mjs_defaultJoint: + +mjs_defaultJoint +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultJoint + +Default joint attributes. + +.. _mjs_defaultGeom: + +mjs_defaultGeom +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultGeom + +Default geom attributes. + +.. _mjs_defaultSite: + +mjs_defaultSite +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultSite + +Default site attributes. + +.. _mjs_defaultCamera: + +mjs_defaultCamera +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultCamera + +Default camera attributes. + +.. _mjs_defaultLight: + +mjs_defaultLight +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultLight + +Default light attributes. + +.. _mjs_defaultFlex: + +mjs_defaultFlex +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultFlex + +Default flex attributes. + +.. _mjs_defaultMesh: + +mjs_defaultMesh +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultMesh + +Default mesh attributes. + +.. _mjs_defaultHField: + +mjs_defaultHField +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultHField + +Default height field attributes. + +.. _mjs_defaultSkin: + +mjs_defaultSkin +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultSkin + +Default skin attributes. + +.. _mjs_defaultTexture: + +mjs_defaultTexture +~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultTexture + +Default texture attributes. + +.. _mjs_defaultMaterial: + +mjs_defaultMaterial +~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultMaterial + +Default material attributes. + +.. _mjs_defaultPair: + +mjs_defaultPair +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultPair + +Default pair attributes. + +.. _mjs_defaultEquality: + +mjs_defaultEquality +~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultEquality + +Default equality attributes. + +.. _mjs_defaultTendon: + +mjs_defaultTendon +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultTendon + +Default tendon attributes. + +.. _mjs_defaultActuator: + +mjs_defaultActuator +~~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultActuator + +Default actuator attributes. + +.. _mjs_defaultSensor: + +mjs_defaultSensor +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultSensor + +Default sensor attributes. + +.. _mjs_defaultNumeric: + +mjs_defaultNumeric +~~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultNumeric + +Default numeric attributes. + +.. _mjs_defaultText: + +mjs_defaultText +~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultText + +Default text attributes. + +.. _mjs_defaultTuple: + +mjs_defaultTuple +~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultTuple + +Default tuple attributes. + +.. _mjs_defaultKey: + +mjs_defaultKey +~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultKey + +Default keyframe attributes. + +.. _mjs_defaultPlugin: + +mjs_defaultPlugin +~~~~~~~~~~~~~~~~~ + +.. mujoco-include:: mjs_defaultPlugin + +Default plugin attributes. + diff --git a/doc/APIreference/functions_override.rst b/doc/APIreference/functions_override.rst index 9f39042d..cb212686 100644 --- a/doc/APIreference/functions_override.rst +++ b/doc/APIreference/functions_override.rst @@ -312,7 +312,7 @@ depending on which UI item was modified and what the state of that item is after This function is called in the screen refresh loop. It copies the offscreen OpenGL buffer to the window framebuffer. If there are multiple UIs in the application, it should be called once for each UI. Thus ``mjui_render`` is called all the -time, while :ref:`mjui_update` is called only when changes in the UI take place. +time, while :ref:`mjui_update` is called only when changes in the UI take place. dsffsdg @@ -545,7 +545,7 @@ Finite-differenced discrete-time transition matrices. Letting :math:`x, u` denote the current :ref:`state` and :ref:`control` vector in an mjData instance, and letting :math:`y, s` denote the next state and sensor -values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)`. +values, the top-level :ref:`mj_step` function computes :math:`(x,u) \rightarrow (y,s)` :ref:`mjd_transitionFD` computes the four associated Jacobians using finite-differencing. These matrices and their dimensions are: @@ -623,3 +623,8 @@ to the inputs. Below, :math:`\bar q` denotes the pre-modified quaternion: Note that derivatives depend only on :math:`h` and :math:`v` (in fact, on :math:`s = h v`). All outputs are optional. + +.. _SpecManip: + +These functions provide high level manipulation for :ref:`mjSpec` structs, which represent an uncompiled :ref:`mjModel`. + diff --git a/doc/changelog.rst b/doc/changelog.rst index 2e42197a..c265aa27 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,16 +7,21 @@ Upcoming version (not yet released) General ^^^^^^^ +1. Added a new API for :doc:`procedural model manipulation`. Fixes :github:issue:`364`. + Still missing: + + - Detailed documentation. + - Python bindings. + +2. Added :ref:`maxhullvert`, the maximum number of vertices in a mesh's convex hull. -1. Added :ref:`maxhullvert`, the maximum number of vertices in a mesh's convex hull. MJX ~~~ -2. Added support for :ref:`elliptic friction cones`. -3. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings. -4. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients. - +3. Added support for :ref:`elliptic friction cones`. +4. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings. +5. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients. Version 3.1.6 (Jun 3, 2024) --------------------------- @@ -731,13 +736,13 @@ General Previously, the smooth part consisted of two stitched quadratics, once continuously differentiable. It is now a single quintic, twice continuously differentiable: - .. math:: - s(x) = - \begin{cases} - 0, & & x \le 0 \\ - 6x^5 - 15x^4 + 10x^3, & 0 \lt & x \lt 1 \\ - 1, & 1 \le & x \qquad - \end{cases} + .. math:: + s(x) = + \begin{cases} + 0, & & x \le 0 \\ + 6x^5 - 15x^4 + 10x^3, & 0 \lt & x \lt 1 \\ + 1, & 1 \le & x \qquad + \end{cases} 17. Added optional :ref:`tausmooth` attribute to muscle actuators. When positive, the time-constant :math:`\tau` of muscle activation/deactivation uses :ref:`mju_sigmoid` to transition smoothly diff --git a/doc/css/theme_overrides.css b/doc/css/theme_overrides.css index 6b607bda..e51e4eb0 100644 --- a/doc/css/theme_overrides.css +++ b/doc/css/theme_overrides.css @@ -266,6 +266,14 @@ dt .at { margin-bottom: 0.3em; } +/* Adjust margins around code blocks */ +.highlight pre { + margin-top: -0.3em; + margin-bottom: -0.3em; + margin-left: -0.5em; + margin-right: -0.5em; +} + details summary { font-weight: 600; } diff --git a/doc/includes/references.h b/doc/includes/references.h index c85c07eb..253ced07 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -1598,6 +1598,637 @@ struct mjrContext_ { // custom OpenGL context int readDepthMap; // depth mapping: mjDEPTH_ZERONEAR or mjDEPTH_ZEROFAR }; typedef struct mjrContext_ mjrContext; +typedef enum mjtGeomInertia_ { // type of inertia inference + mjINERTIA_VOLUME, // mass distributed in the volume + mjINERTIA_SHELL, // mass distributed on the surface +} mjtGeomInertia; +typedef enum mjtBuiltin_ { // type of built-in procedural texture + mjBUILTIN_NONE = 0, // no built-in texture + mjBUILTIN_GRADIENT, // gradient: rgb1->rgb2 + mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2 + mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down +} mjtBuiltin; +typedef enum mjtMark_ { // mark type for procedural textures + mjMARK_NONE = 0, // no mark + mjMARK_EDGE, // edges + mjMARK_CROSS, // cross + mjMARK_RANDOM // random dots +} mjtMark; +typedef enum mjtLimited_ { // type of limit specification + mjLIMITED_FALSE = 0, // not limited + mjLIMITED_TRUE, // limited + mjLIMITED_AUTO, // limited inferred from presence of range +} mjtLimited; +typedef enum mjtInertiaFromGeom_ { // whether to infer body inertias from child geoms + mjINERTIAFROMGEOM_FALSE = 0, // do not use; inertial element required + mjINERTIAFROMGEOM_TRUE, // always use; overwrite inertial element + mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing +} mjtInertiaFromGeom; +typedef enum mjtOrientation_ { // type of orientation specifier + mjORIENTATION_QUAT = 0, // quaternion + mjORIENTATION_AXISANGLE, // axis and angle + mjORIENTATION_XYAXES, // x and y axes + mjORIENTATION_ZAXIS, // z axis (minimal rotation) + mjORIENTATION_EULER, // Euler angles +} mjtOrientation; +typedef struct mjsElement_ { // element type, do not modify + mjtObj elemtype; // element type +} mjsElement; +typedef struct mjSpec_ { // model specification + mjsElement* element; // element type + mjString* modelname; // model name + + // compiler settings + mjtByte autolimits; // infer "limited" attribute based on range + double boundmass; // enforce minimum body mass + double boundinertia; // enforce minimum body diagonal inertia + double settotalmass; // rescale masses and inertias; <=0: ignore + mjtByte balanceinertia; // automatically impose A + B >= C rule + mjtByte strippath; // automatically strip paths from mesh files + mjtByte fitaabb; // meshfit to aabb instead of inertia box + mjtByte degree; // angles in radians or degrees + char euler[3]; // sequence for euler rotations + mjString* meshdir; // mesh and hfield directory + mjString* texturedir; // texture directory + mjtByte discardvisual; // discard visual geoms in parser + mjtByte convexhull; // compute mesh convex hulls + mjtByte usethread; // use multiple threads to speed up compiler + mjtByte fusestatic; // fuse static bodies with parent + int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom) + int inertiagrouprange[2]; // range of geom groups used to compute inertia + mjtByte exactmeshinertia; // if false, use old formula + mjLROpt LRopt; // options for lengthrange computation + + // engine data + mjOption option; // physics options + mjVisual visual; // visual options + mjStatistic stat; // statistics override (if defined) + + // sizes + size_t memory; // number of bytes in arena+stack memory + int nemax; // max number of equality constraints + int nuserdata; // number of mjtNums in userdata + int nuser_body; // number of mjtNums in body_user + int nuser_jnt; // number of mjtNums in jnt_user + int nuser_geom; // number of mjtNums in geom_user + int nuser_site; // number of mjtNums in site_user + int nuser_cam; // number of mjtNums in cam_user + int nuser_tendon; // number of mjtNums in tendon_user + int nuser_actuator; // number of mjtNums in actuator_user + int nuser_sensor; // number of mjtNums in sensor_user + int nkey; // number of keyframes + int njmax; // (deprecated) max number of constraints + int nconmax; // (deprecated) max number of detected contacts + size_t nstack; // (deprecated) number of mjtNums in mjData stack + + // global data + mjString* comment; // comment at top of XML + mjString* modelfiledir; // path to model file + + // other + mjtByte hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator +} mjSpec; +typedef struct mjsOrientation_ { // alternative orientation specifiers + mjtOrientation type; // active orientation specifier + double axisangle[4]; // axis and angle + double xyaxes[6]; // x and y axes + double zaxis[3]; // z axis (minimal rotation) + double euler[3]; // Euler angles +} mjsOrientation; +typedef struct mjsPlugin_ { // plugin specification + mjsElement* instance; // element type + mjString* name; // name + mjString* instance_name; // instance name + int plugin_slot; // global registered slot number of the plugin + mjtByte active; // is the plugin active + mjString* info; // message appended to compiler errors +} mjsPlugin; +typedef struct mjsBody_ { // body specification + mjsElement* element; // element type + mjString* name; // name + mjString* childclass; // childclass name + + // body frame + double pos[3]; // frame position + double quat[4]; // frame orientation + mjsOrientation alt; // frame alternative orientation + + // inertial frame + double mass; // mass + double ipos[3]; // inertial frame position + double iquat[4]; // inertial frame orientation + double inertia[3]; // diagonal inertia (in i-frame) + mjsOrientation ialt; // inertial frame alternative orientation + double fullinertia[6]; // non-axis-aligned inertia matrix + + // other + mjtByte mocap; // is this a mocap body + double gravcomp; // gravity compensation + mjDoubleVec* userdata; // user data + mjtByte explicitinertial; // whether to save the body with explicit inertial clause + mjsPlugin plugin; // passive force plugin + mjString* info; // message appended to compiler errors +} mjsBody; +typedef struct mjsFrame_ { // frame specification + mjsElement* element; // element type + mjString* name; // name + mjString* childclass; // childclass name + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + mjString* info; // message appended to compiler errors +} mjsFrame; +typedef struct mjsJoint_ { // joint specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + mjtJoint type; // joint type + + // kinematics + double pos[3]; // anchor position + double axis[3]; // joint axis + double ref; // value at reference configuration: qpos0 + + // stiffness + double stiffness; // stiffness coefficient + double springref; // spring reference value: qpos_spring + double springdamper[2]; // timeconst, dampratio + + // limits + int limited; // does joint have limits (mjtLimited) + double range[2]; // joint limits + double margin; // margin value for joint limit detection + mjtNum solref_limit[mjNREF]; // solver reference: joint limits + mjtNum solimp_limit[mjNIMP]; // solver impedance: joint limits + int actfrclimited; // are actuator forces on joint limited (mjtLimited) + double actfrcrange[2]; // actuator force limits + + // dof properties + double armature; // armature inertia (mass for slider) + double damping; // damping coefficient + double frictionloss; // friction loss + mjtNum solref_friction[mjNREF]; // solver reference: dof friction + mjtNum solimp_friction[mjNIMP]; // solver impedance: dof friction + + // other + int group; // group + mjtByte actgravcomp; // is gravcomp force applied via actuators + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsJoint; +typedef struct mjsGeom_ { // geom specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // classname + mjtGeom type; // geom type + + // frame, size + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid + double size[3]; // type-specific size + + // contact related + int contype; // contact type + int conaffinity; // contact affinity + int condim; // contact dimensionality + int priority; // contact priority + double friction[3]; // one-sided friction coefficients: slide, roll, spin + double solmix; // solver mixing for contact pairs + mjtNum solref[mjNREF]; // solver reference + mjtNum solimp[mjNIMP]; // solver impedance + double margin; // margin for contact detection + double gap; // include in solver if dist < margin-gap + + // inertia inference + double mass; // used to compute density + double density; // used to compute mass and inertia from volume or surface + mjtGeomInertia typeinertia; // selects between surface and volume inertia + + // fluid forces + mjtNum fluid_ellipsoid; // whether ellipsoid-fluid model is active + mjtNum fluid_coefs[5]; // ellipsoid-fluid interaction coefs + + // visual + mjString* material; // name of material + float rgba[4]; // rgba when material is omitted + int group; // group + + // other + mjString* hfieldname; // heightfield attached to geom + mjString* meshname; // mesh attached to geom + double fitscale; // scale mesh uniformly + mjDoubleVec* userdata; // user data + mjsPlugin plugin; // sdf plugin + mjString* info; // message appended to compiler errors +} mjsGeom; +typedef struct mjsSite_ { // site specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // frame, size + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid + double size[3]; // geom size + + // visual + mjtGeom type; // geom type + mjString* material; // name of material + int group; // group + float rgba[4]; // rgba when material is omitted + + // other + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsSite; +typedef struct mjsCamera_ { // camera specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // extrinsics + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + mjtCamLight mode; // tracking mode + mjString* targetbody; // target body for tracking/targeting + + // intrinsics + double fovy; // y-field of view + double ipd; // inter-pupilary distance + float intrinsic[4]; // camera intrinsics (length) + float sensor_size[2]; // sensor size (length) + float resolution[2]; // resolution (pixel) + float focal_length[2]; // focal length (length) + float focal_pixel[2]; // focal length (pixel) + float principal_length[2]; // principal point (length) + float principal_pixel[2]; // principal point (pixel) + + // other + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsCamera; +typedef struct mjsLight_ { // light specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // frame + double pos[3]; // position + double dir[3]; // direction + mjtCamLight mode; // tracking mode + mjString* targetbody; // target body for targeting + + // intrinsics + mjtByte active; // is light active + mjtByte directional; // is light directional or spot + mjtByte castshadow; // does light cast shadows + double bulbradius; // bulb radius, for soft shadows + float attenuation[3]; // OpenGL attenuation (quadratic model) + float cutoff; // OpenGL cutoff + float exponent; // OpenGL exponent + float ambient[3]; // ambient color + float diffuse[3]; // diffuse color + float specular[3]; // specular color + + // other + mjString* info; // message appended to compiler errorsx +} mjsLight; +typedef struct mjsFlex_ { // flex specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // contact properties + int contype; // contact type + int conaffinity; // contact affinity + int condim; // contact dimensionality + int priority; // contact priority + double friction[3]; // one-sided friction coefficients: slide, roll, spin + double solmix; // solver mixing for contact pairs + mjtNum solref[mjNREF]; // solver reference + mjtNum solimp[mjNIMP]; // solver impedance + double margin; // margin for contact detection + double gap; // include in solver if dist`---it is compiled into :ref:`mjModel`. +Compilation is independent of loading, meaning that the compiler works in the same way regardless of how :ref:`mjSpec` +was created. Both the parser and the compiler perform extensive error checking, and abort when the first error is encountered. The resulting error messages contain the row and column number in the XML file, and are self-explanatory so we do not document them here. The parser uses a custom schema to make sure that the file structure, elements and attributes are valid. The compiler then applies many additional semantic checks. Finally, one @@ -72,9 +72,9 @@ binary MJB file with :ref:`mj_saveModel`. The MJB is a stand-alone file and does refer to any other files. It also loads faster. So we recommend saving commonly used models as MJB and loading them when needed for simulation. -It is also possible to save a compiled mjCModel as MJCF with :ref:`mj_saveLastXML`. If any real-valued fields in the -corresponding mjModel were modified after compilation (which is unusual but can happen in system identification -applications for example), the modifications are automatically copied back into mjCModel before saving. Note that +It is also possible to save a compiled :ref:`mjSpec` as MJCF with :ref:`mj_saveLastXML`. If any real-valued fields in +the corresponding mjModel were modified after compilation (which is unusual but can happen in system identification +applications for example), the modifications are automatically copied back into :ref:`mjSpec` before saving. Note that structural changes cannot be made in the compiled model. The XML writer attempts to generate the smallest MJCF file which is guaranteed to compile into the same model, modulo negligible numeric differences caused by the plain text representation of real values. The resulting file may not have the same structure as the original because MJCF has many @@ -83,6 +83,14 @@ subset of MJCF where all coordinates are local and all body positions, orientati explicitly specified. In the Computation chapter we showed an `example <_static/example.xml>`__ MJCF file and the corresponding `saved example <_static/example_saved.xml>`__. +.. _EditModel: + +Editing models +~~~~~~~~~~~~~~ + +As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API. +For further documentation, please see the :doc:`Model Editing` chapter. + .. _Mechanisms: MJCF Mechanisms diff --git a/doc/overview.rst b/doc/overview.rst index fff37970..068a66e5 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -141,32 +141,30 @@ There are several entities called "model" in MuJoCo. The user defines the model The software can then create multiple instances of the same model in different media (file or memory) and on different levels of description (high or low). All combinations are possible as shown in the following table: -+------------+----------------------+----------------------+ -| | High level | Low level | -+============+======================+======================+ -| **File** | MJCF/URDF (XML) | MJB (binary) | -+------------+----------------------+----------------------+ -| **Memory** | mjCModel (C++ class) | mjModel (C struct) | -+------------+----------------------+----------------------+ ++------------+---------------------------+----------------------------+ +| | High level | Low level | ++============+===========================+============================+ +| **File** | MJCF/URDF (XML) | MJB (binary) | ++------------+---------------------------+----------------------------+ +| **Memory** | :ref:`mjSpec` (C struct) | :ref:`mjModel` (C struct) | ++------------+---------------------------+----------------------------+ -All runtime computations are performed with ``mjModel`` which is too complex to create manually. This is why we have two -levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level -model on which computations can be performed. The resulting ``mjModel`` can be loaded and saved into a binary file +All runtime computations are performed with :ref:`mjModel` which is too complex to create manually. This is why we have +two levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level +model on which computations can be performed. The resulting :ref:`mjModel` can be loaded and saved into a binary file (MJB), however those are version-specific and cannot be decompiled, thus models should always be maintained as XML files. -The (internal) C++ class ``mjCModel`` is roughly in one-to-one correspondence with the MJCF file format. The XML parser -interprets the MJCF or URDF file and creates the corresponding ``mjCModel``. In principle the user can create -``mjCModel`` programmatically and then save it to MJCF or compile it. However this functionality is not yet exposed -because a C++ API cannot be exported from a compiler-independent library. There is a plan to develop a C wrapper around -it, but for the time being the parser and compiler are always invoked together, and models can only be created in XML. +The :ref:`mjSpec` C struct is in one-to-one correspondence with the MJCF file format. The XML loader interprets the MJCF +or URDF file, creates the corresponding :ref:`mjSpec` and compiles it to :ref:`mjModel`. The user can create +:ref:`mjSpec` programmatically and then save it to MJCF or compile it. Procedural model creation and editing is +described in the :doc:`Model Editing ` chapter. -The following diagram shows the different paths to obtaining an ``mjModel`` (again, the second bullet point is not yet -available): +The following diagram shows the different paths to obtaining an :ref:`mjModel`: -- (text editor) → MJCF/URDF file → (MuJoCo parser → mjCModel → MuJoCo compiler) → mjModel -- (user code) → mjCModel → (MuJoCo compiler) → mjModel -- MJB file → (MuJoCo loader) → mjModel +- (text editor) → MJCF/URDF file → (MuJoCo parser → mjSpec → compiler) → mjModel +- (user code) → mjSpec → (MuJoCo compiler) → mjModel +- MJB file → (model loader) → mjModel .. _Examples: diff --git a/doc/programming/index.rst b/doc/programming/index.rst index 11273f46..5d438482 100644 --- a/doc/programming/index.rst +++ b/doc/programming/index.rst @@ -18,7 +18,7 @@ Engine The simulator (or physics engine) is written in C. It is responsible for all runtime computations. Parser The XML parser is written in C++. It can parse MJCF models and URDF models, converting them into an internal mjCModel - C++ object which is not directly exposed to the user. + C++ object which is exposed to the user via mjSpec. Compiler The compiler is written in C++. It takes an mjCModel C++ object constructed by the parser, and converts it into an mjModel C structure used at runtime. @@ -108,10 +108,10 @@ Building from source To build MuJoCo from source, you will need CMake and a working C++17 compiler installed. The steps are: - #. Clone the ``mujoco`` repository from GitHub. - #. Create a new build directory somewhere, and ``cd`` into it. - #. Run ``cmake $PATH_TO_CLONED_REPO`` to configure the build. - #. Run ``cmake --build .`` to build. +#. Clone the ``mujoco`` repository from GitHub. +#. Create a new build directory somewhere, and ``cd`` into it. +#. Run ``cmake $PATH_TO_CLONED_REPO`` to configure the build. +#. Run ``cmake --build .`` to build. MuJoCo's build system automatically fetches dependencies from upstream repositories over the Internet using CMake's `FetchContent `_ module. @@ -123,8 +123,8 @@ section of the documentation. Additionally, the CMake setup also implements an installation phase which will copy and organize the output files to a target directory. - 5. Select the directory: ``cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=`` - #. After building, install with ``cmake --install .`` +5. Select the directory: ``cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=`` +#. After building, install with ``cmake --install .`` When building on Windows, use Visual Studio 2019 or later and make sure Windows SDK version 10.0.22000 or later is installed (see `here `__ for more details). @@ -160,6 +160,8 @@ links below, to make this documentation self-contained. Defines the primitive types and structures needed by the UI framework. `mjtnum.h `__ Defines MuJoCo's ``mjtNum`` floating-point type to be either ``double`` or ``float``. See :ref:`mjtNum`. +`mjspec.h `__ + Defines enums and structs used for :doc:`procedural model editing `. `mjmacro.h `__ Defines C macros that are useful in user code. `mjxmacro.h `__ @@ -226,6 +228,8 @@ to which the symbol belongs. First we list the prefixes corresponding to type de Data structure related to OpenGL rendering, for example :ref:`mjrContext`. ``mjui`` Data structure related to UI framework, for example :ref:`mjuiSection`. +``mjs`` + Data structure related :doc:`procedural model editing `, for example :ref:`mjsJoint`. Next we list the prefixes corresponding to function definitions. Note that function prefixes always end with underscore. @@ -247,6 +251,8 @@ Next we list the prefixes corresponding to function definitions. Note that funct custom callbacks by setting these global pointers to user-defined functions. ``mjd_`` Functions for computing derivatives, for example :ref:`mjd_transitionFD`. +``mjs_`` + Functions for :doc:`procedural model editing `, for example :ref:`mjs_addJoint`. .. _inOpenGL: @@ -276,5 +282,6 @@ now lazily resolved at runtime after the switch to GLAD, the "nogl" libraries ar simulation visualization ui + modeledit samples extension diff --git a/doc/programming/modeledit.rst b/doc/programming/modeledit.rst new file mode 100644 index 00000000..33181d1d --- /dev/null +++ b/doc/programming/modeledit.rst @@ -0,0 +1,44 @@ +Model Editing +------------- + +.. admonition:: Unstable API + :class: attention + + The API described below is new and unstable. There may be latent bugs and function signatures may change. Early + adopters are welcome (indeed, encouraged) to try it out and report any issues on GitHub. + +As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API. +This datastructure is in one-to-one correspondence with MJCF and indeed, MuJoCo's own XML parsers (both MJCF and URDF) +use this API when loading a model. + + +.. _meOverview: + +Overview +~~~~~~~~ + +As summarized in the the :ref:`Overview chapter`, the traditional workflow to create compiled :ref:`mjModel` +instances is: + +1. Create an XML model description file (MJCF or URDF). +2. Call :ref:`mj_loadXML` passing in the XML (and associated assets), obtain an :ref:`mjModel` instance. + +The new workflow looks like: + +1. Create an :ref:`mjSpec`, either an empty one corresponding to the XML ````, or by loading an existing XML + file. +2. Modify the :ref:`mjSpec` as desired, adding, editing and removing elements. +3. Compile the :ref:`mjSpec` at any point, obtaining an updated :ref:`mjModel` instance. After compilation, the + :ref:`mjSpec` remains editable, so steps 2 and 3 are interchangable. + + +.. _meUsage: + +Usage +~~~~~ + +Detailed documentation is still missing. In the meantime, advanced users can refer to +`user_api_test.cc `__ and the MJCF +parser in `xml_native_reader.cc `__, +which is already using this API. + diff --git a/doc/programming/simulation.rst b/doc/programming/simulation.rst index 5b3d50f8..6939a421 100644 --- a/doc/programming/simulation.rst +++ b/doc/programming/simulation.rst @@ -585,8 +585,8 @@ corresponding to precomputed quantities when the model is in the reference confi Finally, if changes are made to mjModel at runtime, it may be desirable to save them back to the XML. The function :ref:`mj_saveLastXML` does that in a limited sense: it copies all real-valued parameters from mjModel back to the -internal mjCModel, and then saves it as XML. This does not cover all possible changes that the user could have made. -The only way to guarantee that all changes are saved is to save the model as a binary MJB file with the function +internal :ref:`mjSpec`, and then saves it as XML. This does not cover all possible changes that the user could have +made. The only way to guarantee that all changes are saved is to save the model as a binary MJB file with the function :ref:`mj_saveModel`, or even better, make the changes directly in the XML. Unfortunately there are situations where changes need to be made programmatically, as in system identification for example, and this can only be done with the compiled model. So in summary, we have reasonable but not perfect mechanisms for saving model changes. The reason for diff --git a/include/mujoco/mjspec.h b/include/mujoco/mjspec.h new file mode 100644 index 00000000..a52f7d7d --- /dev/null +++ b/include/mujoco/mjspec.h @@ -0,0 +1,763 @@ +// 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_INCLUDE_MJSPEC_H_ +#define MUJOCO_INCLUDE_MJSPEC_H_ + +#include +#include +#include + + +// this is a C-API +#ifdef __cplusplus +#include +#include + +extern "C" { +#endif + +//-------------------------------- handles to strings and arrays ----------------------------------- + +#ifdef __cplusplus + // C++: defined to be compatible with corresponding std types + using mjString = std::string; + using mjStringVec = std::vector; + using mjIntVec = std::vector; + using mjIntVecVec = std::vector>; + using mjFloatVec = std::vector; + using mjFloatVecVec = std::vector>; + using mjDoubleVec = std::vector; +#else + // C: opaque types + typedef void mjString; + typedef void mjStringVec; + typedef void mjIntVec; + typedef void mjIntVecVec; + typedef void mjFloatVec; + typedef void mjFloatVecVec; + typedef void mjDoubleVec; +#endif + + +//-------------------------------- enum types (mjt) ------------------------------------------------ + +typedef enum mjtGeomInertia_ { // type of inertia inference + mjINERTIA_VOLUME, // mass distributed in the volume + mjINERTIA_SHELL, // mass distributed on the surface +} mjtGeomInertia; + + +typedef enum mjtBuiltin_ { // type of built-in procedural texture + mjBUILTIN_NONE = 0, // no built-in texture + mjBUILTIN_GRADIENT, // gradient: rgb1->rgb2 + mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2 + mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down +} mjtBuiltin; + + +typedef enum mjtMark_ { // mark type for procedural textures + mjMARK_NONE = 0, // no mark + mjMARK_EDGE, // edges + mjMARK_CROSS, // cross + mjMARK_RANDOM // random dots +} mjtMark; + + +typedef enum mjtLimited_ { // type of limit specification + mjLIMITED_FALSE = 0, // not limited + mjLIMITED_TRUE, // limited + mjLIMITED_AUTO, // limited inferred from presence of range +} mjtLimited; + + +typedef enum mjtInertiaFromGeom_ { // whether to infer body inertias from child geoms + mjINERTIAFROMGEOM_FALSE = 0, // do not use; inertial element required + mjINERTIAFROMGEOM_TRUE, // always use; overwrite inertial element + mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing +} mjtInertiaFromGeom; + + +typedef enum mjtOrientation_ { // type of orientation specifier + mjORIENTATION_QUAT = 0, // quaternion + mjORIENTATION_AXISANGLE, // axis and angle + mjORIENTATION_XYAXES, // x and y axes + mjORIENTATION_ZAXIS, // z axis (minimal rotation) + mjORIENTATION_EULER, // Euler angles +} mjtOrientation; + + +//-------------------------------- attribute structs (mjs) ----------------------------------------- + +typedef struct mjsElement_ { // element type, do not modify + mjtObj elemtype; // element type +} mjsElement; + + +typedef struct mjSpec_ { // model specification + mjsElement* element; // element type + mjString* modelname; // model name + + // compiler settings + mjtByte autolimits; // infer "limited" attribute based on range + double boundmass; // enforce minimum body mass + double boundinertia; // enforce minimum body diagonal inertia + double settotalmass; // rescale masses and inertias; <=0: ignore + mjtByte balanceinertia; // automatically impose A + B >= C rule + mjtByte strippath; // automatically strip paths from mesh files + mjtByte fitaabb; // meshfit to aabb instead of inertia box + mjtByte degree; // angles in radians or degrees + char euler[3]; // sequence for euler rotations + mjString* meshdir; // mesh and hfield directory + mjString* texturedir; // texture directory + mjtByte discardvisual; // discard visual geoms in parser + mjtByte convexhull; // compute mesh convex hulls + mjtByte usethread; // use multiple threads to speed up compiler + mjtByte fusestatic; // fuse static bodies with parent + int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom) + int inertiagrouprange[2]; // range of geom groups used to compute inertia + mjtByte exactmeshinertia; // if false, use old formula + mjLROpt LRopt; // options for lengthrange computation + + // engine data + mjOption option; // physics options + mjVisual visual; // visual options + mjStatistic stat; // statistics override (if defined) + + // sizes + size_t memory; // number of bytes in arena+stack memory + int nemax; // max number of equality constraints + int nuserdata; // number of mjtNums in userdata + int nuser_body; // number of mjtNums in body_user + int nuser_jnt; // number of mjtNums in jnt_user + int nuser_geom; // number of mjtNums in geom_user + int nuser_site; // number of mjtNums in site_user + int nuser_cam; // number of mjtNums in cam_user + int nuser_tendon; // number of mjtNums in tendon_user + int nuser_actuator; // number of mjtNums in actuator_user + int nuser_sensor; // number of mjtNums in sensor_user + int nkey; // number of keyframes + int njmax; // (deprecated) max number of constraints + int nconmax; // (deprecated) max number of detected contacts + size_t nstack; // (deprecated) number of mjtNums in mjData stack + + // global data + mjString* comment; // comment at top of XML + mjString* modelfiledir; // path to model file + + // other + mjtByte hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator +} mjSpec; + + +typedef struct mjsOrientation_ { // alternative orientation specifiers + mjtOrientation type; // active orientation specifier + double axisangle[4]; // axis and angle + double xyaxes[6]; // x and y axes + double zaxis[3]; // z axis (minimal rotation) + double euler[3]; // Euler angles +} mjsOrientation; + + +typedef struct mjsPlugin_ { // plugin specification + mjsElement* instance; // element type + mjString* name; // name + mjString* instance_name; // instance name + int plugin_slot; // global registered slot number of the plugin + mjtByte active; // is the plugin active + mjString* info; // message appended to compiler errors +} mjsPlugin; + + +typedef struct mjsBody_ { // body specification + mjsElement* element; // element type + mjString* name; // name + mjString* childclass; // childclass name + + // body frame + double pos[3]; // frame position + double quat[4]; // frame orientation + mjsOrientation alt; // frame alternative orientation + + // inertial frame + double mass; // mass + double ipos[3]; // inertial frame position + double iquat[4]; // inertial frame orientation + double inertia[3]; // diagonal inertia (in i-frame) + mjsOrientation ialt; // inertial frame alternative orientation + double fullinertia[6]; // non-axis-aligned inertia matrix + + // other + mjtByte mocap; // is this a mocap body + double gravcomp; // gravity compensation + mjDoubleVec* userdata; // user data + mjtByte explicitinertial; // whether to save the body with explicit inertial clause + mjsPlugin plugin; // passive force plugin + mjString* info; // message appended to compiler errors +} mjsBody; + + +typedef struct mjsFrame_ { // frame specification + mjsElement* element; // element type + mjString* name; // name + mjString* childclass; // childclass name + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + mjString* info; // message appended to compiler errors +} mjsFrame; + + +typedef struct mjsJoint_ { // joint specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + mjtJoint type; // joint type + + // kinematics + double pos[3]; // anchor position + double axis[3]; // joint axis + double ref; // value at reference configuration: qpos0 + + // stiffness + double stiffness; // stiffness coefficient + double springref; // spring reference value: qpos_spring + double springdamper[2]; // timeconst, dampratio + + // limits + int limited; // does joint have limits (mjtLimited) + double range[2]; // joint limits + double margin; // margin value for joint limit detection + mjtNum solref_limit[mjNREF]; // solver reference: joint limits + mjtNum solimp_limit[mjNIMP]; // solver impedance: joint limits + int actfrclimited; // are actuator forces on joint limited (mjtLimited) + double actfrcrange[2]; // actuator force limits + + // dof properties + double armature; // armature inertia (mass for slider) + double damping; // damping coefficient + double frictionloss; // friction loss + mjtNum solref_friction[mjNREF]; // solver reference: dof friction + mjtNum solimp_friction[mjNIMP]; // solver impedance: dof friction + + // other + int group; // group + mjtByte actgravcomp; // is gravcomp force applied via actuators + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsJoint; + + +typedef struct mjsGeom_ { // geom specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // classname + mjtGeom type; // geom type + + // frame, size + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid + double size[3]; // type-specific size + + // contact related + int contype; // contact type + int conaffinity; // contact affinity + int condim; // contact dimensionality + int priority; // contact priority + double friction[3]; // one-sided friction coefficients: slide, roll, spin + double solmix; // solver mixing for contact pairs + mjtNum solref[mjNREF]; // solver reference + mjtNum solimp[mjNIMP]; // solver impedance + double margin; // margin for contact detection + double gap; // include in solver if dist < margin-gap + + // inertia inference + double mass; // used to compute density + double density; // used to compute mass and inertia from volume or surface + mjtGeomInertia typeinertia; // selects between surface and volume inertia + + // fluid forces + mjtNum fluid_ellipsoid; // whether ellipsoid-fluid model is active + mjtNum fluid_coefs[5]; // ellipsoid-fluid interaction coefs + + // visual + mjString* material; // name of material + float rgba[4]; // rgba when material is omitted + int group; // group + + // other + mjString* hfieldname; // heightfield attached to geom + mjString* meshname; // mesh attached to geom + double fitscale; // scale mesh uniformly + mjDoubleVec* userdata; // user data + mjsPlugin plugin; // sdf plugin + mjString* info; // message appended to compiler errors +} mjsGeom; + + +typedef struct mjsSite_ { // site specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // frame, size + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid + double size[3]; // geom size + + // visual + mjtGeom type; // geom type + mjString* material; // name of material + int group; // group + float rgba[4]; // rgba when material is omitted + + // other + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsSite; + + +typedef struct mjsCamera_ { // camera specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // extrinsics + double pos[3]; // position + double quat[4]; // orientation + mjsOrientation alt; // alternative orientation + mjtCamLight mode; // tracking mode + mjString* targetbody; // target body for tracking/targeting + + // intrinsics + double fovy; // y-field of view + double ipd; // inter-pupilary distance + float intrinsic[4]; // camera intrinsics (length) + float sensor_size[2]; // sensor size (length) + float resolution[2]; // resolution (pixel) + float focal_length[2]; // focal length (length) + float focal_pixel[2]; // focal length (pixel) + float principal_length[2]; // principal point (length) + float principal_pixel[2]; // principal point (pixel) + + // other + mjDoubleVec* userdata; // user data + mjString* info; // message appended to compiler errors +} mjsCamera; + + +typedef struct mjsLight_ { // light specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // frame + double pos[3]; // position + double dir[3]; // direction + mjtCamLight mode; // tracking mode + mjString* targetbody; // target body for targeting + + // intrinsics + mjtByte active; // is light active + mjtByte directional; // is light directional or spot + mjtByte castshadow; // does light cast shadows + double bulbradius; // bulb radius, for soft shadows + float attenuation[3]; // OpenGL attenuation (quadratic model) + float cutoff; // OpenGL cutoff + float exponent; // OpenGL exponent + float ambient[3]; // ambient color + float diffuse[3]; // diffuse color + float specular[3]; // specular color + + // other + mjString* info; // message appended to compiler errorsx +} mjsLight; + + +typedef struct mjsFlex_ { // flex specification + mjsElement* element; // element type + mjString* name; // name + mjString* classname; // class name + + // contact properties + int contype; // contact type + int conaffinity; // contact affinity + int condim; // contact dimensionality + int priority; // contact priority + double friction[3]; // one-sided friction coefficients: slide, roll, spin + double solmix; // solver mixing for contact pairs + mjtNum solref[mjNREF]; // solver reference + mjtNum solimp[mjNIMP]; // solver impedance + double margin; // margin for contact detection + double gap; // include in solver if dist - - -// this is a C-API -#ifdef __cplusplus -extern "C" { -#endif - // header version; should match the library version as returned by mj_version() #define mjVERSION_HEADER 317 @@ -32,15 +24,21 @@ extern "C" { // type definitions #include +#include #include #include #include #include +#include #include #include #include #include +// this is a C-API +#ifdef __cplusplus +extern "C" { +#endif // user error and memory handlers MJAPI extern void (*mju_user_error)(const char*); @@ -97,6 +95,7 @@ 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 XML file in MJCF or URDF format, compile it, return low-level model. @@ -104,6 +103,18 @@ MJAPI int mj_makeEmptyFileVFS(mjVFS* vfs, const char* filename, int filesize); // If error is not NULL, it must have size error_sz. MJAPI mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, char* error, int error_sz); +// Parse spec from XML file. +MJAPI mjSpec* mj_parseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz); + +// Parse spec from XML string. +MJAPI mjSpec* mj_parseXMLString(const char* xml, const mjVFS* vfs, char* error, int error_sz); + +// Compile spec to model. +MJAPI mjModel* mj_compile(mjSpec* s, const mjVFS* vfs); + +// Recompile spec to model, preserving the state. +MJAPI void mj_recompile(mjSpec* s, const mjVFS* vfs, mjModel* m, mjData* d); + // Update XML data structures with info from low-level model, save as MJCF. // If error is not NULL, it must have size error_sz. MJAPI int mj_saveLastXML(const char* filename, const mjModel* m, char* error, int error_sz); @@ -111,9 +122,14 @@ MJAPI int mj_saveLastXML(const char* filename, const mjModel* m, char* error, in // Free last XML model if loaded. Called internally at each load. MJAPI void mj_freeLastXML(void); -// Print internal XML schema as plain text or HTML, with style-padding or  . -MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz, - int flg_html, int flg_pad); +// Copy (possibly modified) model fields back into spec. +MJAPI void mj_copyBack(mjSpec* s, const mjModel* m); + +// Save spec to XML string, return 1 on success, 0 otherwise. +MJAPI int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int error_sz); + +// Save spec to XML file, return 1 on success, 0 otherwise. +MJAPI int mj_saveXML(const mjSpec* s, const char* filename, char* error, int error_sz); //---------------------------------- Main simulation ----------------------------------------------- @@ -221,6 +237,15 @@ MJAPI void mj_setConst(mjModel* m, mjData* d); MJAPI int mj_setLengthRange(mjModel* m, mjData* d, int index, const mjLROpt* opt, char* error, int error_sz); +// Create empty spec. +MJAPI mjSpec* mj_makeSpec(void); + +// Copy spec. +MJAPI mjSpec* mj_copySpec(const mjSpec* s); + +// Free memory allocation in mjSpec. +MJAPI void mj_deleteSpec(mjSpec* s); + //---------------------------------- Printing ------------------------------------------------------ @@ -246,6 +271,10 @@ MJAPI void mju_printMat(const mjtNum* mat, int nr, int nc); MJAPI void mju_printMatSparse(const mjtNum* mat, int nr, const int* rownnz, const int* rowadr, const int* colind); +// Print internal XML schema as plain text or HTML, with style-padding or  . +MJAPI int mj_printSchema(const char* filename, char* buffer, int buffer_sz, + int flg_html, int flg_pad); + //---------------------------------- Components ---------------------------------------------------- @@ -510,7 +539,7 @@ MJAPI int mj_version(void); MJAPI const char* mj_versionString(void); -//---------------------------------- Ray collisions ------------------------------------------------ +//---------------------------------- Ray casting --------------------------------------------------- // Intersect multiple rays emanating from a single point. // Similar semantics to mj_ray, but vec is an array of (nray x 3) directions. @@ -852,6 +881,12 @@ MJAPI void mj_warning(mjData* d, int warning, int info); // Write [datetime, type: message] to MUJOCO_LOG.TXT. MJAPI void mju_writeLog(const char* type, const char* msg); +// Get compiler error message from spec. +MJAPI const char* mjs_getError(mjSpec* s); + +// Return 1 if compiler error is a warning. +MJAPI int mjs_isWarning(mjSpec* s); + //---------------------------------- Standard math ------------------------------------------------- @@ -1037,6 +1072,7 @@ MJAPI void mju_transformSpatial(mjtNum res[6], const mjtNum vec[6], int flg_forc const mjtNum newpos[3], const mjtNum oldpos[3], const mjtNum rotnew2old[9]); + //---------------------------------- Quaternions --------------------------------------------------- // Rotate vector by quaternion. @@ -1079,6 +1115,7 @@ MJAPI void mju_quatZ2Vec(mjtNum quat[4], const mjtNum vec[3]); // seq[0,1,2] must be in 'xyzXYZ', lower/upper-case mean intrinsic/extrinsic rotations. MJAPI void mju_euler2Quat(mjtNum quat[4], const mjtNum euler[3], const char* seq); + //---------------------------------- Poses --------------------------------------------------------- // Multiply two poses. @@ -1166,7 +1203,8 @@ MJAPI int mju_boxQP(mjtNum* res, mjtNum* R, int* index, const mjtNum* H, const m MJAPI void mju_boxQPmalloc(mjtNum** res, mjtNum** R, int** index, mjtNum** H, mjtNum** g, int n, mjtNum** lower, mjtNum** upper); -//---------------------- Miscellaneous ------------------------------------------------------------- + +//---------------------------------- Miscellaneous ------------------------------------------------- // Muscle active force, prm = (range[2], force, scale, lmin, lmax, vmax, fpmax, fvmax). MJAPI mjtNum mju_muscleGain(mjtNum len, mjtNum vel, const mjtNum lengthrange[2], @@ -1252,7 +1290,7 @@ MJAPI char* mju_strncpy(char *dst, const char *src, int n); MJAPI mjtNum mju_sigmoid(mjtNum x); -//---------------------- Derivatives --------------------------------------------------------------- +//---------------------------------- Derivatives --------------------------------------------------- // Finite differenced transition matrices (control theory notation) // d(x_next) = A*dx + B*du @@ -1292,7 +1330,8 @@ MJAPI void mjd_subQuat(const mjtNum qa[4], const mjtNum qb[4], mjtNum Da[9], mjt MJAPI void mjd_quatIntegrate(const mjtNum vel[3], mjtNum scale, mjtNum Dquat[9], mjtNum Dvel[9], mjtNum Dscale[3]); -//---------------------- Plugins ------------------------------------------------------------------- + +//---------------------------------- Plugins ------------------------------------------------------- // Set default plugin definition. MJAPI void mjp_defaultPlugin(mjpPlugin* plugin); @@ -1333,7 +1372,8 @@ MJAPI const mjpResourceProvider* mjp_getResourceProvider(const char* resource_na // If invalid slot number, return NULL. MJAPI const mjpResourceProvider* mjp_getResourceProviderAtSlot(int slot); -//---------------------- Thread ------------------------------------------------------------------- + +//---------------------------------- Threads ------------------------------------------------------- // Create a thread pool with the specified number of threads running. MJAPI mjThreadPool* mju_threadPoolCreate(size_t number_of_threads); @@ -1353,10 +1393,301 @@ MJAPI void mju_defaultTask(mjTask* task); // Wait for a task to complete. MJAPI void mju_taskJoin(mjTask* task); -//---------------------- Sanitizer instrumentation helpers ----------------------------------------- -// -// Most MuJoCo users can ignore these functions, the following comments are aimed primarily at -// MuJoCo developers. + +//---------------------------------- Attachment ---------------------------------------------------- + +// Attach child body to a parent frame, return 0 on success. +MJAPI int mjs_attachBody(mjsFrame* parent, const mjsBody* child, + const char* prefix, const char* suffix); + +// Attach child frame to a parent body, return 0 on success. +MJAPI int mjs_attachFrame(mjsBody* parent, const mjsFrame* child, + const char* prefix, const char* suffix); + +// Detach body from mjSpec, remove all references and delete the body, return 0 on success. +MJAPI int mjs_detachBody(mjSpec* s, mjsBody* b); + + +//---------------------------------- Tree elements ------------------------------------------------- + +// Add child body to body, return child. +MJAPI mjsBody* mjs_addBody(mjsBody* body, mjsDefault* def); + +// Add site to body, return site spec. +MJAPI mjsSite* mjs_addSite(mjsBody* body, mjsDefault* def); + +// Add joint to body. +MJAPI mjsJoint* mjs_addJoint(mjsBody* body, mjsDefault* def); + +// Add freejoint to body. +MJAPI mjsJoint* mjs_addFreeJoint(mjsBody* body); + +// Add geom to body. +MJAPI mjsGeom* mjs_addGeom(mjsBody* body, mjsDefault* def); + +// Add camera to body. +MJAPI mjsCamera* mjs_addCamera(mjsBody* body, mjsDefault* def); + +// Add light to body. +MJAPI mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def); + +// Add frame to body. +MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe); + +// Delete object corresponding to the given element. +MJAPI void mjs_delete(mjsElement* element); + + +//---------------------------------- Non-tree elements --------------------------------------------- + +// Add actuator. +MJAPI mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* def); + +// Add sensor. +MJAPI mjsSensor* mjs_addSensor(mjSpec* s); + +// Add flex. +MJAPI mjsFlex* mjs_addFlex(mjSpec* s); + +// Add contact pair. +MJAPI mjsPair* mjs_addPair(mjSpec* s, mjsDefault* def); + +// Add excluded body pair. +MJAPI mjsExclude* mjs_addExclude(mjSpec* s); + +// Add equality. +MJAPI mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* def); + +// Add tendon. +MJAPI mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* def); + +// Wrap site using tendon. +MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendon, const char* name); + +// Wrap geom using tendon. +MJAPI mjsWrap* mjs_wrapGeom(mjsTendon* tendon, const char* name, const char* sidesite); + +// Wrap joint using tendon. +MJAPI mjsWrap* mjs_wrapJoint(mjsTendon* tendon, const char* name, double coef); + +// Wrap pulley using tendon. +MJAPI mjsWrap* mjs_wrapPulley(mjsTendon* tendon, double divisor); + +// Add numeric. +MJAPI mjsNumeric* mjs_addNumeric(mjSpec* s); + +// Add text. +MJAPI mjsText* mjs_addText(mjSpec* s); + +// Add tuple. +MJAPI mjsTuple* mjs_addTuple(mjSpec* s); + +// Add keyframe. +MJAPI mjsKey* mjs_addKey(mjSpec* s); + +// Add plugin. +MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s); + +// Add default. +MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id); + + +//---------------------------------- Assets -------------------------------------------------------- + +// Add mesh. +MJAPI mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def); + +// Add height field. +MJAPI mjsHField* mjs_addHField(mjSpec* s); + +// Add skin. +MJAPI mjsSkin* mjs_addSkin(mjSpec* s); + +// Add texture. +MJAPI mjsTexture* mjs_addTexture(mjSpec* s); + +// Add material. +MJAPI mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* def); + + +//---------------------------------- Find and get utilities ---------------------------------------- + +// Get spec from body. +MJAPI mjSpec* mjs_getSpec(mjsBody* body); + +// Find body in model by name. +MJAPI mjsBody* mjs_findBody(mjSpec* s, const char* name); + +// Find child body by name. +MJAPI mjsBody* mjs_findChild(mjsBody* body, const char* name); + +// Find mesh by name. +MJAPI mjsMesh* mjs_findMesh(mjSpec* s, const char* name); + +// Find frame by name. +MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name); + +// Get default corresponding to an element. +MJAPI mjsDefault* mjs_getDefault(mjsElement* element); + +// Find default in model by class name. +MJAPI mjsDefault* mjs_findDefault(mjSpec* s, const char* classname); + +// Get global default from model. +MJAPI mjsDefault* mjs_getSpecDefault(mjSpec* s); + +// Get element id. +MJAPI int mjs_getId(mjsElement* element); + +// Return body's first child of given type. +MJAPI mjsElement* mjs_firstChild(mjsBody* body, mjtObj type); + +// Return body's next child of the same type; return NULL if child is last. +MJAPI mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child); + + +//---------------------------------- Attribute setters --------------------------------------------- + +// Copy text to string. +MJAPI void mjs_setString(mjString* dest, const char* text); + +// Split text to entries and copy to string vector. +MJAPI void mjs_setStringVec(mjStringVec* dest, const char* text); + +// Set entry in string vector. +MJAPI mjtByte mjs_setInStringVec(mjStringVec* dest, int i, const char* text); + +// Append text entry to string vector. +MJAPI void mjs_appendString(mjStringVec* dest, const char* text); + +// Copy int array to vector. +MJAPI void mjs_setInt(mjIntVec* dest, const int* array, int size); + +// Append int array to vector of arrays. +MJAPI void mjs_appendIntVec(mjIntVecVec* dest, const int* array, int size); + +// Copy float array to vector. +MJAPI void mjs_setFloat(mjFloatVec* dest, const float* array, int size); + +// Append float array to vector of arrays. +MJAPI void mjs_appendFloatVec(mjFloatVecVec* dest, const float* array, int size); + +// Copy double array to vector. +MJAPI void mjs_setDouble(mjDoubleVec* dest, const double* array, int size); + +// Set plugin attributes. +MJAPI void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes); + + +//---------------------------------- Attribute getters --------------------------------------------- + +// Get string contents. +MJAPI const char* mjs_getString(const mjString* source); + +// Get double array contents and optionally its size. +MJAPI const double* mjs_getDouble(const mjDoubleVec* source, int* size); + + +//---------------------------------- Spec utilities ------------------------------------------------ + +// Set active plugins. +MJAPI void mjs_setActivePlugins(mjSpec* s, void* activeplugins); + +// Set element's default. +MJAPI void mjs_setDefault(mjsElement* element, mjsDefault* def); + +// Set element's enlcosing frame. +MJAPI void mjs_setFrame(mjsElement* dest, mjsFrame* frame); + +// Resolve alternative orientations to quat, return error if any. +MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence, + 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 --------------------------------------- + +// Default spec attributes. +MJAPI void mjs_defaultSpec(mjSpec* spec); + +// Default orientation attributes. +MJAPI void mjs_defaultOrientation(mjsOrientation* orient); + +// Default body attributes. +MJAPI void mjs_defaultBody(mjsBody* body); + +// Default frame attributes. +MJAPI void mjs_defaultFrame(mjsFrame* frame); + +// Default joint attributes. +MJAPI void mjs_defaultJoint(mjsJoint* joint); + +// Default geom attributes. +MJAPI void mjs_defaultGeom(mjsGeom* geom); + +// Default site attributes. +MJAPI void mjs_defaultSite(mjsSite* site); + +// Default camera attributes. +MJAPI void mjs_defaultCamera(mjsCamera* camera); + +// Default light attributes. +MJAPI void mjs_defaultLight(mjsLight* light); + +// Default flex attributes. +MJAPI void mjs_defaultFlex(mjsFlex* flex); + +// Default mesh attributes. +MJAPI void mjs_defaultMesh(mjsMesh* mesh); + +// Default height field attributes. +MJAPI void mjs_defaultHField(mjsHField* hfield); + +// Default skin attributes. +MJAPI void mjs_defaultSkin(mjsSkin* skin); + +// Default texture attributes. +MJAPI void mjs_defaultTexture(mjsTexture* texture); + +// Default material attributes. +MJAPI void mjs_defaultMaterial(mjsMaterial* material); + +// Default pair attributes. +MJAPI void mjs_defaultPair(mjsPair* pair); + +// Default equality attributes. +MJAPI void mjs_defaultEquality(mjsEquality* equality); + +// Default tendon attributes. +MJAPI void mjs_defaultTendon(mjsTendon* tendon); + +// Default actuator attributes. +MJAPI void mjs_defaultActuator(mjsActuator* actuator); + +// Default sensor attributes. +MJAPI void mjs_defaultSensor(mjsSensor* sensor); + +// Default numeric attributes. +MJAPI void mjs_defaultNumeric(mjsNumeric* numeric); + +// Default text attributes. +MJAPI void mjs_defaultText(mjsText* text); + +// Default tuple attributes. +MJAPI void mjs_defaultTuple(mjsTuple* tuple); + +// Default keyframe attributes. +MJAPI void mjs_defaultKey(mjsKey* key); + +// Default plugin attributes. +MJAPI void mjs_defaultPlugin(mjsPlugin* plugin); + + +//---------------------------------- Sanitizer instrumentation ------------------------------------- + +// Most users can ignore these functions, the following comments are primarily for developers. // // When built and run under address sanitizer (asan), mj_markStack and mj_freeStack are instrumented // to detect leakage of mjData stack frames. When the compiler inlines several callees that call diff --git a/introspect/codegen/generate_structs.py b/introspect/codegen/generate_structs.py index 956b548f..42a5dcd1 100644 --- a/introspect/codegen/generate_structs.py +++ b/introspect/codegen/generate_structs.py @@ -123,7 +123,7 @@ class MjStructVisitor: """Makes a Decl object from a Clang AST RecordDecl node.""" name = f"{node['tagUsed']} {node['name']}" if 'name' in node else '' fields = [] - for child in node['inner']: + for child in node.get('inner', ()): child_kind = child.get('kind') if child_kind == 'FieldDecl': fields.append(self._make_field(child)) diff --git a/introspect/enums.py b/introspect/enums.py index 36a9e3a3..7d22f36f 100644 --- a/introspect/enums.py +++ b/introspect/enums.py @@ -686,6 +686,69 @@ ENUMS: Mapping[str, EnumDecl] = dict([ ('mjFONT_BIG', 2), ]), )), + ('mjtGeomInertia', + EnumDecl( + name='mjtGeomInertia', + declname='enum mjtGeomInertia_', + values=dict([ + ('mjINERTIA_VOLUME', 0), + ('mjINERTIA_SHELL', 1), + ]), + )), + ('mjtBuiltin', + EnumDecl( + name='mjtBuiltin', + declname='enum mjtBuiltin_', + values=dict([ + ('mjBUILTIN_NONE', 0), + ('mjBUILTIN_GRADIENT', 1), + ('mjBUILTIN_CHECKER', 2), + ('mjBUILTIN_FLAT', 3), + ]), + )), + ('mjtMark', + EnumDecl( + name='mjtMark', + declname='enum mjtMark_', + values=dict([ + ('mjMARK_NONE', 0), + ('mjMARK_EDGE', 1), + ('mjMARK_CROSS', 2), + ('mjMARK_RANDOM', 3), + ]), + )), + ('mjtLimited', + EnumDecl( + name='mjtLimited', + declname='enum mjtLimited_', + values=dict([ + ('mjLIMITED_FALSE', 0), + ('mjLIMITED_TRUE', 1), + ('mjLIMITED_AUTO', 2), + ]), + )), + ('mjtInertiaFromGeom', + EnumDecl( + name='mjtInertiaFromGeom', + declname='enum mjtInertiaFromGeom_', + values=dict([ + ('mjINERTIAFROMGEOM_FALSE', 0), + ('mjINERTIAFROMGEOM_TRUE', 1), + ('mjINERTIAFROMGEOM_AUTO', 2), + ]), + )), + ('mjtOrientation', + EnumDecl( + name='mjtOrientation', + declname='enum mjtOrientation_', + values=dict([ + ('mjORIENTATION_QUAT', 0), + ('mjORIENTATION_AXISANGLE', 1), + ('mjORIENTATION_XYAXES', 2), + ('mjORIENTATION_ZAXIS', 3), + ('mjORIENTATION_EULER', 4), + ]), + )), ('mjtButton', EnumDecl( name='mjtButton', diff --git a/introspect/functions.py b/introspect/functions.py index 2bb72499..a4cb5820 100644 --- a/introspect/functions.py +++ b/introspect/functions.py @@ -206,6 +206,124 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Parse XML file in MJCF or URDF format, compile it, return low-level model. If vfs is not NULL, look up files in vfs before reading from disk. If error is not NULL, it must have size error_sz.', # pylint: disable=line-too-long )), + ('mj_parseXML', + FunctionDecl( + name='mj_parseXML', + return_type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + parameters=( + FunctionParameterDecl( + name='filename', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='vfs', + type=PointerType( + inner_type=ValueType(name='mjVFS', is_const=True), + ), + ), + FunctionParameterDecl( + name='error', + type=PointerType( + inner_type=ValueType(name='char'), + ), + ), + FunctionParameterDecl( + name='error_sz', + type=ValueType(name='int'), + ), + ), + doc='Parse spec from XML file.', + )), + ('mj_parseXMLString', + FunctionDecl( + name='mj_parseXMLString', + return_type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + parameters=( + FunctionParameterDecl( + name='xml', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='vfs', + type=PointerType( + inner_type=ValueType(name='mjVFS', is_const=True), + ), + ), + FunctionParameterDecl( + name='error', + type=PointerType( + inner_type=ValueType(name='char'), + ), + ), + FunctionParameterDecl( + name='error_sz', + type=ValueType(name='int'), + ), + ), + doc='Parse spec from XML string.', + )), + ('mj_compile', + FunctionDecl( + name='mj_compile', + return_type=PointerType( + inner_type=ValueType(name='mjModel'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='vfs', + type=PointerType( + inner_type=ValueType(name='mjVFS', is_const=True), + ), + ), + ), + doc='Compile spec to model.', + )), + ('mj_recompile', + FunctionDecl( + name='mj_recompile', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='vfs', + type=PointerType( + inner_type=ValueType(name='mjVFS', is_const=True), + ), + ), + FunctionParameterDecl( + name='m', + type=PointerType( + inner_type=ValueType(name='mjModel'), + ), + ), + FunctionParameterDecl( + name='d', + type=PointerType( + inner_type=ValueType(name='mjData'), + ), + ), + ), + doc='Recompile spec to model, preserving the state.', + )), ('mj_saveLastXML', FunctionDecl( name='mj_saveLastXML', @@ -243,11 +361,71 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ parameters=(), doc='Free last XML model if loaded. Called internally at each load.', )), - ('mj_printSchema', + ('mj_copyBack', FunctionDecl( - name='mj_printSchema', + name='mj_copyBack', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='m', + type=PointerType( + inner_type=ValueType(name='mjModel', is_const=True), + ), + ), + ), + doc='Copy (possibly modified) model fields back into spec.', + )), + ('mj_saveXMLString', + FunctionDecl( + name='mj_saveXMLString', return_type=ValueType(name='int'), parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec', is_const=True), + ), + ), + FunctionParameterDecl( + name='xml', + type=PointerType( + inner_type=ValueType(name='char'), + ), + ), + FunctionParameterDecl( + name='xml_sz', + type=ValueType(name='int'), + ), + FunctionParameterDecl( + name='error', + type=PointerType( + inner_type=ValueType(name='char'), + ), + ), + FunctionParameterDecl( + name='error_sz', + type=ValueType(name='int'), + ), + ), + doc='Save spec to XML string, return 1 on success, 0 otherwise.', + )), + ('mj_saveXML', + FunctionDecl( + name='mj_saveXML', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec', is_const=True), + ), + ), FunctionParameterDecl( name='filename', type=PointerType( @@ -255,25 +433,17 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), ), FunctionParameterDecl( - name='buffer', + name='error', type=PointerType( inner_type=ValueType(name='char'), ), ), FunctionParameterDecl( - name='buffer_sz', - type=ValueType(name='int'), - ), - FunctionParameterDecl( - name='flg_html', - type=ValueType(name='int'), - ), - FunctionParameterDecl( - name='flg_pad', + name='error_sz', type=ValueType(name='int'), ), ), - doc='Print internal XML schema as plain text or HTML, with style-padding or  .', # pylint: disable=line-too-long + doc='Save spec to XML file, return 1 on success, 0 otherwise.', )), ('mj_step', FunctionDecl( @@ -880,6 +1050,45 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Set actuator_lengthrange for specified actuator; return 1 if ok, 0 if error.', # pylint: disable=line-too-long )), + ('mj_makeSpec', + FunctionDecl( + name='mj_makeSpec', + return_type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + parameters=(), + doc='Create empty spec.', + )), + ('mj_copySpec', + FunctionDecl( + name='mj_copySpec', + return_type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec', is_const=True), + ), + ), + ), + doc='Copy spec.', + )), + ('mj_deleteSpec', + FunctionDecl( + name='mj_deleteSpec', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Free memory allocation in mjSpec.', + )), ('mj_printFormattedModel', FunctionDecl( name='mj_printFormattedModel', @@ -1042,6 +1251,38 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Print sparse matrix to screen.', )), + ('mj_printSchema', + FunctionDecl( + name='mj_printSchema', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='filename', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='buffer', + type=PointerType( + inner_type=ValueType(name='char'), + ), + ), + FunctionParameterDecl( + name='buffer_sz', + type=ValueType(name='int'), + ), + FunctionParameterDecl( + name='flg_html', + type=ValueType(name='int'), + ), + FunctionParameterDecl( + name='flg_pad', + type=ValueType(name='int'), + ), + ), + doc='Print internal XML schema as plain text or HTML, with style-padding or  .', # pylint: disable=line-too-long + )), ('mj_fwdPosition', FunctionDecl( name='mj_fwdPosition', @@ -5537,6 +5778,36 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Write [datetime, type: message] to MUJOCO_LOG.TXT.', )), + ('mjs_getError', + FunctionDecl( + name='mjs_getError', + return_type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Get compiler error message from spec.', + )), + ('mjs_isWarning', + FunctionDecl( + name='mjs_isWarning', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Return 1 if compiler error is a warning.', + )), ('mju_zero3', FunctionDecl( name='mju_zero3', @@ -8590,4 +8861,1658 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([ ), doc='Wait for a task to complete.', )), + ('mjs_attachBody', + FunctionDecl( + name='mjs_attachBody', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='parent', + type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + ), + FunctionParameterDecl( + name='child', + type=PointerType( + inner_type=ValueType(name='mjsBody', is_const=True), + ), + ), + FunctionParameterDecl( + name='prefix', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='suffix', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Attach child body to a parent frame, return 0 on success.', + )), + ('mjs_attachFrame', + FunctionDecl( + name='mjs_attachFrame', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='parent', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='child', + type=PointerType( + inner_type=ValueType(name='mjsFrame', is_const=True), + ), + ), + FunctionParameterDecl( + name='prefix', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='suffix', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Attach child frame to a parent body, return 0 on success.', + )), + ('mjs_detachBody', + FunctionDecl( + name='mjs_detachBody', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='b', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + ), + doc='Detach body from mjSpec, remove all references and delete the body, return 0 on success.', # pylint: disable=line-too-long + )), + ('mjs_addBody', + FunctionDecl( + name='mjs_addBody', + return_type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add child body to body, return child.', + )), + ('mjs_addSite', + FunctionDecl( + name='mjs_addSite', + return_type=PointerType( + inner_type=ValueType(name='mjsSite'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add site to body, return site spec.', + )), + ('mjs_addJoint', + FunctionDecl( + name='mjs_addJoint', + return_type=PointerType( + inner_type=ValueType(name='mjsJoint'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add joint to body.', + )), + ('mjs_addFreeJoint', + FunctionDecl( + name='mjs_addFreeJoint', + return_type=PointerType( + inner_type=ValueType(name='mjsJoint'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + ), + doc='Add freejoint to body.', + )), + ('mjs_addGeom', + FunctionDecl( + name='mjs_addGeom', + return_type=PointerType( + inner_type=ValueType(name='mjsGeom'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add geom to body.', + )), + ('mjs_addCamera', + FunctionDecl( + name='mjs_addCamera', + return_type=PointerType( + inner_type=ValueType(name='mjsCamera'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add camera to body.', + )), + ('mjs_addLight', + FunctionDecl( + name='mjs_addLight', + return_type=PointerType( + inner_type=ValueType(name='mjsLight'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add light to body.', + )), + ('mjs_addFrame', + FunctionDecl( + name='mjs_addFrame', + return_type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='parentframe', + type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + ), + ), + doc='Add frame to body.', + )), + ('mjs_delete', + FunctionDecl( + name='mjs_delete', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + ), + doc='Delete object corresponding to the given element.', + )), + ('mjs_addActuator', + FunctionDecl( + name='mjs_addActuator', + return_type=PointerType( + inner_type=ValueType(name='mjsActuator'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add actuator.', + )), + ('mjs_addSensor', + FunctionDecl( + name='mjs_addSensor', + return_type=PointerType( + inner_type=ValueType(name='mjsSensor'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add sensor.', + )), + ('mjs_addFlex', + FunctionDecl( + name='mjs_addFlex', + return_type=PointerType( + inner_type=ValueType(name='mjsFlex'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add flex.', + )), + ('mjs_addPair', + FunctionDecl( + name='mjs_addPair', + return_type=PointerType( + inner_type=ValueType(name='mjsPair'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add contact pair.', + )), + ('mjs_addExclude', + FunctionDecl( + name='mjs_addExclude', + return_type=PointerType( + inner_type=ValueType(name='mjsExclude'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add excluded body pair.', + )), + ('mjs_addEquality', + FunctionDecl( + name='mjs_addEquality', + return_type=PointerType( + inner_type=ValueType(name='mjsEquality'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add equality.', + )), + ('mjs_addTendon', + FunctionDecl( + name='mjs_addTendon', + return_type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add tendon.', + )), + ('mjs_wrapSite', + FunctionDecl( + name='mjs_wrapSite', + return_type=PointerType( + inner_type=ValueType(name='mjsWrap'), + ), + parameters=( + FunctionParameterDecl( + name='tendon', + type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + ), + FunctionParameterDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Wrap site using tendon.', + )), + ('mjs_wrapGeom', + FunctionDecl( + name='mjs_wrapGeom', + return_type=PointerType( + inner_type=ValueType(name='mjsWrap'), + ), + parameters=( + FunctionParameterDecl( + name='tendon', + type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + ), + FunctionParameterDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='sidesite', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Wrap geom using tendon.', + )), + ('mjs_wrapJoint', + FunctionDecl( + name='mjs_wrapJoint', + return_type=PointerType( + inner_type=ValueType(name='mjsWrap'), + ), + parameters=( + FunctionParameterDecl( + name='tendon', + type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + ), + FunctionParameterDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='coef', + type=ValueType(name='double'), + ), + ), + doc='Wrap joint using tendon.', + )), + ('mjs_wrapPulley', + FunctionDecl( + name='mjs_wrapPulley', + return_type=PointerType( + inner_type=ValueType(name='mjsWrap'), + ), + parameters=( + FunctionParameterDecl( + name='tendon', + type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + ), + FunctionParameterDecl( + name='divisor', + type=ValueType(name='double'), + ), + ), + doc='Wrap pulley using tendon.', + )), + ('mjs_addNumeric', + FunctionDecl( + name='mjs_addNumeric', + return_type=PointerType( + inner_type=ValueType(name='mjsNumeric'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add numeric.', + )), + ('mjs_addText', + FunctionDecl( + name='mjs_addText', + return_type=PointerType( + inner_type=ValueType(name='mjsText'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add text.', + )), + ('mjs_addTuple', + FunctionDecl( + name='mjs_addTuple', + return_type=PointerType( + inner_type=ValueType(name='mjsTuple'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add tuple.', + )), + ('mjs_addKey', + FunctionDecl( + name='mjs_addKey', + return_type=PointerType( + inner_type=ValueType(name='mjsKey'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add keyframe.', + )), + ('mjs_addPlugin', + FunctionDecl( + name='mjs_addPlugin', + return_type=PointerType( + inner_type=ValueType(name='mjsPlugin'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add plugin.', + )), + ('mjs_addDefault', + FunctionDecl( + name='mjs_addDefault', + return_type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='classname', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='parentid', + type=ValueType(name='int'), + ), + FunctionParameterDecl( + name='id', + type=PointerType( + inner_type=ValueType(name='int'), + ), + ), + ), + doc='Add default.', + )), + ('mjs_addMesh', + FunctionDecl( + name='mjs_addMesh', + return_type=PointerType( + inner_type=ValueType(name='mjsMesh'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add mesh.', + )), + ('mjs_addHField', + FunctionDecl( + name='mjs_addHField', + return_type=PointerType( + inner_type=ValueType(name='mjsHField'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add height field.', + )), + ('mjs_addSkin', + FunctionDecl( + name='mjs_addSkin', + return_type=PointerType( + inner_type=ValueType(name='mjsSkin'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add skin.', + )), + ('mjs_addTexture', + FunctionDecl( + name='mjs_addTexture', + return_type=PointerType( + inner_type=ValueType(name='mjsTexture'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Add texture.', + )), + ('mjs_addMaterial', + FunctionDecl( + name='mjs_addMaterial', + return_type=PointerType( + inner_type=ValueType(name='mjsMaterial'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc='Add material.', + )), + ('mjs_getSpec', + FunctionDecl( + name='mjs_getSpec', + return_type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + ), + doc='Get spec from body.', + )), + ('mjs_findBody', + FunctionDecl( + name='mjs_findBody', + return_type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + 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 body in model by name.', + )), + ('mjs_findChild', + FunctionDecl( + name='mjs_findChild', + return_type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Find child body by name.', + )), + ('mjs_findMesh', + FunctionDecl( + name='mjs_findMesh', + return_type=PointerType( + inner_type=ValueType(name='mjsMesh'), + ), + 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 mesh by name.', + )), + ('mjs_findFrame', + FunctionDecl( + name='mjs_findFrame', + return_type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + 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 frame by name.', + )), + ('mjs_getDefault', + FunctionDecl( + name='mjs_getDefault', + return_type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + parameters=( + FunctionParameterDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + ), + doc='Get default corresponding to an element.', + )), + ('mjs_findDefault', + FunctionDecl( + name='mjs_findDefault', + return_type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='classname', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Find default in model by class name.', + )), + ('mjs_getSpecDefault', + FunctionDecl( + name='mjs_getSpecDefault', + return_type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Get global default from model.', + )), + ('mjs_getId', + FunctionDecl( + name='mjs_getId', + return_type=ValueType(name='int'), + parameters=( + FunctionParameterDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + ), + doc='Get element id.', + )), + ('mjs_firstChild', + FunctionDecl( + name='mjs_firstChild', + return_type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='type', + type=ValueType(name='mjtObj'), + ), + ), + doc="Return body's first child of given type.", + )), + ('mjs_nextChild', + FunctionDecl( + name='mjs_nextChild', + return_type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + FunctionParameterDecl( + name='child', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + ), + doc="Return body's next child of the same type; return NULL if child is last.", # pylint: disable=line-too-long + )), + ('mjs_setString', + FunctionDecl( + name='mjs_setString', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + ), + FunctionParameterDecl( + name='text', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Copy text to string.', + )), + ('mjs_setStringVec', + FunctionDecl( + name='mjs_setStringVec', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjStringVec'), + ), + ), + FunctionParameterDecl( + name='text', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Split text to entries and copy to string vector.', + )), + ('mjs_setInStringVec', + FunctionDecl( + name='mjs_setInStringVec', + return_type=ValueType(name='mjtByte'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjStringVec'), + ), + ), + FunctionParameterDecl( + name='i', + type=ValueType(name='int'), + ), + FunctionParameterDecl( + name='text', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Set entry in string vector.', + )), + ('mjs_appendString', + FunctionDecl( + name='mjs_appendString', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjStringVec'), + ), + ), + FunctionParameterDecl( + name='text', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + ), + doc='Append text entry to string vector.', + )), + ('mjs_setInt', + FunctionDecl( + name='mjs_setInt', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjIntVec'), + ), + ), + FunctionParameterDecl( + name='array', + type=PointerType( + inner_type=ValueType(name='int', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=ValueType(name='int'), + ), + ), + doc='Copy int array to vector.', + )), + ('mjs_appendIntVec', + FunctionDecl( + name='mjs_appendIntVec', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjIntVecVec'), + ), + ), + FunctionParameterDecl( + name='array', + type=PointerType( + inner_type=ValueType(name='int', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=ValueType(name='int'), + ), + ), + doc='Append int array to vector of arrays.', + )), + ('mjs_setFloat', + FunctionDecl( + name='mjs_setFloat', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjFloatVec'), + ), + ), + FunctionParameterDecl( + name='array', + type=PointerType( + inner_type=ValueType(name='float', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=ValueType(name='int'), + ), + ), + doc='Copy float array to vector.', + )), + ('mjs_appendFloatVec', + FunctionDecl( + name='mjs_appendFloatVec', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjFloatVecVec'), + ), + ), + FunctionParameterDecl( + name='array', + type=PointerType( + inner_type=ValueType(name='float', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=ValueType(name='int'), + ), + ), + doc='Append float array to vector of arrays.', + )), + ('mjs_setDouble', + FunctionDecl( + name='mjs_setDouble', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjDoubleVec'), + ), + ), + FunctionParameterDecl( + name='array', + type=PointerType( + inner_type=ValueType(name='double', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=ValueType(name='int'), + ), + ), + doc='Copy double array to vector.', + )), + ('mjs_setPluginAttributes', + FunctionDecl( + name='mjs_setPluginAttributes', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='plugin', + type=PointerType( + inner_type=ValueType(name='mjsPlugin'), + ), + ), + FunctionParameterDecl( + name='attributes', + type=PointerType( + inner_type=ValueType(name='void'), + ), + ), + ), + doc='Set plugin attributes.', + )), + ('mjs_getString', + FunctionDecl( + name='mjs_getString', + return_type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + parameters=( + FunctionParameterDecl( + name='source', + type=PointerType( + inner_type=ValueType(name='mjString', is_const=True), + ), + ), + ), + doc='Get string contents.', + )), + ('mjs_getDouble', + FunctionDecl( + name='mjs_getDouble', + return_type=PointerType( + inner_type=ValueType(name='double', is_const=True), + ), + parameters=( + FunctionParameterDecl( + name='source', + type=PointerType( + inner_type=ValueType(name='mjDoubleVec', is_const=True), + ), + ), + FunctionParameterDecl( + name='size', + type=PointerType( + inner_type=ValueType(name='int'), + ), + ), + ), + doc='Get double array contents and optionally its size.', + )), + ('mjs_setActivePlugins', + FunctionDecl( + name='mjs_setActivePlugins', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='s', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + FunctionParameterDecl( + name='activeplugins', + type=PointerType( + inner_type=ValueType(name='void'), + ), + ), + ), + doc='Set active plugins.', + )), + ('mjs_setDefault', + FunctionDecl( + name='mjs_setDefault', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + FunctionParameterDecl( + name='def', + type=PointerType( + inner_type=ValueType(name='mjsDefault'), + ), + ), + ), + doc="Set element's default.", + )), + ('mjs_setFrame', + FunctionDecl( + name='mjs_setFrame', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='dest', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + ), + FunctionParameterDecl( + name='frame', + type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + ), + ), + doc="Set element's enlcosing frame.", + )), + ('mjs_resolveOrientation', + FunctionDecl( + name='mjs_resolveOrientation', + 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='degree', + type=ValueType(name='mjtByte'), + ), + FunctionParameterDecl( + name='sequence', + type=PointerType( + inner_type=ValueType(name='char', is_const=True), + ), + ), + FunctionParameterDecl( + name='orientation', + type=PointerType( + inner_type=ValueType(name='mjsOrientation', is_const=True), + ), + ), + ), + 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', + FunctionDecl( + name='mjs_defaultSpec', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='spec', + type=PointerType( + inner_type=ValueType(name='mjSpec'), + ), + ), + ), + doc='Default spec attributes.', + )), + ('mjs_defaultOrientation', + FunctionDecl( + name='mjs_defaultOrientation', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='orient', + type=PointerType( + inner_type=ValueType(name='mjsOrientation'), + ), + ), + ), + doc='Default orientation attributes.', + )), + ('mjs_defaultBody', + FunctionDecl( + name='mjs_defaultBody', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='body', + type=PointerType( + inner_type=ValueType(name='mjsBody'), + ), + ), + ), + doc='Default body attributes.', + )), + ('mjs_defaultFrame', + FunctionDecl( + name='mjs_defaultFrame', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='frame', + type=PointerType( + inner_type=ValueType(name='mjsFrame'), + ), + ), + ), + doc='Default frame attributes.', + )), + ('mjs_defaultJoint', + FunctionDecl( + name='mjs_defaultJoint', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='joint', + type=PointerType( + inner_type=ValueType(name='mjsJoint'), + ), + ), + ), + doc='Default joint attributes.', + )), + ('mjs_defaultGeom', + FunctionDecl( + name='mjs_defaultGeom', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='geom', + type=PointerType( + inner_type=ValueType(name='mjsGeom'), + ), + ), + ), + doc='Default geom attributes.', + )), + ('mjs_defaultSite', + FunctionDecl( + name='mjs_defaultSite', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='site', + type=PointerType( + inner_type=ValueType(name='mjsSite'), + ), + ), + ), + doc='Default site attributes.', + )), + ('mjs_defaultCamera', + FunctionDecl( + name='mjs_defaultCamera', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='camera', + type=PointerType( + inner_type=ValueType(name='mjsCamera'), + ), + ), + ), + doc='Default camera attributes.', + )), + ('mjs_defaultLight', + FunctionDecl( + name='mjs_defaultLight', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='light', + type=PointerType( + inner_type=ValueType(name='mjsLight'), + ), + ), + ), + doc='Default light attributes.', + )), + ('mjs_defaultFlex', + FunctionDecl( + name='mjs_defaultFlex', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='flex', + type=PointerType( + inner_type=ValueType(name='mjsFlex'), + ), + ), + ), + doc='Default flex attributes.', + )), + ('mjs_defaultMesh', + FunctionDecl( + name='mjs_defaultMesh', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='mesh', + type=PointerType( + inner_type=ValueType(name='mjsMesh'), + ), + ), + ), + doc='Default mesh attributes.', + )), + ('mjs_defaultHField', + FunctionDecl( + name='mjs_defaultHField', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='hfield', + type=PointerType( + inner_type=ValueType(name='mjsHField'), + ), + ), + ), + doc='Default height field attributes.', + )), + ('mjs_defaultSkin', + FunctionDecl( + name='mjs_defaultSkin', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='skin', + type=PointerType( + inner_type=ValueType(name='mjsSkin'), + ), + ), + ), + doc='Default skin attributes.', + )), + ('mjs_defaultTexture', + FunctionDecl( + name='mjs_defaultTexture', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='texture', + type=PointerType( + inner_type=ValueType(name='mjsTexture'), + ), + ), + ), + doc='Default texture attributes.', + )), + ('mjs_defaultMaterial', + FunctionDecl( + name='mjs_defaultMaterial', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='material', + type=PointerType( + inner_type=ValueType(name='mjsMaterial'), + ), + ), + ), + doc='Default material attributes.', + )), + ('mjs_defaultPair', + FunctionDecl( + name='mjs_defaultPair', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='pair', + type=PointerType( + inner_type=ValueType(name='mjsPair'), + ), + ), + ), + doc='Default pair attributes.', + )), + ('mjs_defaultEquality', + FunctionDecl( + name='mjs_defaultEquality', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='equality', + type=PointerType( + inner_type=ValueType(name='mjsEquality'), + ), + ), + ), + doc='Default equality attributes.', + )), + ('mjs_defaultTendon', + FunctionDecl( + name='mjs_defaultTendon', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='tendon', + type=PointerType( + inner_type=ValueType(name='mjsTendon'), + ), + ), + ), + doc='Default tendon attributes.', + )), + ('mjs_defaultActuator', + FunctionDecl( + name='mjs_defaultActuator', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='actuator', + type=PointerType( + inner_type=ValueType(name='mjsActuator'), + ), + ), + ), + doc='Default actuator attributes.', + )), + ('mjs_defaultSensor', + FunctionDecl( + name='mjs_defaultSensor', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='sensor', + type=PointerType( + inner_type=ValueType(name='mjsSensor'), + ), + ), + ), + doc='Default sensor attributes.', + )), + ('mjs_defaultNumeric', + FunctionDecl( + name='mjs_defaultNumeric', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='numeric', + type=PointerType( + inner_type=ValueType(name='mjsNumeric'), + ), + ), + ), + doc='Default numeric attributes.', + )), + ('mjs_defaultText', + FunctionDecl( + name='mjs_defaultText', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='text', + type=PointerType( + inner_type=ValueType(name='mjsText'), + ), + ), + ), + doc='Default text attributes.', + )), + ('mjs_defaultTuple', + FunctionDecl( + name='mjs_defaultTuple', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='tuple', + type=PointerType( + inner_type=ValueType(name='mjsTuple'), + ), + ), + ), + doc='Default tuple attributes.', + )), + ('mjs_defaultKey', + FunctionDecl( + name='mjs_defaultKey', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='key', + type=PointerType( + inner_type=ValueType(name='mjsKey'), + ), + ), + ), + doc='Default keyframe attributes.', + )), + ('mjs_defaultPlugin', + FunctionDecl( + name='mjs_defaultPlugin', + return_type=ValueType(name='void'), + parameters=( + FunctionParameterDecl( + name='plugin', + type=PointerType( + inner_type=ValueType(name='mjsPlugin'), + ), + ), + ), + doc='Default plugin attributes.', + )), ]) diff --git a/introspect/structs.py b/introspect/structs.py index f5c26e18..cdd5ff1b 100644 --- a/introspect/structs.py +++ b/introspect/structs.py @@ -8147,6 +8147,2997 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), ), )), + ('mjsElement', + StructDecl( + name='mjsElement', + declname='struct mjsElement_', + fields=( + StructFieldDecl( + name='elemtype', + type=ValueType(name='mjtObj'), + doc='element type', + ), + ), + )), + ('mjSpec', + StructDecl( + name='mjSpec', + declname='struct mjSpec_', + fields=( + StructFieldDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='modelname', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='model name', + ), + StructFieldDecl( + name='autolimits', + type=ValueType(name='mjtByte'), + doc='infer "limited" attribute based on range', + ), + StructFieldDecl( + name='boundmass', + type=ValueType(name='double'), + doc='enforce minimum body mass', + ), + StructFieldDecl( + name='boundinertia', + type=ValueType(name='double'), + doc='enforce minimum body diagonal inertia', + ), + StructFieldDecl( + name='settotalmass', + type=ValueType(name='double'), + doc='rescale masses and inertias;<=0: ignore', + ), + StructFieldDecl( + name='balanceinertia', + type=ValueType(name='mjtByte'), + doc='automatically impose A + B >= C rule', + ), + StructFieldDecl( + name='strippath', + type=ValueType(name='mjtByte'), + doc='automatically strip paths from mesh files', + ), + StructFieldDecl( + name='fitaabb', + type=ValueType(name='mjtByte'), + doc='meshfit to aabb instead of inertia box', + ), + StructFieldDecl( + name='degree', + type=ValueType(name='mjtByte'), + doc='angles in radians or degrees', + ), + StructFieldDecl( + name='euler', + type=ArrayType( + inner_type=ValueType(name='char'), + extents=(3,), + ), + doc='sequence for euler rotations', + ), + StructFieldDecl( + name='meshdir', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='mesh and hfield directory', + ), + StructFieldDecl( + name='texturedir', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='texture directory', + ), + StructFieldDecl( + name='discardvisual', + type=ValueType(name='mjtByte'), + doc='discard visual geoms in parser', + ), + StructFieldDecl( + name='convexhull', + type=ValueType(name='mjtByte'), + doc='compute mesh convex hulls', + ), + StructFieldDecl( + name='usethread', + type=ValueType(name='mjtByte'), + doc='use multiple threads to speed up compiler', + ), + StructFieldDecl( + name='fusestatic', + type=ValueType(name='mjtByte'), + doc='fuse static bodies with parent', + ), + StructFieldDecl( + name='inertiafromgeom', + type=ValueType(name='int'), + doc='use geom inertias (mjtInertiaFromGeom)', + ), + StructFieldDecl( + name='inertiagrouprange', + type=ArrayType( + inner_type=ValueType(name='int'), + extents=(2,), + ), + doc='range of geom groups used to compute inertia', + ), + StructFieldDecl( + name='exactmeshinertia', + type=ValueType(name='mjtByte'), + doc='if false, use old formula', + ), + StructFieldDecl( + name='LRopt', + type=ValueType(name='mjLROpt'), + doc='options for lengthrange computation', + ), + StructFieldDecl( + name='option', + type=ValueType(name='mjOption'), + doc='physics options', + ), + StructFieldDecl( + name='visual', + type=ValueType(name='mjVisual'), + doc='visual options', + ), + StructFieldDecl( + name='stat', + type=ValueType(name='mjStatistic'), + doc='statistics override (if defined)', + ), + StructFieldDecl( + name='memory', + type=ValueType(name='size_t'), + doc='number of bytes in arena+stack memory', + ), + StructFieldDecl( + name='nemax', + type=ValueType(name='int'), + doc='max number of equality constraints', + ), + StructFieldDecl( + name='nuserdata', + type=ValueType(name='int'), + doc='number of mjtNums in userdata', + ), + StructFieldDecl( + name='nuser_body', + type=ValueType(name='int'), + doc='number of mjtNums in body_user', + ), + StructFieldDecl( + name='nuser_jnt', + type=ValueType(name='int'), + doc='number of mjtNums in jnt_user', + ), + StructFieldDecl( + name='nuser_geom', + type=ValueType(name='int'), + doc='number of mjtNums in geom_user', + ), + StructFieldDecl( + name='nuser_site', + type=ValueType(name='int'), + doc='number of mjtNums in site_user', + ), + StructFieldDecl( + name='nuser_cam', + type=ValueType(name='int'), + doc='number of mjtNums in cam_user', + ), + StructFieldDecl( + name='nuser_tendon', + type=ValueType(name='int'), + doc='number of mjtNums in tendon_user', + ), + StructFieldDecl( + name='nuser_actuator', + type=ValueType(name='int'), + doc='number of mjtNums in actuator_user', + ), + StructFieldDecl( + name='nuser_sensor', + type=ValueType(name='int'), + doc='number of mjtNums in sensor_user', + ), + StructFieldDecl( + name='nkey', + type=ValueType(name='int'), + doc='number of keyframes', + ), + StructFieldDecl( + name='njmax', + type=ValueType(name='int'), + doc='(deprecated) max number of constraints', + ), + StructFieldDecl( + name='nconmax', + type=ValueType(name='int'), + doc='(deprecated) max number of detected contacts', + ), + StructFieldDecl( + name='nstack', + type=ValueType(name='size_t'), + doc='(deprecated) number of mjtNums in mjData stack', + ), + StructFieldDecl( + name='comment', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='comment at top of XML', + ), + StructFieldDecl( + name='modelfiledir', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='path to model file', + ), + StructFieldDecl( + name='hasImplicitPluginElem', + type=ValueType(name='mjtByte'), + doc='already encountered an implicit plugin sensor/actuator', + ), + ), + )), + ('mjsOrientation', + StructDecl( + name='mjsOrientation', + declname='struct mjsOrientation_', + fields=( + StructFieldDecl( + name='type', + type=ValueType(name='mjtOrientation'), + doc='active orientation specifier', + ), + StructFieldDecl( + name='axisangle', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(4,), + ), + doc='axis and angle', + ), + StructFieldDecl( + name='xyaxes', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(6,), + ), + doc='x and y axes', + ), + StructFieldDecl( + name='zaxis', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='z axis (minimal rotation)', + ), + StructFieldDecl( + name='euler', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='Euler angles', + ), + ), + )), + ('mjsPlugin', + StructDecl( + name='mjsPlugin', + declname='struct mjsPlugin_', + fields=( + StructFieldDecl( + name='instance', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='name', + ), + StructFieldDecl( + name='instance_name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='instance name', + ), + StructFieldDecl( + name='plugin_slot', + type=ValueType(name='int'), + doc='global registered slot number of the plugin', + ), + StructFieldDecl( + name='active', + type=ValueType(name='mjtByte'), + doc='is the plugin active', + ), + StructFieldDecl( + name='info', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='message appended to compiler errors', + ), + ), + )), + ('mjsBody', + StructDecl( + name='mjsBody', + declname='struct mjsBody_', + fields=( + StructFieldDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='name', + ), + StructFieldDecl( + name='childclass', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='childclass name', + ), + StructFieldDecl( + name='pos', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='frame position', + ), + StructFieldDecl( + name='quat', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(4,), + ), + doc='frame orientation', + ), + StructFieldDecl( + name='alt', + type=ValueType(name='mjsOrientation'), + doc='frame alternative orientation', + ), + StructFieldDecl( + name='mass', + type=ValueType(name='double'), + doc='mass', + ), + StructFieldDecl( + name='ipos', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='inertial frame position', + ), + StructFieldDecl( + name='iquat', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(4,), + ), + doc='inertial frame orientation', + ), + StructFieldDecl( + name='inertia', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='diagonal inertia (in i-frame)', + ), + StructFieldDecl( + name='ialt', + type=ValueType(name='mjsOrientation'), + doc='inertial frame alternative orientation', + ), + StructFieldDecl( + name='fullinertia', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(6,), + ), + doc='non-axis-aligned inertia matrix', + ), + StructFieldDecl( + name='mocap', + type=ValueType(name='mjtByte'), + doc='is this a mocap body', + ), + StructFieldDecl( + name='gravcomp', + type=ValueType(name='double'), + doc='gravity compensation', + ), + StructFieldDecl( + name='userdata', + type=PointerType( + inner_type=ValueType(name='mjDoubleVec'), + ), + doc='user data', + ), + StructFieldDecl( + name='explicitinertial', + type=ValueType(name='mjtByte'), + doc='whether to save the body with explicit inertial clause', + ), + StructFieldDecl( + name='plugin', + type=ValueType(name='mjsPlugin'), + doc='passive force plugin', + ), + StructFieldDecl( + name='info', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='message appended to compiler errors', + ), + ), + )), + ('mjsFrame', + StructDecl( + name='mjsFrame', + declname='struct mjsFrame_', + fields=( + StructFieldDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='name', + ), + StructFieldDecl( + name='childclass', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='childclass name', + ), + StructFieldDecl( + name='pos', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='position', + ), + StructFieldDecl( + name='quat', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(4,), + ), + doc='orientation', + ), + StructFieldDecl( + name='alt', + type=ValueType(name='mjsOrientation'), + doc='alternative orientation', + ), + StructFieldDecl( + name='info', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='message appended to compiler errors', + ), + ), + )), + ('mjsJoint', + StructDecl( + name='mjsJoint', + declname='struct mjsJoint_', + fields=( + StructFieldDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='name', + ), + StructFieldDecl( + name='classname', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='class name', + ), + StructFieldDecl( + name='type', + type=ValueType(name='mjtJoint'), + doc='joint type', + ), + StructFieldDecl( + name='pos', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='anchor position', + ), + StructFieldDecl( + name='axis', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='joint axis', + ), + StructFieldDecl( + name='ref', + type=ValueType(name='double'), + doc='value at reference configuration: qpos0', + ), + StructFieldDecl( + name='stiffness', + type=ValueType(name='double'), + doc='stiffness coefficient', + ), + StructFieldDecl( + name='springref', + type=ValueType(name='double'), + doc='spring reference value: qpos_spring', + ), + StructFieldDecl( + name='springdamper', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(2,), + ), + doc='timeconst, dampratio', + ), + StructFieldDecl( + name='limited', + type=ValueType(name='int'), + doc='does joint have limits (mjtLimited)', + ), + StructFieldDecl( + name='range', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(2,), + ), + doc='joint limits', + ), + StructFieldDecl( + name='margin', + type=ValueType(name='double'), + doc='margin value for joint limit detection', + ), + StructFieldDecl( + name='solref_limit', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(2,), + ), + doc='solver reference: joint limits', + ), + StructFieldDecl( + name='solimp_limit', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(5,), + ), + doc='solver impedance: joint limits', + ), + StructFieldDecl( + name='actfrclimited', + type=ValueType(name='int'), + doc='are actuator forces on joint limited (mjtLimited)', + ), + StructFieldDecl( + name='actfrcrange', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(2,), + ), + doc='actuator force limits', + ), + StructFieldDecl( + name='armature', + type=ValueType(name='double'), + doc='armature inertia (mass for slider)', + ), + StructFieldDecl( + name='damping', + type=ValueType(name='double'), + doc='damping coefficient', + ), + StructFieldDecl( + name='frictionloss', + type=ValueType(name='double'), + doc='friction loss', + ), + StructFieldDecl( + name='solref_friction', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(2,), + ), + doc='solver reference: dof friction', + ), + StructFieldDecl( + name='solimp_friction', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(5,), + ), + doc='solver impedance: dof friction', + ), + StructFieldDecl( + name='group', + type=ValueType(name='int'), + doc='group', + ), + StructFieldDecl( + name='actgravcomp', + type=ValueType(name='mjtByte'), + doc='is gravcomp force applied via actuators', + ), + StructFieldDecl( + name='userdata', + type=PointerType( + inner_type=ValueType(name='mjDoubleVec'), + ), + doc='user data', + ), + StructFieldDecl( + name='info', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='message appended to compiler errors', + ), + ), + )), + ('mjsGeom', + StructDecl( + name='mjsGeom', + declname='struct mjsGeom_', + fields=( + StructFieldDecl( + name='element', + type=PointerType( + inner_type=ValueType(name='mjsElement'), + ), + doc='element type', + ), + StructFieldDecl( + name='name', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='name', + ), + StructFieldDecl( + name='classname', + type=PointerType( + inner_type=ValueType(name='mjString'), + ), + doc='classname', + ), + StructFieldDecl( + name='type', + type=ValueType(name='mjtGeom'), + doc='geom type', + ), + StructFieldDecl( + name='pos', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='position', + ), + StructFieldDecl( + name='quat', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(4,), + ), + doc='orientation', + ), + StructFieldDecl( + name='alt', + type=ValueType(name='mjsOrientation'), + doc='alternative orientation', + ), + StructFieldDecl( + name='fromto', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(6,), + ), + doc='alternative for capsule, cylinder, box, ellipsoid', + ), + StructFieldDecl( + name='size', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='type-specific size', + ), + StructFieldDecl( + name='contype', + type=ValueType(name='int'), + doc='contact type', + ), + StructFieldDecl( + name='conaffinity', + type=ValueType(name='int'), + doc='contact affinity', + ), + StructFieldDecl( + name='condim', + type=ValueType(name='int'), + doc='contact dimensionality', + ), + StructFieldDecl( + name='priority', + type=ValueType(name='int'), + doc='contact priority', + ), + StructFieldDecl( + name='friction', + type=ArrayType( + inner_type=ValueType(name='double'), + extents=(3,), + ), + doc='one-sided friction coefficients: slide, roll, spin', + ), + StructFieldDecl( + name='solmix', + type=ValueType(name='double'), + doc='solver mixing for contact pairs', + ), + StructFieldDecl( + name='solref', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(2,), + ), + doc='solver reference', + ), + StructFieldDecl( + name='solimp', + type=ArrayType( + inner_type=ValueType(name='mjtNum'), + extents=(5,), + ), + doc='solver impedance', + ), + StructFieldDecl( + name='margin', + type=ValueType(name='double'), + doc='margin for contact detection', + ), + StructFieldDecl( + name='gap', + type=ValueType(name='double'), + doc='include in solver if distspec; } @@ -60,7 +60,7 @@ mjSpec* mjs_createSpec() { // copy model -mjSpec* mjs_copySpec(const mjSpec* s) { +mjSpec* mj_copySpec(const mjSpec* s) { mjCModel* modelC = new mjCModel(*static_cast(s->element)); return &modelC->spec; } @@ -68,7 +68,7 @@ mjSpec* mjs_copySpec(const mjSpec* s) { // copy back model -void mjs_copyBack(mjSpec* s, const mjModel* m) { +void mj_copyBack(mjSpec* s, const mjModel* m) { mjCModel* modelC = static_cast(s->element); modelC->CopyBack(m); } @@ -76,7 +76,7 @@ void mjs_copyBack(mjSpec* s, const mjModel* m) { // compile model -mjModel* mjs_compile(mjSpec* s, const mjVFS* vfs) { +mjModel* mj_compile(mjSpec* s, const mjVFS* vfs) { mjCModel* modelC = static_cast(s->element); return modelC->Compile(vfs); } @@ -84,7 +84,7 @@ mjModel* mjs_compile(mjSpec* s, const mjVFS* vfs) { // recompile spec into existing model and data while preserving the state -void mjs_recompile(mjSpec* s, const mjVFS* vfs, mjModel* m, mjData* d) { +void mj_recompile(mjSpec* s, const mjVFS* vfs, mjModel* m, mjData* d) { mjCModel* modelC = static_cast(s->element); modelC->SaveState(d); modelC->Compile(vfs, &m); @@ -143,7 +143,7 @@ int mjs_isWarning(mjSpec* s) { // delete model -void mjs_deleteSpec(mjSpec* s) { +void mj_deleteSpec(mjSpec* s) { mjCModel* model = static_cast(s->element); delete model; } @@ -151,7 +151,7 @@ void mjs_deleteSpec(mjSpec* s) { // delete object, it will call the appropriate destructor since ~mjCBase is virtual -void mjs_delete(mjElement* element) { +void mjs_delete(mjsElement* element) { mjCBase* object = static_cast(element); delete object; } @@ -430,7 +430,7 @@ mjsKey* mjs_addKey(mjSpec* s) { mjsPlugin* mjs_addPlugin(mjSpec* s) { mjCModel* modelC = static_cast(s->element); mjCPlugin* plugin = modelC->AddPlugin(); - plugin->spec.instance = static_cast(plugin); + plugin->spec.instance = static_cast(plugin); return &plugin->spec; } @@ -458,7 +458,7 @@ mjSpec* mjs_getSpec(mjsBody* body) { // get default -mjsDefault* mjs_getDefault(mjElement* element) { +mjsDefault* mjs_getDefault(mjsElement* element) { return &(static_cast(element)->def->spec); } @@ -530,7 +530,7 @@ mjsFrame* mjs_findFrame(mjSpec* s, const char* name) { // set frame -void mjs_setFrame(mjElement* dest, mjsFrame* frame) { +void mjs_setFrame(mjsElement* dest, mjsFrame* frame) { if (!frame) { return; } @@ -550,14 +550,14 @@ const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* s // get id -int mjs_getId(mjElement* element) { +int mjs_getId(mjsElement* element) { return static_cast(element)->id; } // set default -void mjs_setDefault(mjElement* element, mjsDefault* defspec) { +void mjs_setDefault(mjsElement* element, mjsDefault* defspec) { mjCBase* baseC = static_cast(element); baseC->def = static_cast(defspec->element); } @@ -565,7 +565,7 @@ void mjs_setDefault(mjElement* element, mjsDefault* defspec) { // return first child of selected type -mjElement* mjs_firstChild(mjsBody* body, mjtObj type) { +mjsElement* mjs_firstChild(mjsBody* body, mjtObj type) { mjCBody* bodyC = static_cast(body->element); return bodyC->NextChild(NULL, type); } @@ -573,7 +573,7 @@ mjElement* mjs_firstChild(mjsBody* body, mjtObj type) { // return body's next child; return NULL if child is last -mjElement* mjs_nextChild(mjsBody* body, mjElement* child) { +mjsElement* mjs_nextChild(mjsBody* body, mjsElement* child) { mjCBody* bodyC = static_cast(body->element); return bodyC->NextChild(child); } diff --git a/src/user/user_api.h b/src/user/user_api.h index 1908791f..d7c03f0f 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -33,749 +34,19 @@ extern "C" { #define mjNAN NAN // used to mark undefined fields - -//---------------------------------- C/C++ handles to strings and arrays --------------------------- - -#ifdef __cplusplus - // C++, defined to be compatible with corresponding std types - using mjString = std::string; - using mjStringVec = std::vector; - using mjIntVec = std::vector; - using mjIntVecVec = std::vector>; - using mjFloatVec = std::vector; - using mjFloatVecVec = std::vector>; - using mjDoubleVec = std::vector; -#else - // C, opaque pointers - typedef struct mjString_ mjString; - typedef struct mjStringVec_ mjStringVec; - typedef struct mjIntVec_ mjIntVec; - typedef struct mjIntVecVec_ mjIntVecVec; - typedef struct mjFloatVec_ mjFloatVec; - typedef struct mjFloatVecVec_ mjFloatVecVec; - typedef struct mjDoubleVec_ mjDoubleVec; -#endif - - -//---------------------------------- enum types (mjt) ---------------------------------------------- - -typedef enum mjtGeomInertia_ { // type of inertia inference - mjINERTIA_VOLUME, // mass distributed in the volume - mjINERTIA_SHELL, // mass distributed on the surface -} mjtGeomInertia; - - -typedef enum mjtBuiltin_ { // type of built-in procedural texture - mjBUILTIN_NONE = 0, // no built-in texture - mjBUILTIN_GRADIENT, // gradient: rgb1->rgb2 - mjBUILTIN_CHECKER, // checker pattern: rgb1, rgb2 - mjBUILTIN_FLAT // 2d: rgb1; cube: rgb1-up, rgb2-side, rgb3-down -} mjtBuiltin; - - -typedef enum mjtMark_ { // mark type for procedural textures - mjMARK_NONE = 0, // no mark - mjMARK_EDGE, // edges - mjMARK_CROSS, // cross - mjMARK_RANDOM // random dots -} mjtMark; - - -typedef enum mjtLimited_ { // type of limit specification - mjLIMITED_FALSE = 0, // not limited - mjLIMITED_TRUE, // limited - mjLIMITED_AUTO, // limited inferred from presence of range -} mjtLimited; - - -typedef enum mjtInertiaFromGeom_ { // whether to infer body inertias from child geoms - mjINERTIAFROMGEOM_FALSE = 0, // do not use; inertial element required - mjINERTIAFROMGEOM_TRUE, // always use; overwrite inertial element - mjINERTIAFROMGEOM_AUTO // use only if inertial element is missing -} mjtInertiaFromGeom; - - -typedef enum mjtOrientation_ { // type of orientation specifier - mjORIENTATION_QUAT = 0, // quaternion - mjORIENTATION_AXISANGLE, // axis and angle - mjORIENTATION_XYAXES, // x and y axes - mjORIENTATION_ZAXIS, // z axis (minimal rotation) - mjORIENTATION_EULER, // Euler angles -} mjtOrientation; - - -//---------------------------------- attribute structs (mjs) --------------------------------------- - -typedef struct mjElement_ { // element type, do not modify - mjtObj elemtype; // element type -} mjElement; - - -typedef struct mjSpec_ { // model specification - mjElement* element; // element type - mjString* modelname; // model name - - // compiler settings - mjtByte autolimits; // infer "limited" attribute based on range - double boundmass; // enforce minimum body mass - double boundinertia; // enforce minimum body diagonal inertia - double settotalmass; // rescale masses and inertias; <=0: ignore - mjtByte balanceinertia; // automatically impose A + B >= C rule - mjtByte strippath; // automatically strip paths from mesh files - mjtByte fitaabb; // meshfit to aabb instead of inertia box - mjtByte degree; // angles in radians or degrees - char euler[3]; // sequence for euler rotations - mjString* meshdir; // mesh and hfield directory - mjString* texturedir; // texture directory - mjtByte discardvisual; // discard visual geoms in parser - mjtByte convexhull; // compute mesh convex hulls - mjtByte usethread; // use multiple threads to speed up compiler - mjtByte fusestatic; // fuse static bodies with parent - int inertiafromgeom; // use geom inertias (mjtInertiaFromGeom) - int inertiagrouprange[2]; // range of geom groups used to compute inertia - mjtByte exactmeshinertia; // if false, use old formula - mjLROpt LRopt; // options for lengthrange computation - - // engine data - mjOption option; // physics options - mjVisual visual; // visual options - mjStatistic stat; // statistics override (if defined) - - // sizes - size_t memory; // number of bytes in arena+stack memory - int nemax; // max number of equality constraints - int nuserdata; // number of mjtNums in userdata - int nuser_body; // number of mjtNums in body_user - int nuser_jnt; // number of mjtNums in jnt_user - int nuser_geom; // number of mjtNums in geom_user - int nuser_site; // number of mjtNums in site_user - int nuser_cam; // number of mjtNums in cam_user - int nuser_tendon; // number of mjtNums in tendon_user - int nuser_actuator; // number of mjtNums in actuator_user - int nuser_sensor; // number of mjtNums in sensor_user - int nkey; // number of keyframes - int njmax; // (deprecated) max number of constraints - int nconmax; // (deprecated) max number of detected contacts - size_t nstack; // (deprecated) number of mjtNums in mjData stack - - // global data - mjString* comment; // comment at top of XML - mjString* modelfiledir; // path to model file - - // other - mjtByte hasImplicitPluginElem; // already encountered an implicit plugin sensor/actuator -} mjSpec; - - -typedef struct mjsOrientation_ { // alternative orientation specifiers - mjtOrientation type; // active orientation specifier - double axisangle[4]; // axis and angle - double xyaxes[6]; // x and y axes - double zaxis[3]; // z axis (minimal rotation) - double euler[3]; // Euler angles -} mjsOrientation; - - -typedef struct mjsPlugin_ { // plugin specification - mjElement* instance; // element type - mjString* name; // name - mjString* instance_name; // instance name - int plugin_slot; // global registered slot number of the plugin - mjtByte active; // is the plugin active - mjString* info; // message appended to compiler errors -} mjsPlugin; - - -typedef struct mjsBody_ { // body specification - mjElement* element; // element type - mjString* name; // name - mjString* childclass; // childclass name - - // body frame - double pos[3]; // frame position - double quat[4]; // frame orientation - mjsOrientation alt; // frame alternative orientation - - // inertial frame - double mass; // mass - double ipos[3]; // inertial frame position - double iquat[4]; // inertial frame orientation - double inertia[3]; // diagonal inertia (in i-frame) - mjsOrientation ialt; // inertial frame alternative orientation - double fullinertia[6]; // non-axis-aligned inertia matrix - - // other - mjtByte mocap; // is this a mocap body - double gravcomp; // gravity compensation - mjDoubleVec* userdata; // user data - mjtByte explicitinertial; // whether to save the body with explicit inertial clause - mjsPlugin plugin; // passive force plugin - mjString* info; // message appended to compiler errors -} mjsBody; - - -typedef struct mjsFrame_ { // frame specification - mjElement* element; // element type - mjString* name; // name - mjString* childclass; // childclass name - double pos[3]; // position - double quat[4]; // orientation - mjsOrientation alt; // alternative orientation - mjString* info; // message appended to compiler errors -} mjsFrame; - - -typedef struct mjsJoint_ { // joint specification - mjElement* element; // element type - mjString* name; // name - mjString* classname; // class name - mjtJoint type; // joint type - - // kinematics - double pos[3]; // anchor position - double axis[3]; // joint axis - double ref; // value at reference configuration: qpos0 - - // stiffness - double stiffness; // stiffness coefficient - double springref; // spring reference value: qpos_spring - double springdamper[2]; // timeconst, dampratio - - // limits - int limited; // does joint have limits (mjtLimited) - double range[2]; // joint limits - double margin; // margin value for joint limit detection - mjtNum solref_limit[mjNREF]; // solver reference: joint limits - mjtNum solimp_limit[mjNIMP]; // solver impedance: joint limits - int actfrclimited; // are actuator forces on joint limited (mjtLimited) - double actfrcrange[2]; // actuator force limits - - // dof properties - double armature; // armature inertia (mass for slider) - double damping; // damping coefficient - double frictionloss; // friction loss - mjtNum solref_friction[mjNREF]; // solver reference: dof friction - mjtNum solimp_friction[mjNIMP]; // solver impedance: dof friction - - // other - int group; // group - mjtByte actgravcomp; // is gravcomp force applied via actuators - mjDoubleVec* userdata; // user data - mjString* info; // message appended to compiler errors -} mjsJoint; - - -typedef struct mjsGeom_ { // geom specification - mjElement* element; // element type - mjString* name; // name - mjString* classname; // classname - mjtGeom type; // geom type - - // frame, size - double pos[3]; // position - double quat[4]; // orientation - mjsOrientation alt; // alternative orientation - double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid - double size[3]; // type-specific size - - // contact related - int contype; // contact type - int conaffinity; // contact affinity - int condim; // contact dimensionality - int priority; // contact priority - double friction[3]; // one-sided friction coefficients: slide, roll, spin - double solmix; // solver mixing for contact pairs - mjtNum solref[mjNREF]; // solver reference - mjtNum solimp[mjNIMP]; // solver impedance - double margin; // margin for contact detection - double gap; // include in solver if dist < margin-gap - - // inertia inference - double mass; // used to compute density - double density; // used to compute mass and inertia from volume or surface - mjtGeomInertia typeinertia; // selects between surface and volume inertia - - // fluid forces - mjtNum fluid_ellipsoid; // whether ellipsoid-fluid model is active - mjtNum fluid_coefs[5]; // ellipsoid-fluid interaction coefs - - // visual - mjString* material; // name of material - float rgba[4]; // rgba when material is omitted - int group; // group - - // other - mjString* hfieldname; // heightfield attached to geom - mjString* meshname; // mesh attached to geom - double fitscale; // scale mesh uniformly - mjDoubleVec* userdata; // user data - mjsPlugin plugin; // sdf plugin - mjString* info; // message appended to compiler errors -} mjsGeom; - - -typedef struct mjsSite_ { // site specification - mjElement* element; // element type - mjString* name; // name - mjString* classname; // class name - - // frame, size - double pos[3]; // position - double quat[4]; // orientation - mjsOrientation alt; // alternative orientation - double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid - double size[3]; // geom size - - // visual - mjtGeom type; // geom type - mjString* material; // name of material - int group; // group - float rgba[4]; // rgba when material is omitted - - // other - mjDoubleVec* userdata; // user data - mjString* info; // message appended to compiler errors -} mjsSite; - - -typedef struct mjsCamera_ { // camera specification - mjElement* element; // element type - mjString* name; // name - mjString* classname; // class name - - // extrinsics - double pos[3]; // position - double quat[4]; // orientation - mjsOrientation alt; // alternative orientation - mjtCamLight mode; // tracking mode - mjString* targetbody; // target body for tracking/targeting - - // intrinsics - double fovy; // y-field of view - double ipd; // inter-pupilary distance - float intrinsic[4]; // camera intrinsics (length) - float sensor_size[2]; // sensor size (length) - float resolution[2]; // resolution (pixel) - float focal_length[2]; // focal length (length) - float focal_pixel[2]; // focal length (pixel) - float principal_length[2]; // principal point (length) - float principal_pixel[2]; // principal point (pixel) - - // other - mjDoubleVec* userdata; // user data - mjString* info; // message appended to compiler errors -} mjsCamera; - - -typedef struct mjsLight_ { // light specification - mjElement* element; // element type - mjString* name; // name - mjString* classname; // class name - - // frame - double pos[3]; // position - double dir[3]; // direction - mjtCamLight mode; // tracking mode - mjString* targetbody; // target body for targeting - - // intrinsics - mjtByte active; // is light active - mjtByte directional; // is light directional or spot - mjtByte castshadow; // does light cast shadows - double bulbradius; // bulb radius, for soft shadows - float attenuation[3]; // OpenGL attenuation (quadratic model) - float cutoff; // OpenGL cutoff - float exponent; // OpenGL exponent - float ambient[3]; // ambient color - float diffuse[3]; // diffuse color - float specular[3]; // specular color - - // other - mjString* info; // message appended to compiler errorsx -} mjsLight; - - -typedef struct mjsFlex_ { - mjElement* element; // element type - mjString* name; // name - mjString* classname; // class name - - // contact properties - int contype; // contact type - int conaffinity; // contact affinity - int condim; // contact dimensionality - int priority; // contact priority - double friction[3]; // one-sided friction coefficients: slide, roll, spin - double solmix; // solver mixing for contact pairs - mjtNum solref[mjNREF]; // solver reference - mjtNum solimp[mjNIMP]; // solver impedance - double margin; // margin for contact detection - double gap; // include in solver if dist #include "user/user_composite.h" #include diff --git a/src/user/user_composite.h b/src/user/user_composite.h index bbc49a72..88bccedc 100644 --- a/src/user/user_composite.h +++ b/src/user/user_composite.h @@ -20,7 +20,7 @@ #include #include -#include "user/user_api.h" +#include #include "user/user_model.h" #include "user/user_objects.h" diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 066e74a7..663c8b6e 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -34,7 +34,7 @@ #include "engine/engine_util_misc.h" #include "engine/engine_util_spatial.h" #include "user/user_flexcomp.h" -#include "user/user_api.h" +#include #include "user/user_model.h" #include "user/user_objects.h" #include "user/user_util.h" @@ -443,7 +443,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { if (plugin.active) { mjsPlugin* pplugin = &body->plugin; pplugin->active = true; - pplugin->instance = static_cast(plugin.instance); + pplugin->instance = static_cast(plugin.instance); mjs_setString(pplugin->name, mjs_getString(plugin.name)); mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } @@ -507,7 +507,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { if (plugin.active) { mjsPlugin* pplugin = &pb->plugin; pplugin->active = true; - pplugin->instance = static_cast(plugin.instance); + pplugin->instance = static_cast(plugin.instance); mjs_setString(pplugin->name, mjs_getString(plugin.name)); mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } diff --git a/src/user/user_flexcomp.h b/src/user/user_flexcomp.h index 5d0ca04f..a22780aa 100644 --- a/src/user/user_flexcomp.h +++ b/src/user/user_flexcomp.h @@ -19,7 +19,7 @@ #include #include -#include "user/user_api.h" +#include #include "user/user_model.h" #include "user/user_objects.h" diff --git a/src/user/user_init.c b/src/user/user_init.c index 6a6c8d15..864c7ec1 100644 --- a/src/user/user_init.c +++ b/src/user/user_init.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "engine/engine_io.h" #include "user/user_api.h" diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 79a1d1d0..61e8265f 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -27,6 +27,7 @@ #include #include +#include #include "user/user_api.h" #ifdef MUJOCO_TINYOBJLOADER_IMPL @@ -196,7 +197,7 @@ mjCMesh& mjCMesh::operator=(const mjCMesh& other) { void mjCMesh::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.file = &spec_file_; @@ -1983,7 +1984,7 @@ mjCSkin& mjCSkin::operator=(const mjCSkin& other) { void mjCSkin::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.file = &spec_file_; @@ -2395,7 +2396,7 @@ mjCFlex& mjCFlex::operator=(const mjCFlex& other) { void mjCFlex::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.material = &spec_material_; diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 0a4f6f44..3a48ace2 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -416,7 +417,7 @@ void mjCModel::CreateObjectLists() { void mjCModel::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.comment = &spec_comment_; spec.modelfiledir = &spec_modelfiledir_; spec.modelname = &spec_modelname_; diff --git a/src/user/user_model.h b/src/user/user_model.h index 95939964..5d2ee204 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -27,13 +27,13 @@ #include #include #include -#include "user/user_api.h" +#include #include "user/user_objects.h" typedef std::map > mjKeyMap; typedef std::array mjListKeyMap; -class mjCModel_ : public mjElement { +class mjCModel_ : public mjsElement { public: // attach namespaces std::string prefix; diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 6ff8c13c..a1d9329b 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -45,6 +45,7 @@ #include "engine/engine_util_misc.h" #include "engine/engine_util_solve.h" #include "engine/engine_util_spatial.h" +#include #include "user/user_api.h" #include "user/user_cache.h" #include "user/user_model.h" @@ -640,7 +641,7 @@ void mjCDef::PointToLocal() { equality_.PointToLocal(); tendon_.PointToLocal(); actuator_.PointToLocal(); - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.joint = &joint_.spec; spec.geom = &geom_.spec; @@ -949,7 +950,7 @@ mjCBody& mjCBody::operator-=(const mjCBody& subtree) { void mjCBody::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.childclass = &classname; spec.userdata = &spec_userdata_; @@ -1256,7 +1257,7 @@ mjCBase* mjCBody::FindObject(mjtObj type, string _name, bool recursive) { template -static mjElement* GetNext(std::vector& list, mjElement* child) { +static mjsElement* GetNext(std::vector& list, mjsElement* child) { for (unsigned int i = 0; i < list.size()-1; i++) { if (list[i]->spec.element == child) { return list[i+1]->spec.element; @@ -1268,7 +1269,7 @@ static mjElement* GetNext(std::vector& list, mjElement* child) { // get next child of given type -mjElement* mjCBody::NextChild(mjElement* child, mjtObj type) { +mjsElement* mjCBody::NextChild(mjsElement* child, mjtObj type) { if (type == mjOBJ_UNKNOWN) { if (!child) { throw mjCError(this, "child type must be specified if no child element is given"); @@ -1669,7 +1670,7 @@ void mjCFrame::SetParent(mjCBody* _body) { void mjCFrame::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.childclass = &classname; spec.info = &info; @@ -1765,7 +1766,7 @@ bool mjCJoint::is_actfrclimited() const { return islimited(actfrclimited, actfrc void mjCJoint::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.userdata = &spec_userdata_; @@ -1965,7 +1966,7 @@ mjCGeom& mjCGeom::operator=(const mjCGeom& other) { // to be called after any default copy constructor void mjCGeom::PointToLocal(void) { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.info = &info; spec.classname = &classname; @@ -2598,7 +2599,7 @@ mjCSite& mjCSite::operator=(const mjCSite& other) { void mjCSite::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.info = &info; spec.classname = &classname; @@ -2750,7 +2751,7 @@ mjCCamera& mjCCamera::operator=(const mjCCamera& other) { void mjCCamera::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.userdata = &spec_userdata_; @@ -2901,7 +2902,7 @@ mjCLight& mjCLight::operator=(const mjCLight& other) { void mjCLight::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.targetbody = &spec_targetbody_; @@ -3001,7 +3002,7 @@ mjCHField& mjCHField::operator=(const mjCHField& other) { void mjCHField::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.file = &spec_file_; spec.content_type = &spec_content_type_; @@ -3230,7 +3231,7 @@ mjCTexture& mjCTexture::operator=(const mjCTexture& other) { void mjCTexture::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.file = &spec_file_; @@ -3941,7 +3942,7 @@ mjCMaterial& mjCMaterial::operator=(const mjCMaterial& other) { void mjCMaterial::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.texture = &spec_texture_; @@ -4031,7 +4032,7 @@ mjCPair& mjCPair::operator=(const mjCPair& other) { void mjCPair::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.geomname1 = &spec_geomname1_; @@ -4256,7 +4257,7 @@ mjCBodyPair& mjCBodyPair::operator=(const mjCBodyPair& other) { void mjCBodyPair::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.bodyname1 = &spec_bodyname1_; spec.bodyname2 = &spec_bodyname2_; @@ -4390,7 +4391,7 @@ mjCEquality& mjCEquality::operator=(const mjCEquality& other) { void mjCEquality::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.name1 = &spec_name1_; @@ -4559,7 +4560,7 @@ bool mjCTendon::is_limited() const { return islimited(limited, range); } void mjCTendon::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.material = &spec_material_; @@ -4891,7 +4892,7 @@ mjCWrap& mjCWrap::operator=(const mjCWrap& other) { void mjCWrap::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.info = &info; } @@ -5040,7 +5041,7 @@ bool mjCActuator::is_actlimited() const { return islimited(actlimited, actrange) void mjCActuator::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.userdata = &spec_userdata_; @@ -5363,7 +5364,7 @@ mjCSensor& mjCSensor::operator=(const mjCSensor& other) { void mjCSensor::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.classname = &classname; spec.userdata = &spec_userdata_; @@ -5866,7 +5867,7 @@ mjCNumeric& mjCNumeric::operator=(const mjCNumeric& other) { void mjCNumeric::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.data = &spec_data_; spec.info = &info; @@ -5955,7 +5956,7 @@ mjCText& mjCText::operator=(const mjCText& other) { void mjCText::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.data = &spec_data_; spec.info = &info; @@ -6035,7 +6036,7 @@ mjCTuple& mjCTuple::operator=(const mjCTuple& other) { void mjCTuple::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.objtype = (mjIntVec*)&spec_objtype_; spec.objname = &spec_objname_; @@ -6170,7 +6171,7 @@ mjCKey& mjCKey::operator=(const mjCKey& other) { void mjCKey::PointToLocal() { - spec.element = static_cast(this); + spec.element = static_cast(this); spec.name = &name; spec.qpos = &spec_qpos_; spec.qvel = &spec_qvel_; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index e3548686..cd79226a 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -26,7 +26,7 @@ #include #include #include -#include "user/user_api.h" +#include #include "user/user_cache.h" #include "user/user_util.h" @@ -168,7 +168,7 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { //------------------------- class mjCBase ---------------------------------------------------------- // Generic functionality for all derived classes -class mjCBase_ : public mjElement { +class mjCBase_ : public mjsElement { public: int id; // object id std::string name; // object name @@ -309,7 +309,7 @@ class mjCBody : public mjCBody_, private mjsBody { const std::vector& get_userdata() { return userdata_; } // get next child of given type - mjElement* NextChild(mjElement* child, mjtObj type = mjOBJ_UNKNOWN); + mjsElement* NextChild(mjsElement* child, mjtObj type = mjOBJ_UNKNOWN); private: mjCBody(const mjCBody& other, mjCModel* _model); // copy constructor @@ -1624,7 +1624,7 @@ class mjCKey : public mjCKey_, private mjsKey { //------------------------- class mjCDef ----------------------------------------------------------- // Describes one set of defaults -class mjCDef : public mjElement { +class mjCDef : public mjsElement { friend class mjXWriter; public: diff --git a/src/xml/xml.cc b/src/xml/xml.cc index ad1cf06f..0e5fd090 100644 --- a/src/xml/xml.cc +++ b/src/xml/xml.cc @@ -35,7 +35,7 @@ #include "cc/array_safety.h" #include "engine/engine_crossplatform.h" #include "engine/engine_resource.h" -#include "user/user_api.h" +#include #include "user/user_util.h" #include "user/user_vfs.h" #include "xml/xml_native_reader.h" @@ -345,7 +345,7 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, } // create model, set filedir - spec = mjs_createSpec(); + spec = mj_makeSpec(); const char* dir; int ndir = 0; mju_getResourceDir(resource, &dir, &ndir); @@ -394,7 +394,7 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, // catch known errors catch (mjXError err) { mjCopyError(error, err.message, error_sz); - mjs_deleteSpec(spec); + mj_deleteSpec(spec); return nullptr; } diff --git a/src/xml/xml.h b/src/xml/xml.h index 2fdd3acc..dadc2451 100644 --- a/src/xml/xml.h +++ b/src/xml/xml.h @@ -19,7 +19,7 @@ #include #include -#include "user/user_api.h" +#include // Top level API diff --git a/src/xml/xml_api.cc b/src/xml/xml_api.cc index 23af4c81..65a2198b 100644 --- a/src/xml/xml_api.cc +++ b/src/xml/xml_api.cc @@ -28,7 +28,7 @@ #include #include "engine/engine_io.h" #include "engine/engine_resource.h" -#include "user/user_api.h" +#include #include "user/user_vfs.h" #include "xml/xml.h" #include "xml/xml_native_reader.h" @@ -59,7 +59,7 @@ std::optional GlobalModel::ToXML(const mjModel* m, char* error, mjCopyError(error, "No XML model loaded", error_sz); return std::nullopt; } - mjs_copyBack(spec_, m); + mj_copyBack(spec_, m); std::string result = mjWriteXML(spec_, error, error_sz); if (result.empty()) { return std::nullopt; @@ -70,7 +70,7 @@ std::optional GlobalModel::ToXML(const mjModel* m, char* error, void GlobalModel::Set(mjSpec* spec) { std::lock_guard lock(*mutex_); if (spec_ != nullptr) { - mjs_deleteSpec(spec_); + mj_deleteSpec(spec_); } spec_ = spec; } @@ -96,13 +96,13 @@ mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, // parse new model std::unique_ptr> spec( mjParseXML(filename, vfs, error, error_sz), - [](mjSpec* s) { mjs_deleteSpec(s); }); + [](mjSpec* s) { mj_deleteSpec(s); }); if (!spec) { return nullptr; } // compile new model - mjModel* m = mjs_compile(spec.get(), vfs); + mjModel* m = mj_compile(spec.get(), vfs); if (!m) { mjCopyError(error, mjs_getError(spec.get()), error_sz); return nullptr; @@ -248,7 +248,7 @@ int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int er std::string error_msg = "Output string too short, should be at least " + std::to_string(result.size()+1); mjCopyError(error, error_msg.c_str(), error_sz); - return 0; + return result.size(); } if (result.empty()) { return 0; @@ -256,6 +256,6 @@ int mj_saveXMLString(const mjSpec* s, char* xml, int xml_sz, char* error, int er result.copy(xml, xml_sz); xml[result.size()] = 0; - return 1; + return 0; } diff --git a/src/xml/xml_api.h b/src/xml/xml_api.h index 046e8410..fe4d0f18 100644 --- a/src/xml/xml_api.h +++ b/src/xml/xml_api.h @@ -17,7 +17,7 @@ #include #include -#include "user/user_api.h" +#include #ifdef __cplusplus extern "C" { diff --git a/src/xml/xml_base.cc b/src/xml/xml_base.cc index bcefd583..4d809581 100644 --- a/src/xml/xml_base.cc +++ b/src/xml/xml_base.cc @@ -21,9 +21,7 @@ #include #include -#include "user/user_api.h" -#include "user/user_model.h" -#include "user/user_objects.h" +#include #include "xml/xml_util.h" #include "tinyxml2.h" diff --git a/src/xml/xml_base.h b/src/xml/xml_base.h index 7df966cc..ec3fd74c 100644 --- a/src/xml/xml_base.h +++ b/src/xml/xml_base.h @@ -19,7 +19,7 @@ #include #include "tinyxml2.h" -#include "user/user_api.h" +#include #include "xml/xml_util.h" diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 786e54ae..59aa680e 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -36,7 +36,7 @@ #include "engine/engine_plugin.h" #include "engine/engine_util_errmem.h" #include "engine/engine_util_misc.h" -#include "user/user_api.h" +#include #include "user/user_composite.h" #include "user/user_flexcomp.h" #include "user/user_util.h" diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index e0f857db..aa20841a 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -21,7 +21,7 @@ #include "tinyxml2.h" #include -#include "user/user_api.h" +#include #include "xml/xml_base.h" #include "xml/xml_util.h" diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index c9012bdd..a9cda59a 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -22,11 +22,12 @@ #include #include +#include +#include #include "engine/engine_io.h" #include "engine/engine_plugin.h" #include "engine/engine_util_errmem.h" #include "engine/engine_util_misc.h" -#include "user/user_api.h" #include "user/user_model.h" #include "user/user_objects.h" #include "user/user_util.h" diff --git a/src/xml/xml_native_writer.h b/src/xml/xml_native_writer.h index 6f5f0812..c6791acd 100644 --- a/src/xml/xml_native_writer.h +++ b/src/xml/xml_native_writer.h @@ -18,7 +18,7 @@ #include #include -#include "user/user_api.h" +#include #include "user/user_objects.h" #include "xml/xml_base.h" #include "tinyxml2.h" diff --git a/src/xml/xml_urdf.cc b/src/xml/xml_urdf.cc index 8001d93a..cf3b841d 100644 --- a/src/xml/xml_urdf.cc +++ b/src/xml/xml_urdf.cc @@ -20,6 +20,7 @@ #include #include +#include #include "user/user_api.h" #include "user/user_util.h" #include "xml/xml_native_reader.h" diff --git a/src/xml/xml_urdf.h b/src/xml/xml_urdf.h index d2efa317..b549ac6e 100644 --- a/src/xml/xml_urdf.h +++ b/src/xml/xml_urdf.h @@ -19,7 +19,7 @@ #include #include -#include "user/user_api.h" +#include #include "xml/xml_base.h" #include "tinyxml2.h" diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index 2bc661bc..c0120a29 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -24,7 +24,7 @@ #include #include #include -#include "src/user/user_api.h" +#include #include "src/xml/xml_api.h" #include "src/xml/xml_numeric_format.h" #include "test/fixture.h" @@ -39,7 +39,7 @@ using ::testing::NotNull; // -------------------------- test model manipulation ------------------------- TEST_F(MujocoTest, GetSetData) { - mjSpec* spec = mjs_createSpec(); + mjSpec* spec = mj_makeSpec(); mjsBody* world = mjs_findBody(spec, "world"); mjsBody* body = mjs_addBody(world, 0); mjsSite* site = mjs_addSite(body, 0); @@ -60,11 +60,11 @@ TEST_F(MujocoTest, GetSetData) { EXPECT_EQ(vec[i], i); } - mjs_deleteSpec(spec); + mj_deleteSpec(spec); } TEST_F(MujocoTest, TreeTraversal) { - mjSpec* spec = mjs_createSpec(); + mjSpec* spec = mj_makeSpec(); mjsBody* world = mjs_findBody(spec, "world"); mjsBody* body = mjs_addBody(world, 0); @@ -75,15 +75,15 @@ TEST_F(MujocoTest, TreeTraversal) { mjsSite* site3 = mjs_addSite(body, 0); mjsGeom* geom3 = mjs_addGeom(body, 0); - mjElement* t_el1 = mjs_firstChild(body, mjOBJ_TENDON); - mjElement* s_el1 = mjs_firstChild(body, mjOBJ_SITE); - mjElement* s_el2 = mjs_nextChild(body, s_el1); - mjElement* s_el3 = mjs_nextChild(body, s_el2); - mjElement* s_el4 = mjs_nextChild(body, s_el3); - mjElement* g_el1 = mjs_firstChild(body, mjOBJ_GEOM); - mjElement* g_el2 = mjs_nextChild(body, g_el1); - mjElement* g_el3 = mjs_nextChild(body, g_el2); - mjElement* g_el4 = mjs_nextChild(body, g_el3); + mjsElement* t_el1 = mjs_firstChild(body, mjOBJ_TENDON); + mjsElement* s_el1 = mjs_firstChild(body, mjOBJ_SITE); + mjsElement* s_el2 = mjs_nextChild(body, s_el1); + mjsElement* s_el3 = mjs_nextChild(body, s_el2); + mjsElement* s_el4 = mjs_nextChild(body, s_el3); + mjsElement* g_el1 = mjs_firstChild(body, mjOBJ_GEOM); + mjsElement* g_el2 = mjs_nextChild(body, g_el1); + mjsElement* g_el3 = mjs_nextChild(body, g_el2); + mjsElement* g_el4 = mjs_nextChild(body, g_el3); EXPECT_EQ(t_el1, nullptr); EXPECT_EQ(s_el1, site1->element); @@ -95,7 +95,7 @@ TEST_F(MujocoTest, TreeTraversal) { EXPECT_EQ(g_el4, nullptr); EXPECT_EQ(s_el4, nullptr); - mjs_deleteSpec(spec); + mj_deleteSpec(spec); } // ------------------- test recompilation multiple files ----------------------- @@ -131,16 +131,16 @@ TEST_F(PluginTest, RecompileCompare) { << "Failed to load " << xml << ": " << err.data(); // copy spec - mjSpec* s_copy = mjs_copySpec(s); + mjSpec* s_copy = mj_copySpec(s); // compile twice and compare - mjModel* m_old = mjs_compile(s, nullptr); + mjModel* m_old = mj_compile(s, nullptr); ASSERT_THAT(m_old, NotNull()) << "Failed to compile " << xml << ": " << mjs_getError(s); - mjModel* m_new = mjs_compile(s, nullptr); - mjModel* m_copy = mjs_compile(s_copy, nullptr); + mjModel* m_new = mj_compile(s, nullptr); + mjModel* m_copy = mj_compile(s_copy, nullptr); ASSERT_THAT(m_new, NotNull()) << "Failed to recompile " << xml << ": " << mjs_getError(s); @@ -158,8 +158,8 @@ TEST_F(PluginTest, RecompileCompare) { << "Different field: " << field << '\n'; // copy to a new spec, compile and compare - mjSpec* s_copy2 = mjs_copySpec(s); - mjModel* m_copy2 = mjs_compile(s_copy2, nullptr); + mjSpec* s_copy2 = mj_copySpec(s); + mjModel* m_copy2 = mj_compile(s_copy2, nullptr); ASSERT_THAT(m_copy2, NotNull()) << "Failed to compile " << xml << ": " << mjs_getError(s_copy2); @@ -170,9 +170,9 @@ TEST_F(PluginTest, RecompileCompare) { << "Different field: " << field << '\n'; // delete models - mjs_deleteSpec(s); - mjs_deleteSpec(s_copy); - mjs_deleteSpec(s_copy2); + mj_deleteSpec(s); + mj_deleteSpec(s_copy); + mj_deleteSpec(s_copy2); mj_deleteModel(m_old); mj_deleteModel(m_new); mj_deleteModel(m_copy); @@ -433,7 +433,7 @@ TEST_F(MujocoTest, AttachSame) { mjs_attachBody(frame, body, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); // compile new model - mjModel* m_attached = mjs_compile(parent, 0); + mjModel* m_attached = mj_compile(parent, 0); EXPECT_THAT(m_attached, NotNull()); // check full name stored in mjModel @@ -450,7 +450,7 @@ TEST_F(MujocoTest, AttachSame) { << "Different field: " << field << '\n';; // destroy everything - mjs_deleteSpec(parent); + mj_deleteSpec(parent); mj_deleteModel(m_attached); mj_deleteModel(m_expected); } @@ -550,7 +550,7 @@ TEST_F(MujocoTest, AttachDifferent) { mjs_attachBody(frame, body, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); // compile new model - mjModel* m_attached = mjs_compile(parent, 0); + mjModel* m_attached = mj_compile(parent, 0); EXPECT_THAT(m_attached, NotNull()); // check full name stored in mjModel @@ -567,8 +567,8 @@ TEST_F(MujocoTest, AttachDifferent) { << "Different field: " << field << '\n';; // destroy everything - mjs_deleteSpec(parent); - mjs_deleteSpec(child); + mj_deleteSpec(parent); + mj_deleteSpec(child); mj_deleteModel(m_attached); mj_deleteModel(m_expected); } @@ -662,7 +662,7 @@ TEST_F(MujocoTest, AttachFrame) { mjs_attachFrame(body, frame, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); // compile new model - mjModel* m_attached = mjs_compile(parent, 0); + mjModel* m_attached = mj_compile(parent, 0); EXPECT_THAT(m_attached, NotNull()); // check full name stored in mjModel @@ -679,8 +679,8 @@ TEST_F(MujocoTest, AttachFrame) { << "Different field: " << field << '\n';; // destroy everything - mjs_deleteSpec(parent); - mjs_deleteSpec(child); + mj_deleteSpec(parent); + mj_deleteSpec(child); mj_deleteModel(m_attached); mj_deleteModel(m_expected); } @@ -715,7 +715,7 @@ void TestDetachBody(bool compile) { EXPECT_THAT(child, NotNull()) << er.data(); // compile model (for testing double compilation) - mjModel* m_child = compile ? mjs_compile(child, 0) : nullptr; + mjModel* m_child = compile ? mj_compile(child, 0) : nullptr; // get subtree mjsBody* body = mjs_findBody(child, "body"); @@ -725,7 +725,7 @@ void TestDetachBody(bool compile) { EXPECT_THAT(mjs_detachBody(child, body), 0); // compile new model - mjModel* m_detached = mjs_compile(child, 0); + mjModel* m_detached = mj_compile(child, 0); EXPECT_THAT(m_detached, NotNull()); // compare with expected XML @@ -736,7 +736,7 @@ void TestDetachBody(bool compile) { << "Different field: " << field << '\n'; // destroy everything - mjs_deleteSpec(child); + mj_deleteSpec(child); mj_deleteModel(m_detached); mj_deleteModel(m_expected); if (m_child) mj_deleteModel(m_child); @@ -791,7 +791,7 @@ TEST_F(MujocoTest, PreserveState) { EXPECT_THAT(spec, NotNull()) << er.data(); // compile models - mjModel* model = mjs_compile(spec, 0); + mjModel* model = mj_compile(spec, 0); EXPECT_THAT(model, NotNull()); mjModel* m_expected = LoadModelFromString(xml_expected, er.data(), er.size()); EXPECT_THAT(m_expected, NotNull()); @@ -834,7 +834,7 @@ TEST_F(MujocoTest, PreserveState) { joint->ref = d_expected->qpos[m_expected->nq-1]; // compile new model - mjs_recompile(spec, 0, model, data); + mj_recompile(spec, 0, model, data); EXPECT_THAT(model, NotNull()); // compare qpos @@ -861,7 +861,7 @@ TEST_F(MujocoTest, PreserveState) { // destroy everything mj_deleteData(data); mj_deleteData(d_expected); - mjs_deleteSpec(spec); + mj_deleteSpec(spec); mj_deleteModel(model); mj_deleteModel(m_expected); } diff --git a/test/xml/xml_api_test.cc b/test/xml/xml_api_test.cc index d11be846..8c5041a2 100644 --- a/test/xml/xml_api_test.cc +++ b/test/xml/xml_api_test.cc @@ -24,7 +24,7 @@ #include #include #include -#include "src/user/user_api.h" +#include #include "src/xml/xml_api.h" #include "test/fixture.h" @@ -119,15 +119,15 @@ TEST_F(MujocoTest, SaveXmlShortString) { mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size()); EXPECT_THAT(spec, NotNull()) << "Failed to parse spec: " << error.data(); - mjModel* model = mjs_compile(spec, 0); + mjModel* model = mj_compile(spec, 0); EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data(); std::array out; EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), - error.data(), error.size()), 0); + error.data(), error.size()), 272); EXPECT_STREQ(error.data(), "Output string too short, should be at least 273"); - mjs_deleteSpec(spec); + mj_deleteSpec(spec); mj_deleteModel(model); } @@ -136,16 +136,16 @@ TEST_F(MujocoTest, SaveXml) { mjSpec* spec = mj_parseXMLString(xml, 0, error.data(), error.size()); EXPECT_THAT(spec, NotNull()) << "Failed to parse spec: " << error.data(); - mjModel* model = mjs_compile(spec, 0); + mjModel* model = mj_compile(spec, 0); EXPECT_THAT(model, NotNull()) << "Failed to compile model: " << error.data(); std::array out; EXPECT_THAT(mj_saveXMLString(spec, out.data(), out.size(), error.data(), - error.size()), 1) << error.data(); + error.size()), 0) << error.data(); mjSpec* saved_spec = mj_parseXMLString(xml, 0, error.data(), error.size()); EXPECT_THAT(saved_spec, NotNull()) << "Invalid saved spec: " << error.data(); - mjModel* saved_model = mjs_compile(saved_spec, 0); + mjModel* saved_model = mj_compile(saved_spec, 0); EXPECT_THAT(saved_model, NotNull()) << "Invalid model: " << error.data(); mjtNum tol = 0; @@ -154,8 +154,8 @@ TEST_F(MujocoTest, SaveXml) { << "Expected and attached models are different!\n" << "Different field: " << field << '\n'; - mjs_deleteSpec(spec); - mjs_deleteSpec(saved_spec); + mj_deleteSpec(spec); + mj_deleteSpec(saved_spec); mj_deleteModel(model); mj_deleteModel(saved_model); } diff --git a/test/xml/xml_native_reader_test.cc b/test/xml/xml_native_reader_test.cc index c07c8e73..3a12e71c 100644 --- a/test/xml/xml_native_reader_test.cc +++ b/test/xml/xml_native_reader_test.cc @@ -24,10 +24,10 @@ #include #include #include +#include #include #include "src/cc/array_safety.h" #include "src/engine/engine_util_errmem.h" -#include "src/user/user_api.h" #include "src/xml/xml_api.h" #include "test/fixture.h" @@ -1101,7 +1101,7 @@ TEST_F(XMLReaderTest, ParseReplicateDefaultPropagate) { EXPECT_THAT(def, NotNull()); EXPECT_THAT(def->geom->type, mjGEOM_CAPSULE); - mjs_deleteSpec(spec); + mj_deleteSpec(spec); } // ----------------------- test camera parsing --------------------------------- diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index d81ebb90..d3c68f8e 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -57,6 +57,7 @@ public const bool mjEXTERNC = true; public const bool THIRD_PARTY_MUJOCO_MJRENDER_H_ = true; public const int mjNAUX = 10; public const int mjMAXTEXTURE = 1000; +public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJSPEC_H_ = true; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTHREAD_H_ = true; public const int mjMAXTHREAD = 128; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTNUM_H_ = true; @@ -427,6 +428,39 @@ public enum mjtFont : int{ mjFONT_SHADOW = 1, mjFONT_BIG = 2, } +public enum mjtGeomInertia : int{ + mjINERTIA_VOLUME = 1, + mjINERTIA_SHELL = 2, +} +public enum mjtBuiltin : int{ + mjBUILTIN_NONE = 0, + mjBUILTIN_GRADIENT = 1, + mjBUILTIN_CHECKER = 2, + mjBUILTIN_FLAT = 3, +} +public enum mjtMark : int{ + mjMARK_NONE = 0, + mjMARK_EDGE = 1, + mjMARK_CROSS = 2, + mjMARK_RANDOM = 3, +} +public enum mjtLimited : int{ + mjLIMITED_FALSE = 0, + mjLIMITED_TRUE = 1, + mjLIMITED_AUTO = 2, +} +public enum mjtInertiaFromGeom : int{ + mjINERTIAFROMGEOM_FALSE = 0, + mjINERTIAFROMGEOM_TRUE = 1, + mjINERTIAFROMGEOM_AUTO = 2, +} +public enum mjtOrientation : int{ + mjORIENTATION_QUAT = 0, + mjORIENTATION_AXISANGLE = 1, + mjORIENTATION_XYAXES = 2, + mjORIENTATION_ZAXIS = 3, + mjORIENTATION_EULER = 4, +} public enum mjtTaskStatus : int{ mjTASK_NEW = 0, mjTASK_QUEUED = 1, @@ -6358,9 +6392,6 @@ public static unsafe extern int mj_saveLastXML([MarshalAs(UnmanagedType.LPStr)]s [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern void mj_freeLastXML(); -[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] -public static unsafe extern int mj_printSchema([MarshalAs(UnmanagedType.LPStr)]string filename, StringBuilder buffer, int buffer_sz, int flg_html, int flg_pad); - [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern void mj_step(mjModel_* m, mjData_* d); @@ -6469,6 +6500,9 @@ public static unsafe extern void mju_printMat(double* mat, int nr, int nc); [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern void mju_printMatSparse(double* mat, int nr, int* rownnz, int* rowadr, int* colind); +[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] +public static unsafe extern int mj_printSchema([MarshalAs(UnmanagedType.LPStr)]string filename, StringBuilder buffer, int buffer_sz, int flg_html, int flg_pad); + [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern void mj_fwdPosition(mjModel_* m, mjData_* d);