Improve composite docs and changelog.
PiperOrigin-RevId: 730394496 Change-Id: Ie993214deb82b526a96510e02f6ecff103c58607
This commit is contained in:
committed by
Copybara-Service
parent
81b1948b46
commit
b3aa5df68a
+17
-48
@@ -2964,14 +2964,14 @@ the direction specified by the dir attribute. It does not have a full spatial fr
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This is not a model element, but rather a macro which expands into multiple model elements representing a composite
|
||||
object. These elements are bodies (with their own joints, geoms and sites) that become children of the parent body
|
||||
containing the macro, as well as tendons and equality constraints added to the corresponding model sections. The
|
||||
automatically-generated bodies are laid out in a regular grid in 1D, 2D or 3D depending on the object type and count
|
||||
attributes. The macro expansion is done by the model compiler. If the resulting model is then saved, the macro will be
|
||||
object. These elements are bodies (with their own joints and geoms) that become children of the parent body containing
|
||||
the macro. The macro expansion is done by the model compiler. If the resulting model is then saved, the macro will be
|
||||
replaced with the actual model elements. The defaults mechanism used in the rest of MJCF does not apply here, even if
|
||||
the parent body has a childclass attribute defined. Instead there are internal defaults adjusted automatically for each
|
||||
composite object type. Composite objects can only be defined if the model is in local coordinates. Using them in global
|
||||
coordinates results in compiler error. See :ref:`CComposite` in the modeling guide for more detailed explanation.
|
||||
composite object type. See :ref:`CComposite` in the modeling guide for more detailed explanation. Note that there used
|
||||
to be several composite types, but they have incrementally replaced by :ref:`replicate<replicate>` (for repeated
|
||||
objects) and :ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the only supported composite type is now
|
||||
cable, which produces an inextensible chain of bodies connected with ball joints.
|
||||
|
||||
.. _body-composite-prefix:
|
||||
|
||||
@@ -2982,16 +2982,8 @@ coordinates results in compiler error. See :ref:`CComposite` in the modeling gui
|
||||
|
||||
.. _body-composite-type:
|
||||
|
||||
:at:`type`: :at-val:`[particle, cable], required`
|
||||
This attribute determines the type of composite object. The remaining attributes and sub-elements are then
|
||||
interpreted according to the type. Default settings are also adjusted depending on the type.
|
||||
|
||||
The **particle** type creates a 1D, 2D or 3D grid of equally-spaced bodies. By default, each body has a single sphere
|
||||
geom and 3 orthogonal sliding joints, allowing translation but not rotation. The geom condim and priority attributes
|
||||
are set to 1 by default. This makes the spheres have frictionless contacts with all other geoms (unless the priority
|
||||
of some frictional geom is higher). The user can replace the default sliders with multiple joints of kind="particle"
|
||||
and replace the default sphere with a custom geom. Note that the particle composite type is deprecated and might be
|
||||
removed in a future version. Instead of particle, it is recommended to use :ref:`replicate`.
|
||||
:at:`type`: :at-val:`[cable], required`
|
||||
This attribute determines the type of composite object. The only supported type is cable.
|
||||
|
||||
The **cable** type creates a 1D chain of bodies connected with ball joints, each having a geom with user-defined type
|
||||
(cylinder, capsule or box). The geometry can either be defined with an array of 3D vertex coordinates :at:`vertex`
|
||||
@@ -3013,41 +3005,30 @@ coordinates results in compiler error. See :ref:`CComposite` in the modeling gui
|
||||
.. _body-composite-offset:
|
||||
|
||||
:at:`offset`: :at-val:`real(3), "0 0 0"`
|
||||
This attribute affects particle and grid types, and is ignored for all other types. It specifies a 3D offset from the
|
||||
center of the parent body to the center of the grid of elements. The offset is expressed in the local coordinate
|
||||
frame of the parent body.
|
||||
|
||||
.. _body-composite-flatinertia:
|
||||
|
||||
:at:`flatinertia`: :at-val:`real, "0"`
|
||||
This attribute affects the cloth type and is ignored for all other types. The default value 0 disables this
|
||||
mechanism. When the value is positive, it specifies the ratio of the small-to-large axes of the modified diagonal
|
||||
inertia. The idea is to set it to a small value, say 0.01, in which case the inertias of the body elements will
|
||||
corresponds to flat boxes aligned with the cloth (which can then be used for lift forces). This will not change the
|
||||
geom shapes, but instead will set the body inertias directly and disable the automatic computation of inertia from
|
||||
geom shape for the composite body only.
|
||||
It specifies a 3D offset from the center of the parent body to the center of the grid of elements. The offset is
|
||||
expressed in the local coordinate frame of the parent body.
|
||||
|
||||
.. _body-composite-vertex:
|
||||
|
||||
:at:`vertex`: :at-val:`real(3*nvert), optional`
|
||||
Vertex 3D positions in global coordinates (cable only).
|
||||
Vertex 3D positions in global coordinates.
|
||||
|
||||
.. _body-composite-initial:
|
||||
|
||||
:at:`initial`: :at-val:`[free, ball, none], "0"`
|
||||
Behavior of the first point (cable only). Free: free joint. Ball: ball joint. None: no dof.
|
||||
Behavior of the first point. Free: free joint. Ball: ball joint. None: no dof.
|
||||
|
||||
.. _body-composite-curve:
|
||||
|
||||
:at:`curve`: :at-val:`string(3), optional`
|
||||
Functions specifying the vertex positions (cable only). Available functions are `s`, `cos(s)`, and `sin(s)`, where
|
||||
`s` is the arc length parameter.
|
||||
Functions specifying the vertex positions. Available functions are `s`, `cos(s)`, and `sin(s)`, where `s` is the arc
|
||||
length parameter.
|
||||
|
||||
.. _body-composite-size:
|
||||
|
||||
:at:`size`: :at-val:`int(3), optional`
|
||||
Scaling of the curve functions (cable only). `size[0]` is the scaling of `s`, `size[1]` is the radius of `\cos(s)`
|
||||
and `\sin(s)`, and `size[2]` is the speed of the argument (i.e. `\cos(2*\pi*size[2]*s)`).
|
||||
Scaling of the curve functions. `size[0]` is the scaling of `s`, `size[1]` is the radius of `\cos(s)` and `\sin(s)`,
|
||||
and `size[2]` is the speed of the argument (i.e. `\cos(2*\pi*size[2]*s)`).
|
||||
|
||||
|
||||
.. _composite-joint:
|
||||
@@ -3061,7 +3042,7 @@ joints should be created, as well as to adjust the attributes of both automatic
|
||||
|
||||
.. _composite-joint-kind:
|
||||
|
||||
:at:`kind`: :at-val:`[main, twist, stretch, particle], required`
|
||||
:at:`kind`: :at-val:`[main], required`
|
||||
The joint kind here is orthogonal to the joint type in the rest of MJCF. The joint kind refers to the function of the
|
||||
joint within the mechanism comprising the composite body, while the joint type (hinge or slide) is implied by the
|
||||
joint kind and composite body type.
|
||||
@@ -3071,18 +3052,6 @@ joints should be created, as well as to adjust the attributes of both automatic
|
||||
sliders for box, cylinder and rope; universal joints for cloth, rope and loop. Even though the main joints are
|
||||
included automatically, this sub-element is still useful for adjusting their attributes.
|
||||
|
||||
The **twist** kind corresponds to hinge joints enabling rope, loop and cloth objects to twist. These are optional
|
||||
joints and are only created if this sub-element is present. This sub-element is also used to adjust the attributes of
|
||||
the optional twist joints. For other composite object types this sub-element has no effect.
|
||||
|
||||
The **stretch** kind corresponds to slide joints enabling rope, loop and cloth objects to stretch. These are optional
|
||||
joints and are only created if this sub-element is present. This sub-element is also used to adjust the attributes of
|
||||
the optional stretch joints. For other composite object types this sub-element has no effect.
|
||||
|
||||
The **particle** kind can only be used with the particle composite type. As opposed to all previous kinds, this kind
|
||||
*replaces* the default 3 sliders with user-defined joints. User-defined joints can be repeated, for example
|
||||
to create planar particles with two sliders and a hinge.
|
||||
|
||||
.. _composite-joint-solreffix:
|
||||
|
||||
.. _composite-joint-solimpfix:
|
||||
|
||||
+1
-3
@@ -342,9 +342,7 @@
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`prefix<body-composite-prefix>` | :ref:`type<body-composite-type>` | :ref:`count<body-composite-count>` | :ref:`offset<body-composite-offset>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`flatinertia<body-composite-flatinertia>` | :ref:`vertex<body-composite-vertex>` | :ref:`initial<body-composite-initial>` | :ref:`curve<body-composite-curve>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
| | | | :ref:`size<body-composite-size>` | | | | |
|
||||
| | | | :ref:`vertex<body-composite-vertex>` | :ref:`initial<body-composite-initial>` | :ref:`curve<body-composite-curve>` | :ref:`size<body-composite-size>` | |
|
||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| |_2| composite |br| |_2| |L| | | .. table:: |
|
||||
|
||||
+7
-7
@@ -29,20 +29,17 @@ General
|
||||
and a ``clear_figures`` method.
|
||||
- Separate collision and deformation meshes for :ref:`flex<deformable-flex>`. This enables a fixed cost for the soft
|
||||
body computations, while preserving the fidelity of high-resolution collisions.
|
||||
- Added :ref:`mjs_setDeepCopy` API function. When the deep copy flag is 0, attaching a model will not copy it to the
|
||||
parent, so the original references to the child can be used to modify the parent after attachment. The default
|
||||
behavior is to perform such a shallow copy. The old behavior of creating a deep copy of the child model while
|
||||
attaching can be restored by setting the deep copy flag to 1.
|
||||
- Added :ref:`potential<sensor-e_potential>` and :ref:`kinetic<sensor-e_kinetic>` energy sensors.
|
||||
- Improved shadow rendering in the native renderer.
|
||||
- Moved ``introspect`` to ``python/introspect``.
|
||||
- Removed the ``particle`` composite type. It is recommended to use the more generic :ref:`replicate<replicate>`
|
||||
instead, for example `this model
|
||||
<https://github.com/google-deepmind/mujoco/blob/main/model/replicate/particle.xml>`__.
|
||||
|
||||
.. admonition:: Breaking API changes
|
||||
:class: attention
|
||||
|
||||
- Added :ref:`mjs_setDeepCopy` API function. When the deep copy flag is 0, attaching a model will not copy it to the
|
||||
parent, so the original references to the child can be used to modify the parent after attachment. The default
|
||||
behavior is to perform such a shallow copy. The old behavior of creating a deep copy of the child model while
|
||||
attaching can be restored by setting the deep copy flag to 1.
|
||||
- Changes to inertia inference from meshes:
|
||||
|
||||
Previously, in order to specify that the mass lies on the surface, :ref:`geom/shellinertia<body-geom-shellinertia>`
|
||||
@@ -52,6 +49,9 @@ General
|
||||
Previously, if the volumetric inertia computation failed (for example due to a very flat mesh), the compiler
|
||||
would silently fall back to surface inertia computation. Now, the compiler will throw an informative error.
|
||||
- Removed the composite type ``grid``. Users should instead use :ref:`flexcomp<body-flexcomp>`.
|
||||
- Removed the ``particle`` composite type. It is recommended to use the more generic :ref:`replicate<replicate>`
|
||||
instead, see for example `this
|
||||
model<https://github.com/google-deepmind/mujoco/blob/main/model/replicate/particle.xml>`__.
|
||||
|
||||
MJX
|
||||
^^^
|
||||
|
||||
+48
-57
@@ -1121,59 +1121,40 @@ Intrinsics
|
||||
Composite objects
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Composite objects are not new model elements. Instead, they are (large) collections of existing elements designed to
|
||||
simulate particle systems, ropes, cloth, and soft bodies. These collections are generated by the model compiler
|
||||
automatically. The user configures the automatic generator on a high level, using the new XML element
|
||||
:ref:`composite <body-composite>` and its attributes and sub-elements, as described in the XML reference
|
||||
chapter. If the compiled model is then saved, :el:`composite` is no longer present and is replaced with the collection
|
||||
of regular model elements that were automatically generated. So think of it as a macro that gets expanded by the model
|
||||
compiler.
|
||||
Composite objects are not new model elements. Instead, they are collections of existing element originally designed to
|
||||
simulate particle systems, ropes, cloth, and soft bodies. Over time, most of these types have been replaced by
|
||||
:ref:`replicate<replicate>` (for repeated objects) and :ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the
|
||||
only supported composite type is now ``cable``, which produces an inextensible chain of bodies connected with ball
|
||||
joints.
|
||||
|
||||
Composite objects are made up of regular MuJoCo bodies, which we call "element bodies" in this context. The element
|
||||
bodies are created as children of the body within which :el:`composite` appears; thus a composite object appears in the
|
||||
same place in the XML where a regular child body may have been defined. Each automatically-generated element body has a
|
||||
single geom attached to it, usually a sphere but could also be a capsule or an ellipsoid. Thus the composite object is
|
||||
essentially a particle system, however the particles can be constrained to move together in ways that simulate various
|
||||
flexible objects. The initial positions of the element bodies form a regular grid in 1D, 2D or 3D. They could all be
|
||||
children of the parent body (which can be the world or another regular body; composite objects cannot be nested) and
|
||||
have joints allowing motion relative to the parent, or they could form a kinematic tree with joints between the element
|
||||
bodies. They can also be connected with tendons with soft equality constraints on the tendon length, creating the
|
||||
necessary coupling. Joint equality constraints are also used in some cases. The :at:`solref` and :at:`solimp` attributes
|
||||
of these equality constraints can be adjusted by the user, thereby adjusting the softness and flexibility of the
|
||||
composite objects.
|
||||
Composite objects are made up of regular MuJoCo bodies, which we call "element bodies" in this context. The collection
|
||||
of element bodies is generated by the model compiler automatically. The user configures the automatic generator on a
|
||||
high level, using the new XML element :ref:`composite <body-composite>` and its attributes and sub-elements, as
|
||||
described in the XML reference chapter. If the compiled model is then saved, :el:`composite` is no longer present and is
|
||||
replaced with the collection of regular model elements that were automatically generated. So think of it as a macro that
|
||||
gets expanded by the model compiler. The element bodies are created as children of the body within which :el:`composite`
|
||||
appears; thus a composite object appears in the same place in the XML where a regular child body may have been defined.
|
||||
Each automatically-generated element body has a single geom attached to it. We have designed the composite object
|
||||
generator to have intuitive high-level controls as much as possible, but at the same time it exposes a large number of
|
||||
options that interact with each other and can profoundly affect the resulting physics. So at some point users should
|
||||
read the :ref:`reference documentation <body-composite>` carefully.
|
||||
|
||||
In addition to setting up the physics, the composite object generator creates suitable rendering. 2D and 3D objects
|
||||
can be rendered as :ref:`skins <asset-skin>`. The skin is generated
|
||||
automatically, and can be textured as well as subdivided using bi-cubic interpolation. The actual physics and in
|
||||
particular the collision detection are based on the element bodies and their geoms, while the skin is purely a
|
||||
visualization object. Yet in most situations we prefer to look at the skin representation. To facilitate this, the
|
||||
generator places all geoms, sites and tendons in group 3 whose visualization is disabled by default. So when you load
|
||||
a 2D grid for example, you will see a continuous flexible surface and not a collection of spheres connected with
|
||||
tendons. However when fine-tuning the model and trying to understand the physics behind it, it is useful to be able to
|
||||
render the spheres and tendons. To switch the rendering style, disable the rendering of skins and enable group 3 for
|
||||
geoms and tendons.
|
||||
|
||||
We have designed the composite object generator to have intuitive high-level controls as much as possible, but at the
|
||||
same time it exposes a large number of options that interact with each other and can profoundly affect the resulting
|
||||
physics. So at some point users should read the :ref:`reference documentation <body-composite>` carefully.
|
||||
As a quick start though, MuJoCo comes with an example of each composite object type. Below we go over these
|
||||
examples and explain the less obvious aspects. In all examples we have a static scene which is included in the model,
|
||||
followed by a single composite object. The static scene has a mocap body (large capsule) that can be moved around with
|
||||
the mouse to probe the behavior of the system. The XML snippets below are just the definition of the composite object;
|
||||
see the XML model files in the distribution for the complete examples.
|
||||
|
||||
**Particle**.
|
||||
|
||||
The particle type is deprecated. It is recommended to use the more generic :ref:`replicate<replicate>` instead, for
|
||||
example `this model <https://github.com/google-deepmind/mujoco/blob/main/model/replicate/particle.xml>`__.
|
||||
|
||||
**Grid**.
|
||||
|
||||
The grid composite type has been removed. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for
|
||||
simulating thin elastic structures.
|
||||
In addition to setting up the physics, the composite object generator creates suitable rendering. Objects can be
|
||||
rendered as :ref:`skins <asset-skin>`. The skin is generated automatically, and can be textured as well as subdivided
|
||||
using bi-cubic interpolation. The actual physics and in particular the collision detection are based on the element
|
||||
bodies and their geoms, while the skin is purely a visualization object. Yet in some situations we prefer to look at the
|
||||
skin representation, as in `this model
|
||||
<https://github.com/google-deepmind/mujoco/blob/main/model/plugin/elasticity/belt.xml>`__, whose skin is a continuous
|
||||
flexible surface and not a collection of discontinuous thin boxes. However when fine-tuning the model and trying to
|
||||
understand the physics behind it, it is useful to be able to render the geoms. To switch the rendering style, disable
|
||||
the rendering of skins and enable group 3 for geoms and tendons.
|
||||
|
||||
**Cable**.
|
||||
|
||||
As a quick start, MuJoCo comes with an example of composite cables. In all examples we have a static scene which is
|
||||
included in the model, followed by a single composite object. The XML snippets below are just the definition of the
|
||||
composite object; see the XML model files in the distribution for the complete examples.
|
||||
|
||||
|coil|
|
||||
|
||||
.. code-block:: xml
|
||||
@@ -1207,6 +1188,16 @@ stiffnesses can be set independently. Moreover, it is possible to specify if the
|
||||
curve, such as in the case of coil springs. The cable requires using a first-party :ref:`engine plugin<exPlugin>`, which
|
||||
may be integrated directly into the engine in the future.
|
||||
|
||||
**Particle**.
|
||||
|
||||
The particle type is deprecated. It is recommended to use the more generic :ref:`replicate<replicate>` instead, for
|
||||
example `this model <https://github.com/google-deepmind/mujoco/blob/main/model/replicate/particle.xml>`__.
|
||||
|
||||
**Grid**.
|
||||
|
||||
The grid composite type has been removed. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for
|
||||
simulating thin elastic structures.
|
||||
|
||||
**Rope and loop**.
|
||||
|
||||
The rope and loop are deprecated. It is recommended to use the cable for simulating inextensible elastic rods that are
|
||||
@@ -1431,15 +1422,15 @@ mocap bodies around:
|
||||
|
||||
|particle|
|
||||
|
||||
The key thing to understand about mocap bodies is that the simulator treats them as being fixed. We are causing them
|
||||
to move from one simulation time step to the next by updating their position and orientation directly, but as far as
|
||||
the physics model is concerned their position and orientation are constant. So what happens if we make contact with a
|
||||
regular dynamic body, as in the composite object examples provided with the MuJoCo distribution (recall that in
|
||||
those example we have a capsule probe which is a mocap body that we move with the mouse). A contact between two
|
||||
regular bodies will experience penetration as well as relative velocity, while contact with a mocap body is missing
|
||||
the relative velocity component because the simulator does not know that the mocap body itself is moving. So the
|
||||
resulting contact force is smaller and it takes longer for the contact to push the dynamic object away. Also, in more
|
||||
complex simulations the fact that we are doing something inconsistent with the physics can cause instabilities.
|
||||
The key thing to understand about mocap bodies is that the simulator treats them as being fixed. We are causing them to
|
||||
move from one simulation time step to the next by updating their position and orientation directly, but as far as the
|
||||
physics model is concerned their position and orientation are constant. So what happens if we make contact with a
|
||||
regular dynamic body, as in the particle examples provided with the MuJoCo distribution (recall that in those example we
|
||||
have a capsule probe which is a mocap body that we move with the mouse). A contact between two regular bodies will
|
||||
experience penetration as well as relative velocity, while contact with a mocap body is missing the relative velocity
|
||||
component because the simulator does not know that the mocap body itself is moving. So the resulting contact force is
|
||||
smaller and it takes longer for the contact to push the dynamic object away. Also, in more complex simulations the fact
|
||||
that we are doing something inconsistent with the physics can cause instabilities.
|
||||
|
||||
There is however a better-behaved alternative. In addition to the mocap body, we include a second regular body and
|
||||
connect it to the mocap body with a weld equality constraint. In the plots below, the pink box is the mocap body and
|
||||
|
||||
@@ -58,7 +58,6 @@ mjCComposite::mjCComposite(void) {
|
||||
type = mjCOMPTYPE_PARTICLE;
|
||||
count[0] = count[1] = count[2] = 1;
|
||||
mjuu_setvec(offset, 0, 0, 0);
|
||||
flatinertia = 0;
|
||||
|
||||
// plugin variables
|
||||
mjs_defaultPlugin(&plugin);
|
||||
|
||||
@@ -38,11 +38,6 @@ typedef enum _mjtCompType {
|
||||
|
||||
typedef enum _mjtCompKind {
|
||||
mjCOMPKIND_JOINT = 0,
|
||||
mjCOMPKIND_TWIST,
|
||||
mjCOMPKIND_STRETCH,
|
||||
mjCOMPKIND_TENDON,
|
||||
mjCOMPKIND_SHEAR,
|
||||
mjCOMPKIND_PARTICLE,
|
||||
|
||||
mjNCOMPKINDS
|
||||
} mjtCompKind;
|
||||
@@ -79,7 +74,6 @@ class mjCComposite {
|
||||
mjtCompType type; // composite type
|
||||
int count[3]; // geom count in each dimension
|
||||
double offset[3]; // position offset for particle and grid
|
||||
double flatinertia; // flatten ineria of cloth elements; 0: disable
|
||||
|
||||
// currently used only for cable
|
||||
std::string initial; // root boundary type
|
||||
|
||||
@@ -287,8 +287,8 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||
{"<"},
|
||||
{"config", "*", "2", "key", "value"},
|
||||
{">"},
|
||||
{"composite", "*", "9", "prefix", "type", "count", "offset",
|
||||
"flatinertia", "vertex", "initial", "curve", "size"},
|
||||
{"composite", "*", "8", "prefix", "type", "count", "offset",
|
||||
"vertex", "initial", "curve", "size"},
|
||||
{"<"},
|
||||
{"joint", "*", "17", "kind", "group", "stiffness", "damping", "armature",
|
||||
"solreffix", "solimpfix", "type", "axis",
|
||||
@@ -742,11 +742,8 @@ const mjMap comp_map[mjNCOMPTYPES] = {
|
||||
|
||||
|
||||
// composite joint kind
|
||||
const mjMap jkind_map[4] = {
|
||||
{"main", mjCOMPKIND_JOINT},
|
||||
{"twist", mjCOMPKIND_TWIST},
|
||||
{"stretch", mjCOMPKIND_STRETCH},
|
||||
{"particle", mjCOMPKIND_PARTICLE}
|
||||
const mjMap jkind_map[1] = {
|
||||
{"main", mjCOMPKIND_JOINT}
|
||||
};
|
||||
|
||||
|
||||
@@ -2399,7 +2396,6 @@ void mjXReader::OneComposite(XMLElement* elem, mjsBody* body, const mjsDefault*
|
||||
}
|
||||
ReadAttr(elem, "count", 3, comp.count, text, false, false);
|
||||
ReadAttr(elem, "offset", 3, comp.offset, text);
|
||||
ReadAttr(elem, "flatinertia", 1, &comp.flatinertia, text);
|
||||
|
||||
// plugin
|
||||
XMLElement* eplugin = FirstChildElement(elem, "plugin");
|
||||
@@ -2502,7 +2498,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjsBody* body, const mjsDefault*
|
||||
while (ejnt) {
|
||||
// kind
|
||||
int kind;
|
||||
MapValue(ejnt, "kind", &kind, jkind_map, 4, true);
|
||||
MapValue(ejnt, "kind", &kind, jkind_map, 1, true);
|
||||
|
||||
// create a new element if this kind already exists
|
||||
if (comp.add[kind]) {
|
||||
|
||||
Reference in New Issue
Block a user