Remove grid from composite types.
Replaced it with flexcomp in the models. PiperOrigin-RevId: 730070619 Change-Id: Icbc69e4c6784c6252743f689a1eafb6482d0c393
This commit is contained in:
committed by
Copybara-Service
parent
b90ff3f0b1
commit
0fcd20f0da
+1
-36
@@ -2982,7 +2982,7 @@ coordinates results in compiler error. See :ref:`CComposite` in the modeling gui
|
||||
|
||||
.. _body-composite-type:
|
||||
|
||||
:at:`type`: :at-val:`[particle, grid, cable, rope, loop, cloth, box, cylinder, ellipsoid], required`
|
||||
: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.
|
||||
|
||||
@@ -2993,13 +2993,6 @@ coordinates results in compiler error. See :ref:`CComposite` in the modeling gui
|
||||
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`.
|
||||
|
||||
The **grid** type creates a 1D or 2D grid of bodies, each having a sphere geom, a sphere site, and 3 orthogonal
|
||||
sliding joints by default. The :el:`pin` sub-element can be used to specify that some bodies should not have joints,
|
||||
and instead should be pinned to the parent body. Unlike the particle type, here each two neighboring bodies are
|
||||
connected with a spatial tendon whose length is equality-constrained to its initial value (the sites are needed to
|
||||
define the tendons). The "main" tendons are parallel to the axes of the grid. In addition one can create diagonal
|
||||
"shear" tendons, using the :el:`tendon` sub-element. This type is suitable for simulating strings as well as cloth.
|
||||
|
||||
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`
|
||||
or with prescribed functions with the option :at:`curve`. Currently, only linear and trigonometric functions are
|
||||
@@ -3007,34 +3000,6 @@ coordinates results in compiler error. See :ref:`CComposite` in the modeling gui
|
||||
:at:`size`, resulting in :math:`f(s)=\{\text{size}[1]\cdot\cos(2\pi\cdot\text{size}[2]),\;
|
||||
\text{size}[1]\cdot\sin(2\pi\cdot\text{size}[2]),\; \text{size}[0]\cdot s\}`.
|
||||
|
||||
The **cloth** type is a different way to model cloth, beyond type="grid". Here the elements are connected with
|
||||
universal joints and form a kinematic spanning tree. The root of the tree is the parent body, and its coordinates in
|
||||
the grid are inferred from its name - similar to rope but here the naming format is "CB2_0". Neighboring bodies that
|
||||
are not connected with joints are then connected with equality-constrained spatial tendons. The resulting cloth is
|
||||
non-homogeneous, because the kinematic constraints cannot be violated while the tendon equality constraints are soft.
|
||||
One can make it more homogeneous by adding stretch and twist joints (similar to rope) and adjusting the strength of
|
||||
their equality constraints. Shear tendons can also be added. In addition to the different physics, cloth can do
|
||||
things that a 2D grid cannot do. This is because the elements of cloth have both position and orientation, while the
|
||||
elements of grid can only translate. The geoms used in cloth can be ellipsoids and capsules in addition to spheres.
|
||||
When elongated geoms are used, they are rotated and interleaved in a pattern that fills the holes, preventing objects
|
||||
from penetrating the cloth. Furthermore the inertia of the cloth elements can be modified with the flatinertia
|
||||
attribute, and can then be used with lift and drag forces to simulate ripple effects.
|
||||
|
||||
The **box** type creates a 3D arrangement of bodies forming the outer shell of a (soft) box. The parent body is at
|
||||
the center of the box. Each element body has a geom (sphere, ellipsoid or capsule) and a single sliding joint
|
||||
pointing away from the center of the box. The sliding joints are equality-constrained to their initial value.
|
||||
Furthermore, to achieve smooth deformations of the sides of the box, each joint is equality-constrained to remain
|
||||
equal to its neighbor joints. To preserve the volume of the soft box approximately, a fixed tendon is used to
|
||||
constrain the sum of all joints to remain constant. When the user specifies elongated geoms (capsules or ellipsoids)
|
||||
their long axis is aligned with the sliding joint axis. This makes the shell thicker for collision detection
|
||||
purposes, preventing objects from penetrating the box. It is important to disable contacts between the elements of
|
||||
the box. This is done by setting the default geom contype to 0. The user can change it of course, but if the geoms
|
||||
comprising the soft box are allowed to contact each other the model will not work as intended.
|
||||
|
||||
The **cylinder** and **ellipsoid** types are the same as box, except the elements are projected on the surface of an
|
||||
ellipsoid or a cylinder respectively. Thus the composite soft body shape is different, while everything else is the
|
||||
same as in the box type.
|
||||
|
||||
.. _body-composite-count:
|
||||
|
||||
:at:`count`: :at-val:`int(3), required`
|
||||
|
||||
@@ -48,6 +48,7 @@ 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>`.
|
||||
|
||||
MJX
|
||||
^^^
|
||||
|
||||
+3
-40
@@ -1193,47 +1193,10 @@ a more complete treatment, see again the :ref:`deformable <CDeformable>` section
|
||||
flex, see the folder `elasticity/ <https://github.com/google-deepmind/mujoco/tree/main/model/plugin/elasticity>`__ for
|
||||
several examples.
|
||||
|
||||
**1D grid**.
|
||||
**Grid**.
|
||||
|
||||
|image6| |image7|
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<composite type="grid" count="20 1 1" spacing="0.045" offset="0 0 1">
|
||||
<joint kind="main" damping="0.001"/>
|
||||
<tendon kind="main" width="0.01"/>
|
||||
<geom size=".02" rgba=".8 .2 .1 1"/>
|
||||
<pin coord="1"/>
|
||||
<pin coord="13"/>
|
||||
</composite>
|
||||
|
||||
The grid type can create 1D or 2D grids, depending on the :at:`count` attribute. Here we illustrate 1D grids. These
|
||||
are strings of spheres connected with tendons whose length is soft-equality-constrained. The softness can be adjusted.
|
||||
Similar to particles, the element bodies here have slider joints but no rotational joints. The plot on the right
|
||||
illustrates pinning. The :el:`pin` sub-element is used to specify the grid coordinates of the pinned bodies, and the
|
||||
model compiler does not generate joints for these bodies, thereby fixing them rigidly to the parent body (in this case
|
||||
the world). This makes the string in the right plot hang in space. The same mechanism can be used to model a whip for
|
||||
example; in that case the parent body would be moving, and the first element body would be pinned to the parent.
|
||||
|
||||
**2D grid**.
|
||||
|
||||
|image8| |image9|
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
||||
<skin material="matcarpet" inflate="0.001" subgrid="3" texcoord="true"/>
|
||||
<geom size=".02"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
</composite>
|
||||
|
||||
A 2D grid can be used to simulate cloth. What it really simulates is a 2D grid of spheres connected with
|
||||
equality-constrained tendons (not shown). The model compiler can also generate skin, enabled with the :el:`skin`
|
||||
sub-element in the above XML. Some of the element bodies can also be pinned, similar to 1D grids but using two grid
|
||||
coordinates. The plot on the right shows a cloth pinned to the world body at the two corners, and draping over our
|
||||
capsule probe. The skin on the right is subdivided using bi-cubic interpolation, which increases visual quality in the
|
||||
absence of textures. When textures are present (left) the benefits of subdivision are less visible.
|
||||
The grid composite type has been removed. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for
|
||||
simulating thin elastic structures.
|
||||
|
||||
**Cable**.
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<!-- Copyright 2021 DeepMind Technologies Limited
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<mujoco model="2D grid with pins">
|
||||
<include file="scene.xml"/>
|
||||
|
||||
<size memory="10M"/>
|
||||
|
||||
<worldbody>
|
||||
<composite type="grid" count="9 9 1" spacing="0.05" offset="0 0 1">
|
||||
<skin rgba=".6 .1 .6 1" inflate="0.001" subgrid="3"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="8 0"/>
|
||||
<geom size=".02"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
+11
-12
@@ -22,7 +22,7 @@
|
||||
Simple humanoid on a hammock, implemented as a 2D grid composite, pinned at the corners.
|
||||
-->
|
||||
|
||||
<option timestep="0.005" solver="CG" iterations="30" tolerance="1e-6"/>
|
||||
<option timestep="0.001" solver="CG" iterations="30" tolerance="1e-6"/>
|
||||
|
||||
<size memory="20M"/>
|
||||
|
||||
@@ -41,23 +41,22 @@
|
||||
width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
|
||||
<material name="plane" reflectance="0.3" texture="plane" texrepeat="1 1" texuniform="true"/>
|
||||
<material name="hammock" texture="hammock"/>
|
||||
<model name="humanoid" file="../humanoid/humanoid.xml"/>
|
||||
</asset>
|
||||
|
||||
<include file="humanoid_body.xml"/>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="plane" condim="3"/>
|
||||
<light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
|
||||
<light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4" dir="0 0 -1"/>
|
||||
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
|
||||
<skin texcoord="true" material="hammock" inflate="0.01" subgrid="3"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="10 0"/>
|
||||
<pin coord="0 8"/>
|
||||
<pin coord="10 8"/>
|
||||
<geom size=".095"/>
|
||||
<joint kind="main" damping="10"/>
|
||||
</composite>
|
||||
<flexcomp name="hammock" type="grid" count="11 9 1" spacing="0.2 0.2 0.2" material="hammock"
|
||||
radius="0.04" dim="2">
|
||||
<pin id="0 8 90 98"/>
|
||||
<edge equality="true" solref="0.002 5"/>
|
||||
<contact selfcollide="none" internal="false" solimp=".99 .999 .00001"/>
|
||||
</flexcomp>
|
||||
<frame euler="0 180 -15" pos="-.4 -.2 2">
|
||||
<attach model="humanoid" body="torso" prefix="humanoid_"/>
|
||||
</frame>
|
||||
</worldbody>
|
||||
|
||||
</mujoco>
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
<!-- Copyright 2021 DeepMind Technologies Limited
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<mujoco model="Humanoid body">
|
||||
<!-- Degree of Freedom: 27
|
||||
Actuators: 21
|
||||
|
||||
This simplified humanoid model, introduced in [1], is designed for bipedal locomotion
|
||||
behaviours. While several variants of it exist in the wild, this version is based on the model
|
||||
in the DeepMind Control Suite [2], which has fairly realistic actuator gains.
|
||||
[1] Synthesis and Stabilization of Complex Behaviors through Online Trajectory Optimization.
|
||||
https://doi.org/10.1109/IROS.2012.6386025
|
||||
[2] DeepMind Control Suite, Tassa et al. https://arxiv.org/abs/1801.00690
|
||||
-->
|
||||
|
||||
<asset>
|
||||
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128"
|
||||
rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
||||
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||
</asset>
|
||||
|
||||
<default>
|
||||
<motor ctrlrange="-1 1" ctrllimited="true"/>
|
||||
<default class="body">
|
||||
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body"/>
|
||||
<joint type="hinge" damping=".2" stiffness="1" armature=".01" limited="true" solimplimit="0 .99 .01"/>
|
||||
<default class="big_joint">
|
||||
<joint damping="5" stiffness="10"/>
|
||||
<default class="big_stiff_joint">
|
||||
<joint stiffness="20"/>
|
||||
</default>
|
||||
</default>
|
||||
</default>
|
||||
</default>
|
||||
|
||||
<visual>
|
||||
<map force="0.1" zfar="30"/>
|
||||
<rgba haze="0.15 0.25 0.35 1"/>
|
||||
<quality shadowsize="4096"/>
|
||||
<global offwidth="800" offheight="800"/>
|
||||
</visual>
|
||||
|
||||
<worldbody>
|
||||
<body name="torso" pos="0 0 1.5" childclass="body">
|
||||
<camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
|
||||
<camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
|
||||
<freejoint name="root"/>
|
||||
<geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
|
||||
<geom name="upper_waist" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
|
||||
<body name="head" pos="0 0 .19">
|
||||
<geom name="head" type="sphere" size=".09"/>
|
||||
<camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
|
||||
</body>
|
||||
<body name="lower_waist" pos="-.01 0 -.26">
|
||||
<geom name="lower_waist" fromto="0 -.06 0 0 .06 0" size=".06"/>
|
||||
<joint name="abdomen_z" pos="0 0 .065" axis="0 0 1" range="-45 45" class="big_stiff_joint"/>
|
||||
<joint name="abdomen_y" pos="0 0 .065" axis="0 1 0" range="-75 30" class="big_joint"/>
|
||||
<body name="pelvis" pos="0 0 -.165">
|
||||
<joint name="abdomen_x" pos="0 0 .1" axis="1 0 0" range="-35 35" class="big_joint"/>
|
||||
<geom name="butt" fromto="-.02 -.07 0 -.02 .07 0" size=".09"/>
|
||||
<body name="right_thigh" pos="0 -.1 -.04">
|
||||
<joint name="right_hip_x" axis="1 0 0" range="-25 5" class="big_joint"/>
|
||||
<joint name="right_hip_z" axis="0 0 1" range="-60 35" class="big_joint"/>
|
||||
<joint name="right_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
|
||||
<geom name="right_thigh" fromto="0 0 0 0 .01 -.34" size=".06"/>
|
||||
<body name="right_shin" pos="0 .01 -.403">
|
||||
<joint name="right_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
|
||||
<geom name="right_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
|
||||
<body name="right_foot" pos="0 0 -.39">
|
||||
<joint name="right_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
|
||||
<joint name="right_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
|
||||
<geom name="right_right_foot" fromto="-.07 -.02 0 .14 -.04 0" size=".027"/>
|
||||
<geom name="left_right_foot" fromto="-.07 0 0 .14 .02 0" size=".027"/>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="left_thigh" pos="0 .1 -.04">
|
||||
<joint name="left_hip_x" axis="-1 0 0" range="-25 5" class="big_joint"/>
|
||||
<joint name="left_hip_z" axis="0 0 -1" range="-60 35" class="big_joint"/>
|
||||
<joint name="left_hip_y" axis="0 1 0" range="-110 20" class="big_stiff_joint"/>
|
||||
<geom name="left_thigh" fromto="0 0 0 0 -.01 -.34" size=".06"/>
|
||||
<body name="left_shin" pos="0 -.01 -.403">
|
||||
<joint name="left_knee" pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
|
||||
<geom name="left_shin" fromto="0 0 0 0 0 -.3" size=".049"/>
|
||||
<body name="left_foot" pos="0 0 -.39">
|
||||
<joint name="left_ankle_y" pos="0 0 .08" axis="0 1 0" range="-50 50" stiffness="6"/>
|
||||
<joint name="left_ankle_x" pos="0 0 .04" axis="1 0 .5" range="-50 50" stiffness="3"/>
|
||||
<geom name="left_left_foot" fromto="-.07 .02 0 .14 .04 0" size=".027"/>
|
||||
<geom name="right_left_foot" fromto="-.07 0 0 .14 -.02 0" size=".027"/>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="right_upper_arm" pos="0 -.17 .06">
|
||||
<joint name="right_shoulder1" axis="2 1 1" range="-85 60"/>
|
||||
<joint name="right_shoulder2" axis="0 -1 1" range="-85 60"/>
|
||||
<geom name="right_upper_arm" fromto="0 0 0 .16 -.16 -.16" size=".04 .16"/>
|
||||
<body name="right_lower_arm" pos=".18 -.18 -.18">
|
||||
<joint name="right_elbow" axis="0 -1 1" range="-90 50" stiffness="0"/>
|
||||
<geom name="right_lower_arm" fromto=".01 .01 .01 .17 .17 .17" size=".031"/>
|
||||
<body name="right_hand" pos=".18 .18 .18">
|
||||
<geom name="right_hand" type="sphere" size=".04" zaxis="1 1 1"/>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
<body name="left_upper_arm" pos="0 .17 .06">
|
||||
<joint name="left_shoulder1" axis="2 -1 1" range="-60 85"/>
|
||||
<joint name="left_shoulder2" axis="0 1 1" range="-60 85"/>
|
||||
<geom name="left_upper_arm" fromto="0 0 0 .16 .16 -.16" size=".04 .16"/>
|
||||
<body name="left_lower_arm" pos=".18 .18 -.18">
|
||||
<joint name="left_elbow" axis="0 -1 -1" range="-90 50" stiffness="0"/>
|
||||
<geom name="left_lower_arm" fromto=".01 -.01 .01 .17 -.17 .17" size=".031"/>
|
||||
<body name="left_hand" pos=".18 -.18 .18">
|
||||
<geom name="left_hand" type="sphere" size=".04" zaxis="1 -1 1"/>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</body>
|
||||
</worldbody>
|
||||
|
||||
<actuator>
|
||||
<motor name="abdomen_y" gear="40" joint="abdomen_y"/>
|
||||
<motor name="abdomen_z" gear="40" joint="abdomen_z"/>
|
||||
<motor name="abdomen_x" gear="40" joint="abdomen_x"/>
|
||||
<motor name="right_hip_x" gear="40" joint="right_hip_x"/>
|
||||
<motor name="right_hip_z" gear="40" joint="right_hip_z"/>
|
||||
<motor name="right_hip_y" gear="120" joint="right_hip_y"/>
|
||||
<motor name="right_knee" gear="80" joint="right_knee"/>
|
||||
<motor name="right_ankle_x" gear="20" joint="right_ankle_x"/>
|
||||
<motor name="right_ankle_y" gear="20" joint="right_ankle_y"/>
|
||||
<motor name="left_hip_x" gear="40" joint="left_hip_x"/>
|
||||
<motor name="left_hip_z" gear="40" joint="left_hip_z"/>
|
||||
<motor name="left_hip_y" gear="120" joint="left_hip_y"/>
|
||||
<motor name="left_knee" gear="80" joint="left_knee"/>
|
||||
<motor name="left_ankle_x" gear="20" joint="left_ankle_x"/>
|
||||
<motor name="left_ankle_y" gear="20" joint="left_ankle_y"/>
|
||||
<motor name="right_shoulder1" gear="20" joint="right_shoulder1"/>
|
||||
<motor name="right_shoulder2" gear="20" joint="right_shoulder2"/>
|
||||
<motor name="right_elbow" gear="40" joint="right_elbow"/>
|
||||
<motor name="left_shoulder1" gear="20" joint="left_shoulder1"/>
|
||||
<motor name="left_shoulder2" gear="20" joint="left_shoulder2"/>
|
||||
<motor name="left_elbow" gear="40" joint="left_elbow"/>
|
||||
</actuator>
|
||||
</mujoco>
|
||||
+7
-205
@@ -59,9 +59,7 @@ mjCComposite::mjCComposite(void) {
|
||||
count[0] = count[1] = count[2] = 1;
|
||||
spacing = 0;
|
||||
mjuu_setvec(offset, 0, 0, 0);
|
||||
pin.clear();
|
||||
flatinertia = 0;
|
||||
mj_defaultSolRefImp(solrefsmooth, solimpsmooth);
|
||||
|
||||
// plugin variables
|
||||
mjs_defaultPlugin(&plugin);
|
||||
@@ -95,23 +93,6 @@ mjCComposite::mjCComposite(void) {
|
||||
|
||||
|
||||
|
||||
// adjust constraint softness
|
||||
void mjCComposite::AdjustSoft(mjtNum* solref, mjtNum* solimp, int level) {
|
||||
switch (level) {
|
||||
case 0:
|
||||
solref[0] = 0.01;
|
||||
solimp[0] = solimp[1] = 0.99;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
solref[0] = 0.02;
|
||||
solimp[0] = solimp[1] = 0.9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create the array of default joint options, append new elements only for particles type
|
||||
bool mjCComposite::AddDefaultJoint(char* error, int error_sz) {
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
@@ -131,14 +112,6 @@ bool mjCComposite::AddDefaultJoint(char* error, int error_sz) {
|
||||
|
||||
// set defaults, after reading top-level info and skin
|
||||
void mjCComposite::SetDefault(void) {
|
||||
// determine dimensionality
|
||||
int tmpdim = 0;
|
||||
for (int i=0; i<3; i++) {
|
||||
if (count[i]>1) {
|
||||
tmpdim++;
|
||||
}
|
||||
}
|
||||
|
||||
// set all default groups to 3
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
def[i].spec.geom->group = 3;
|
||||
@@ -152,10 +125,7 @@ void mjCComposite::SetDefault(void) {
|
||||
// set default geom and tendon group to 0 if needed to be visible
|
||||
if (!skin ||
|
||||
type==mjCOMPTYPE_PARTICLE ||
|
||||
type==mjCOMPTYPE_ROPE ||
|
||||
type==mjCOMPTYPE_LOOP ||
|
||||
type==mjCOMPTYPE_CABLE ||
|
||||
(type==mjCOMPTYPE_GRID && tmpdim==1)) {
|
||||
type==mjCOMPTYPE_CABLE) {
|
||||
for (int i=0; i<mjNCOMPKINDS; i++) {
|
||||
def[i].spec.geom->group = 0;
|
||||
def[i].spec.tendon->group = 0;
|
||||
@@ -171,25 +141,7 @@ void mjCComposite::SetDefault(void) {
|
||||
def[0].spec.geom->priority = 1;
|
||||
break;
|
||||
|
||||
case mjCOMPTYPE_GRID: // grid
|
||||
|
||||
// hard main tendon fix
|
||||
AdjustSoft(def[mjCOMPKIND_TENDON].spec.equality->solref,
|
||||
def[mjCOMPKIND_TENDON].spec.equality->solimp, 0);
|
||||
|
||||
break;
|
||||
|
||||
case mjCOMPTYPE_CABLE: // cable
|
||||
case mjCOMPTYPE_ROPE: // rope
|
||||
break;
|
||||
|
||||
case mjCOMPTYPE_LOOP: // loop
|
||||
|
||||
// hard smoothing
|
||||
AdjustSoft(solrefsmooth, solimpsmooth, 0);
|
||||
break;
|
||||
|
||||
case mjCOMPTYPE_CLOTH: // cloth
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -213,11 +165,6 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz)
|
||||
return comperr(error, "Composite geom type must be sphere, capsule or ellipsoid", error_sz);
|
||||
}
|
||||
|
||||
// check pin coord number
|
||||
if (pin.size()%2) {
|
||||
return comperr(error, "Pin coordinate number of must be multiple of 2", error_sz);
|
||||
}
|
||||
|
||||
// check counts
|
||||
for (int i=0; i<3; i++) {
|
||||
if (count[i]<1) {
|
||||
@@ -305,7 +252,10 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz)
|
||||
return MakeParticle(model, body, error, error_sz);
|
||||
|
||||
case mjCOMPTYPE_GRID:
|
||||
return MakeGrid(model, body, error, error_sz);
|
||||
return comperr(error,
|
||||
"The \"grid\" composite type is deprecated. Please use "
|
||||
"\"flex\" instead.",
|
||||
error_sz);
|
||||
|
||||
case mjCOMPTYPE_ROPE:
|
||||
return comperr(error,
|
||||
@@ -413,123 +363,6 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int
|
||||
|
||||
|
||||
|
||||
// make grid connected with tendons
|
||||
bool mjCComposite::MakeGrid(mjCModel* model, mjsBody* body, char* error, int error_sz) {
|
||||
char txt[100], txt1[100], txt2[100];
|
||||
|
||||
// check dimensionality
|
||||
if (dim>2) {
|
||||
return comperr(error, "Grid can only be 1D or 2D", error_sz);
|
||||
}
|
||||
|
||||
// check shear dimensionality
|
||||
if (add[mjCOMPKIND_SHEAR] && dim!=2) {
|
||||
return comperr(error, "Shear requires 2D grid", error_sz);
|
||||
}
|
||||
|
||||
// check skin dimensionality
|
||||
if (skin && dim!=2) {
|
||||
return comperr(error, "Skin requires 2D grid", error_sz);
|
||||
}
|
||||
|
||||
// create bodies, joints, geoms, sites
|
||||
for (int ix=0; ix<count[0]; ix++) {
|
||||
for (int iy=0; iy<count[1]; iy++) {
|
||||
// create body
|
||||
mjsBody* b = mjs_addBody(body, NULL);
|
||||
mju::sprintf_arr(txt, "%sB%d_%d", prefix.c_str(), ix, iy);
|
||||
mjs_setString(b->name, txt);
|
||||
|
||||
// set body position
|
||||
b->pos[0] = offset[0] + spacing*(ix - 0.5*count[0]);
|
||||
b->pos[1] = offset[1] + spacing*(iy - 0.5*count[1]);
|
||||
b->pos[2] = offset[2];
|
||||
|
||||
// add geom
|
||||
mjsGeom* g = mjs_addGeom(b, &def[0].spec);
|
||||
mjs_setDefault(g->element, mjs_getDefault(body->element));
|
||||
g->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sG%d_%d", prefix.c_str(), ix, iy);
|
||||
mjs_setString(g->name, txt);
|
||||
|
||||
// add site
|
||||
mjsSite* s = mjs_addSite(b, &def[0].spec);
|
||||
mjs_setDefault(s->element, mjs_getDefault(body->element));
|
||||
s->type = mjGEOM_SPHERE;
|
||||
mju::sprintf_arr(txt, "%sS%d_%d", prefix.c_str(), ix, iy);
|
||||
mjs_setString(s->name, txt);
|
||||
|
||||
// skip pinned elements
|
||||
bool skip = false;
|
||||
for (int ip=0; ip<pin.size(); ip+=2) {
|
||||
if (pin[ip]==ix && pin[ip+1]==iy) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add slider joint
|
||||
mjsJoint* jnt[3];
|
||||
for (int i=0; i<3; i++) {
|
||||
jnt[i] = mjs_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec);
|
||||
mjs_setDefault(jnt[i]->element, mjs_getDefault(body->element));
|
||||
mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), i, ix, iy);
|
||||
mjs_setString(jnt[i]->name, txt);
|
||||
jnt[i]->type = mjJNT_SLIDE;
|
||||
mjuu_setvec(jnt[i]->pos, 0, 0, 0);
|
||||
mjuu_setvec(jnt[i]->axis, 0, 0, 0);
|
||||
jnt[i]->axis[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create tendons and equality constraints
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int ix=0; ix<count[0]-(i==0); ix++) {
|
||||
for (int iy=0; iy<count[1]-(i==1); iy++) {
|
||||
// recover site names
|
||||
mju::sprintf_arr(txt1, "%sS%d_%d", prefix.c_str(), ix, iy);
|
||||
mju::sprintf_arr(txt2, "%sS%d_%d", prefix.c_str(), ix+(i==0), iy+(i==1));
|
||||
|
||||
// create tendon
|
||||
mjCTendon* ten = model->AddTendon(def + mjCOMPKIND_TENDON);
|
||||
ten->classname = model->Default()->name;
|
||||
mju::sprintf_arr(txt, "%sT%d_%d_%d", prefix.c_str(), i, ix, iy);
|
||||
ten->name = txt;
|
||||
ten->WrapSite(txt1);
|
||||
ten->WrapSite(txt2);
|
||||
|
||||
// add equality constraint
|
||||
mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec);
|
||||
mjs_setDefault(eq->element, &model->Default()->spec);
|
||||
eq->type = mjEQ_TENDON;
|
||||
mjs_setString(eq->name1, ten->name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shear for 2D
|
||||
if (add[mjCOMPKIND_SHEAR]) {
|
||||
MakeShear(model);
|
||||
}
|
||||
|
||||
// skin
|
||||
if (skin) {
|
||||
if (skinsubgrid>0) {
|
||||
MakeSkin2Subgrid(model, skininflate);
|
||||
} else {
|
||||
MakeSkin2(model, skininflate);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool mjCComposite::MakeCable(mjCModel* model, mjsBody* body, char* error, int error_sz) {
|
||||
// check dim
|
||||
if (dim!=1) {
|
||||
@@ -730,37 +563,6 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix,
|
||||
|
||||
|
||||
|
||||
// add shear tendons to 2D
|
||||
void mjCComposite::MakeShear(mjCModel* model) {
|
||||
char txt[100], txt1[100], txt2[100];
|
||||
|
||||
for (int ix=0; ix<count[0]-1; ix++) {
|
||||
for (int iy=0; iy<count[1]-1; iy++) {
|
||||
// recover site names
|
||||
mju::sprintf_arr(txt1, "%sS%d_%d", prefix.c_str(), ix, iy);
|
||||
mju::sprintf_arr(txt2, "%sS%d_%d", prefix.c_str(), ix+1, iy+1);
|
||||
|
||||
// create tendon
|
||||
mjCTendon* ten = model->AddTendon(def + mjCOMPKIND_SHEAR);
|
||||
ten->classname = model->Default()->name;
|
||||
ten->WrapSite(txt1);
|
||||
ten->WrapSite(txt2);
|
||||
|
||||
// name tendon
|
||||
mju::sprintf_arr(txt, "%sTS%d_%d", prefix.c_str(), ix, iy);
|
||||
ten->name = txt;
|
||||
|
||||
// equality constraint
|
||||
mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_SHEAR].spec);
|
||||
mjs_setDefault(eq->element, &model->Default()->spec);
|
||||
eq->type = mjEQ_TENDON;
|
||||
mjs_setString(eq->name1, txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// copy local vectors to skin
|
||||
void mjCComposite::CopyIntoSkin(mjsSkin* skin) {
|
||||
mjs_setInt(skin->face, face.data(), face.size());
|
||||
@@ -875,7 +677,7 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) {
|
||||
}
|
||||
|
||||
// couple with bones
|
||||
if (type==mjCOMPTYPE_PARTICLE || type==mjCOMPTYPE_GRID) {
|
||||
if (type==mjCOMPTYPE_PARTICLE) {
|
||||
MakeClothBones(model, skin);
|
||||
} else if (type==mjCOMPTYPE_CABLE) {
|
||||
MakeCableBones(model, skin);
|
||||
@@ -1434,7 +1236,7 @@ void mjCComposite::MakeSkin2Subgrid(mjCModel* model, mjtNum inflate) {
|
||||
face.push_back(NN + iy+1 + (C0-1)*C1);
|
||||
}
|
||||
|
||||
if (type==mjCOMPTYPE_PARTICLE || type==mjCOMPTYPE_GRID) {
|
||||
if (type==mjCOMPTYPE_PARTICLE) {
|
||||
MakeClothBonesSubgrid(model, skin);
|
||||
} else if (type==mjCOMPTYPE_CABLE) {
|
||||
MakeCableBonesSubgrid(model, skin);
|
||||
|
||||
@@ -64,14 +64,10 @@ class mjCComposite {
|
||||
|
||||
void SetDefault(void);
|
||||
bool AddDefaultJoint(char* error = NULL, int error_sz = 0);
|
||||
void AdjustSoft(mjtNum* solref, mjtNum* solimp, int level);
|
||||
|
||||
bool Make(mjSpec* spec, mjsBody* body, char* error, int error_sz);
|
||||
|
||||
bool MakeParticle(mjCModel* model, mjsBody* body, char* error, int error_sz);
|
||||
bool MakeGrid(mjCModel* model, mjsBody* body, char* error, int error_sz);
|
||||
bool MakeCable(mjCModel* model, mjsBody* body, char* error, int error_sz);
|
||||
void MakeShear(mjCModel* model);
|
||||
|
||||
void MakeSkin2(mjCModel* model, mjtNum inflate);
|
||||
void MakeSkin2Subgrid(mjCModel* model, mjtNum inflate);
|
||||
@@ -86,10 +82,7 @@ class mjCComposite {
|
||||
int count[3]; // geom count in each dimension
|
||||
double spacing; // spacing between elements
|
||||
double offset[3]; // position offset for particle and grid
|
||||
std::vector<int> pin; // pin elements of grid (do not create main joint)
|
||||
double flatinertia; // flatten ineria of cloth elements; 0: disable
|
||||
mjtNum solrefsmooth[mjNREF]; // solref for smoothing equality
|
||||
mjtNum solimpsmooth[mjNIMP]; // solimp for smoothing equality
|
||||
|
||||
// currently used only for cable
|
||||
std::string initial; // root boundary type
|
||||
|
||||
@@ -2466,10 +2466,6 @@ void mjXReader::OneComposite(XMLElement* elem, mjsBody* body, const mjsDefault*
|
||||
// set type-specific defaults
|
||||
comp.SetDefault();
|
||||
|
||||
// parse smooth solver parameters after type-specific defaults are set
|
||||
ReadAttr(elem, "solrefsmooth", mjNREF, comp.solrefsmooth, text, false, false);
|
||||
ReadAttr(elem, "solimpsmooth", mjNIMP, comp.solimpsmooth, text, false, false);
|
||||
|
||||
// geom
|
||||
XMLElement* egeom = FirstChildElement(elem, "geom");
|
||||
if (egeom) {
|
||||
@@ -2601,21 +2597,6 @@ void mjXReader::OneComposite(XMLElement* elem, mjsBody* body, const mjsDefault*
|
||||
eten = NextSiblingElement(eten, "tendon");
|
||||
}
|
||||
|
||||
// pin
|
||||
XMLElement* epin = FirstChildElement(elem, "pin");
|
||||
while (epin) {
|
||||
// read
|
||||
int coord[2] = {0, 0};
|
||||
ReadAttr(epin, "coord", 2, coord, text, true, false);
|
||||
|
||||
// insert 2 coordinates (2nd may be unused)
|
||||
comp.pin.push_back(coord[0]);
|
||||
comp.pin.push_back(coord[1]);
|
||||
|
||||
// advance
|
||||
epin = NextSiblingElement(epin, "pin");
|
||||
}
|
||||
|
||||
// make composite
|
||||
char error[200];
|
||||
bool res = comp.Make(spec, body, error, 200);
|
||||
|
||||
+11
-12
@@ -22,7 +22,7 @@
|
||||
Simple humanoid on a hammock, implemented as a 2D grid composite, pinned at the corners.
|
||||
-->
|
||||
|
||||
<option timestep="0.005" solver="CG" iterations="30" tolerance="1e-6"/>
|
||||
<option timestep="0.001" solver="CG" iterations="30" tolerance="1e-6"/>
|
||||
|
||||
<size memory="20M"/>
|
||||
|
||||
@@ -41,23 +41,22 @@
|
||||
width="512" height="512" mark="edge" markrgb=".8 .8 .8"/>
|
||||
<material name="plane" reflectance="0.3" texture="plane" texrepeat="1 1" texuniform="true"/>
|
||||
<material name="hammock" texture="hammock"/>
|
||||
<model name="humanoid" file="humanoid_body.xml"/>
|
||||
</asset>
|
||||
|
||||
<include file="humanoid_body.xml"/>
|
||||
|
||||
<worldbody>
|
||||
<geom name="floor" pos="0 0 -1" size="0 0 .25" type="plane" material="plane" condim="3"/>
|
||||
<light directional="true" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
|
||||
<light directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4" dir="0 0 -1"/>
|
||||
<composite type="grid" count="11 9 1" spacing="0.2" offset="0. 0. 0">
|
||||
<skin texcoord="true" material="hammock" inflate="0.01" subgrid="3"/>
|
||||
<pin coord="0 0"/>
|
||||
<pin coord="10 0"/>
|
||||
<pin coord="0 8"/>
|
||||
<pin coord="10 8"/>
|
||||
<geom size=".095"/>
|
||||
<joint kind="main" damping="10"/>
|
||||
</composite>
|
||||
<flexcomp name="hammock" type="grid" count="11 9 1" spacing="0.2 0.2 0.2" material="hammock"
|
||||
radius="0.04" dim="2">
|
||||
<pin id="0 8 90 98"/>
|
||||
<edge equality="true" damping="10" solimp=".95 .99"/>
|
||||
<contact selfcollide="none" internal="false" solimp=".99 .999 .00001"/>
|
||||
</flexcomp>
|
||||
<frame euler="0 180 0" pos="-.4 -.2 2">
|
||||
<attach model="humanoid" body="torso" prefix="humanoid_"/>
|
||||
</frame>
|
||||
</worldbody>
|
||||
|
||||
</mujoco>
|
||||
|
||||
Vendored
+52
-10
@@ -26,17 +26,59 @@
|
||||
<joint limited="true" range="-45 45"/>
|
||||
<geom type="box" size=".5 .5 .1"/>
|
||||
</body>
|
||||
<body pos="1 -1 .6">
|
||||
<composite prefix="B0" type="grid" count="4 4 1" spacing=".2">
|
||||
<geom group="4" size=".1"/>
|
||||
<skin rgba="1 1 0 1" group="2" inflate=".1"/>
|
||||
</composite>
|
||||
<body pos="1 -1 .6" name="B0_parent">
|
||||
<flexcomp name="B0" type="grid" count="4 4 1" spacing=".2 .2 .2" group="4" radius=".1" dim="2">
|
||||
<edge equality="true"/>
|
||||
<contact internal="false" selfcollide="none"/>
|
||||
</flexcomp>
|
||||
</body>
|
||||
<body pos="-1 1 .6">
|
||||
<composite prefix="B1" type="grid" count="4 4 1" spacing=".2">
|
||||
<geom group="2" size=".1"/>
|
||||
<skin rgba="0 1 1 1" group="4" inflate=".1"/>
|
||||
</composite>
|
||||
<body pos="-1 1 .6" name="B1_parent">
|
||||
<flexcomp name="B1" type="grid" count="4 4 1" spacing=".2 .2 .2" group="2" radius=".1" dim="2">
|
||||
<edge equality="true"/>
|
||||
<contact internal="false" selfcollide="none"/>
|
||||
</flexcomp>
|
||||
</body>
|
||||
</worldbody>
|
||||
<deformable>
|
||||
<skin name="B0Skin" group="2" rgba="1 1 0 1" inflate="0.1"
|
||||
vertex="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
|
||||
face="0 4 5 0 5 1 1 5 6 1 6 2 2 6 7 2 7 3 4 8 9 4 9 5 5 9 10 5 10 6 6 10 11 6 11 7 8 12 13 8 13 9 9 13 14 9 14 10 10 14 15 10 15 11 16 21 20 16 17 21 17 22 21 17 18 22 18 23 22 18 19 23 20 25 24 20 21 25 21 26 25 21 22 26 22 27 26 22 23 27 24 29 28 24 25 29 25 30 29 25 26 30 26 31 30 26 27 31 0 20 4 0 16 20 4 24 8 4 20 24 8 28 12 8 24 28 3 7 23 3 23 19 7 11 27 7 27 23 11 15 31 11 31 27 0 1 17 0 17 16 1 2 18 1 18 17 2 3 19 2 19 18 12 29 13 12 28 29 13 30 14 13 29 30 14 31 15 14 30 31">
|
||||
<bone body="B0_0" bindpos="0 0 0" bindquat="1 0 0 0" vertid="0 16" vertweight="1 1"/>
|
||||
<bone body="B0_1" bindpos="0 0 0" bindquat="1 0 0 0" vertid="1 17" vertweight="1 1"/>
|
||||
<bone body="B0_2" bindpos="0 0 0" bindquat="1 0 0 0" vertid="2 18" vertweight="1 1"/>
|
||||
<bone body="B0_3" bindpos="0 0 0" bindquat="1 0 0 0" vertid="3 19" vertweight="1 1"/>
|
||||
<bone body="B0_4" bindpos="0 0 0" bindquat="1 0 0 0" vertid="4 20" vertweight="1 1"/>
|
||||
<bone body="B0_5" bindpos="0 0 0" bindquat="1 0 0 0" vertid="5 21" vertweight="1 1"/>
|
||||
<bone body="B0_6" bindpos="0 0 0" bindquat="1 0 0 0" vertid="6 22" vertweight="1 1"/>
|
||||
<bone body="B0_7" bindpos="0 0 0" bindquat="1 0 0 0" vertid="7 23" vertweight="1 1"/>
|
||||
<bone body="B0_8" bindpos="0 0 0" bindquat="1 0 0 0" vertid="8 24" vertweight="1 1"/>
|
||||
<bone body="B0_9" bindpos="0 0 0" bindquat="1 0 0 0" vertid="9 25" vertweight="1 1"/>
|
||||
<bone body="B0_10" bindpos="0 0 0" bindquat="1 0 0 0" vertid="10 26" vertweight="1 1"/>
|
||||
<bone body="B0_11" bindpos="0 0 0" bindquat="1 0 0 0" vertid="11 27" vertweight="1 1"/>
|
||||
<bone body="B0_12" bindpos="0 0 0" bindquat="1 0 0 0" vertid="12 28" vertweight="1 1"/>
|
||||
<bone body="B0_13" bindpos="0 0 0" bindquat="1 0 0 0" vertid="13 29" vertweight="1 1"/>
|
||||
<bone body="B0_14" bindpos="0 0 0" bindquat="1 0 0 0" vertid="14 30" vertweight="1 1"/>
|
||||
<bone body="B0_15" bindpos="0 0 0" bindquat="1 0 0 0" vertid="15 31" vertweight="1 1"/>
|
||||
</skin>
|
||||
<skin name="B1Skin" group="4" rgba="0 1 1 1" inflate="0.1"
|
||||
vertex="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
|
||||
face="0 4 5 0 5 1 1 5 6 1 6 2 2 6 7 2 7 3 4 8 9 4 9 5 5 9 10 5 10 6 6 10 11 6 11 7 8 12 13 8 13 9 9 13 14 9 14 10 10 14 15 10 15 11 16 21 20 16 17 21 17 22 21 17 18 22 18 23 22 18 19 23 20 25 24 20 21 25 21 26 25 21 22 26 22 27 26 22 23 27 24 29 28 24 25 29 25 30 29 25 26 30 26 31 30 26 27 31 0 20 4 0 16 20 4 24 8 4 20 24 8 28 12 8 24 28 3 7 23 3 23 19 7 11 27 7 27 23 11 15 31 11 31 27 0 1 17 0 17 16 1 2 18 1 18 17 2 3 19 2 19 18 12 29 13 12 28 29 13 30 14 13 29 30 14 31 15 14 30 31">
|
||||
<bone body="B1_0" bindpos="0 0 0" bindquat="1 0 0 0" vertid="0 16" vertweight="1 1"/>
|
||||
<bone body="B1_1" bindpos="0 0 0" bindquat="1 0 0 0" vertid="1 17" vertweight="1 1"/>
|
||||
<bone body="B1_2" bindpos="0 0 0" bindquat="1 0 0 0" vertid="2 18" vertweight="1 1"/>
|
||||
<bone body="B1_3" bindpos="0 0 0" bindquat="1 0 0 0" vertid="3 19" vertweight="1 1"/>
|
||||
<bone body="B1_4" bindpos="0 0 0" bindquat="1 0 0 0" vertid="4 20" vertweight="1 1"/>
|
||||
<bone body="B1_5" bindpos="0 0 0" bindquat="1 0 0 0" vertid="5 21" vertweight="1 1"/>
|
||||
<bone body="B1_6" bindpos="0 0 0" bindquat="1 0 0 0" vertid="6 22" vertweight="1 1"/>
|
||||
<bone body="B1_7" bindpos="0 0 0" bindquat="1 0 0 0" vertid="7 23" vertweight="1 1"/>
|
||||
<bone body="B1_8" bindpos="0 0 0" bindquat="1 0 0 0" vertid="8 24" vertweight="1 1"/>
|
||||
<bone body="B1_9" bindpos="0 0 0" bindquat="1 0 0 0" vertid="9 25" vertweight="1 1"/>
|
||||
<bone body="B1_10" bindpos="0 0 0" bindquat="1 0 0 0" vertid="10 26" vertweight="1 1"/>
|
||||
<bone body="B1_11" bindpos="0 0 0" bindquat="1 0 0 0" vertid="11 27" vertweight="1 1"/>
|
||||
<bone body="B1_12" bindpos="0 0 0" bindquat="1 0 0 0" vertid="12 28" vertweight="1 1"/>
|
||||
<bone body="B1_13" bindpos="0 0 0" bindquat="1 0 0 0" vertid="13 29" vertweight="1 1"/>
|
||||
<bone body="B1_14" bindpos="0 0 0" bindquat="1 0 0 0" vertid="14 30" vertweight="1 1"/>
|
||||
<bone body="B1_15" bindpos="0 0 0" bindquat="1 0 0 0" vertid="15 31" vertweight="1 1"/>
|
||||
</skin>
|
||||
</deformable>
|
||||
</mujoco>
|
||||
|
||||
@@ -37,32 +37,11 @@ using UserCompositeTest = MujocoTest;
|
||||
|
||||
// ------------- test automatic inference of nuser_xxx -------------------------
|
||||
|
||||
TEST_F(UserCompositeTest, MultipleJointsNotAllowedUnlessParticle) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body>
|
||||
<freejoint/>
|
||||
<composite type="grid" count="7 7 1" spacing="0.04">
|
||||
<joint kind="main" solreffix="0.03 1" solimpfix="0 .1 .01"/>
|
||||
<joint kind="main" solreffix="0.03 1" solimpfix="0 .1 .01"/>
|
||||
</composite>
|
||||
</body>
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* m = LoadModelFromString(xml, error.data(), error.size());
|
||||
EXPECT_THAT(m, IsNull());
|
||||
EXPECT_THAT(error.data(),
|
||||
HasSubstr("Only particles are allowed to have multiple joints"));
|
||||
}
|
||||
|
||||
TEST_F(UserCompositeTest, SpacingGreaterThanGeometry) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<composite type="grid" count="282 2">
|
||||
<composite type="particle" count="282 2">
|
||||
<geom size="8"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
@@ -79,7 +58,7 @@ TEST_F(UserCompositeTest, SpacingEqualToGeometry) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<composite type="grid" count="282 2" spacing="8">
|
||||
<composite type="particle" count="282 2" spacing="8">
|
||||
<geom size="8"/>
|
||||
</composite>
|
||||
</worldbody>
|
||||
|
||||
@@ -1809,29 +1809,85 @@ TEST_F(XMLReaderTest, ReadsSkinGroups) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<body>
|
||||
<composite prefix="B0" type="grid" count="4 4 1" spacing=".2">
|
||||
<geom size=".1" group="2"/>
|
||||
<skin group="4"/>
|
||||
</composite>
|
||||
<body pos="1 -1 .6" name="B0_parent">
|
||||
<flexcomp name="B0" type="grid" count="4 4 1" spacing=".2 .2 .2" group="2" radius=".1" dim="2">
|
||||
<edge equality="true"/>
|
||||
<contact internal="false" selfcollide="none"/>
|
||||
</flexcomp>
|
||||
</body>
|
||||
<body>
|
||||
<composite prefix="B1" type="grid" count="4 4 1" spacing=".2">
|
||||
<geom size=".1" group="4"/>
|
||||
<skin group="2"/>
|
||||
</composite>
|
||||
<body pos="-1 1 .6" name="B1_parent">
|
||||
<flexcomp name="B1" type="grid" count="4 4 1" spacing=".2 .2 .2" group="4" radius=".1" dim="2">
|
||||
<edge equality="true"/>
|
||||
<contact internal="false" selfcollide="none"/>
|
||||
</flexcomp>
|
||||
</body>
|
||||
</worldbody>
|
||||
<deformable>
|
||||
<skin name="B0Skin" group="4" rgba="1 1 0 1" inflate="0.1"
|
||||
vertex="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
|
||||
face="0 4 5 0 5 1 1 5 6 1 6 2 2 6 7 2 7 3 4 8 9 4 9 5 5 9 10 5 10 6 6 10 11 6 11 7 8
|
||||
12 13 8 13 9 9 13 14 9 14 10 10 14 15 10 15 11 16 21 20 16 17 21 17 22 21 17 18
|
||||
22 18 23 22 18 19 23 20 25 24 20 21 25 21 26 25 21 22 26 22 27 26 22 23 27 24 29
|
||||
28 24 25 29 25 30 29 25 26 30 26 31 30 26 27 31 0 20 4 0 16 20 4 24 8 4 20 24 8
|
||||
28 12 8 24 28 3 7 23 3 23 19 7 11 27 7 27 23 11 15 31 11 31 27 0 1 17 0 17 16 1
|
||||
2 18 1 18 17 2 3 19 2 19 18 12 29 13 12 28 29 13 30 14 13 29 30 14 31 15 14 30 31">
|
||||
<bone body="B0_0" bindpos="0 0 0" bindquat="1 0 0 0" vertid="0 16" vertweight="1 1"/>
|
||||
<bone body="B0_1" bindpos="0 0 0" bindquat="1 0 0 0" vertid="1 17" vertweight="1 1"/>
|
||||
<bone body="B0_2" bindpos="0 0 0" bindquat="1 0 0 0" vertid="2 18" vertweight="1 1"/>
|
||||
<bone body="B0_3" bindpos="0 0 0" bindquat="1 0 0 0" vertid="3 19" vertweight="1 1"/>
|
||||
<bone body="B0_4" bindpos="0 0 0" bindquat="1 0 0 0" vertid="4 20" vertweight="1 1"/>
|
||||
<bone body="B0_5" bindpos="0 0 0" bindquat="1 0 0 0" vertid="5 21" vertweight="1 1"/>
|
||||
<bone body="B0_6" bindpos="0 0 0" bindquat="1 0 0 0" vertid="6 22" vertweight="1 1"/>
|
||||
<bone body="B0_7" bindpos="0 0 0" bindquat="1 0 0 0" vertid="7 23" vertweight="1 1"/>
|
||||
<bone body="B0_8" bindpos="0 0 0" bindquat="1 0 0 0" vertid="8 24" vertweight="1 1"/>
|
||||
<bone body="B0_9" bindpos="0 0 0" bindquat="1 0 0 0" vertid="9 25" vertweight="1 1"/>
|
||||
<bone body="B0_10" bindpos="0 0 0" bindquat="1 0 0 0" vertid="10 26" vertweight="1 1"/>
|
||||
<bone body="B0_11" bindpos="0 0 0" bindquat="1 0 0 0" vertid="11 27" vertweight="1 1"/>
|
||||
<bone body="B0_12" bindpos="0 0 0" bindquat="1 0 0 0" vertid="12 28" vertweight="1 1"/>
|
||||
<bone body="B0_13" bindpos="0 0 0" bindquat="1 0 0 0" vertid="13 29" vertweight="1 1"/>
|
||||
<bone body="B0_14" bindpos="0 0 0" bindquat="1 0 0 0" vertid="14 30" vertweight="1 1"/>
|
||||
<bone body="B0_15" bindpos="0 0 0" bindquat="1 0 0 0" vertid="15 31" vertweight="1 1"/>
|
||||
</skin>
|
||||
<skin name="B1Skin" group="2" rgba="0 1 1 1" inflate="0.1"
|
||||
vertex="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
|
||||
face="0 4 5 0 5 1 1 5 6 1 6 2 2 6 7 2 7 3 4 8 9 4 9 5 5 9 10 5 10 6 6 10 11 6 11 7 8
|
||||
12 13 8 13 9 9 13 14 9 14 10 10 14 15 10 15 11 16 21 20 16 17 21 17 22 21 17 18
|
||||
22 18 23 22 18 19 23 20 25 24 20 21 25 21 26 25 21 22 26 22 27 26 22 23 27 24 29
|
||||
28 24 25 29 25 30 29 25 26 30 26 31 30 26 27 31 0 20 4 0 16 20 4 24 8 4 20 24 8
|
||||
28 12 8 24 28 3 7 23 3 23 19 7 11 27 7 27 23 11 15 31 11 31 27 0 1 17 0 17 16 1
|
||||
2 18 1 18 17 2 3 19 2 19 18 12 29 13 12 28 29 13 30 14 13 29 30 14 31 15 14 30 31">
|
||||
<bone body="B1_0" bindpos="0 0 0" bindquat="1 0 0 0" vertid="0 16" vertweight="1 1"/>
|
||||
<bone body="B1_1" bindpos="0 0 0" bindquat="1 0 0 0" vertid="1 17" vertweight="1 1"/>
|
||||
<bone body="B1_2" bindpos="0 0 0" bindquat="1 0 0 0" vertid="2 18" vertweight="1 1"/>
|
||||
<bone body="B1_3" bindpos="0 0 0" bindquat="1 0 0 0" vertid="3 19" vertweight="1 1"/>
|
||||
<bone body="B1_4" bindpos="0 0 0" bindquat="1 0 0 0" vertid="4 20" vertweight="1 1"/>
|
||||
<bone body="B1_5" bindpos="0 0 0" bindquat="1 0 0 0" vertid="5 21" vertweight="1 1"/>
|
||||
<bone body="B1_6" bindpos="0 0 0" bindquat="1 0 0 0" vertid="6 22" vertweight="1 1"/>
|
||||
<bone body="B1_7" bindpos="0 0 0" bindquat="1 0 0 0" vertid="7 23" vertweight="1 1"/>
|
||||
<bone body="B1_8" bindpos="0 0 0" bindquat="1 0 0 0" vertid="8 24" vertweight="1 1"/>
|
||||
<bone body="B1_9" bindpos="0 0 0" bindquat="1 0 0 0" vertid="9 25" vertweight="1 1"/>
|
||||
<bone body="B1_10" bindpos="0 0 0" bindquat="1 0 0 0" vertid="10 26" vertweight="1 1"/>
|
||||
<bone body="B1_11" bindpos="0 0 0" bindquat="1 0 0 0" vertid="11 27" vertweight="1 1"/>
|
||||
<bone body="B1_12" bindpos="0 0 0" bindquat="1 0 0 0" vertid="12 28" vertweight="1 1"/>
|
||||
<bone body="B1_13" bindpos="0 0 0" bindquat="1 0 0 0" vertid="13 29" vertweight="1 1"/>
|
||||
<bone body="B1_14" bindpos="0 0 0" bindquat="1 0 0 0" vertid="14 30" vertweight="1 1"/>
|
||||
<bone body="B1_15" bindpos="0 0 0" bindquat="1 0 0 0" vertid="15 31" vertweight="1 1"/>
|
||||
</skin>
|
||||
</deformable>
|
||||
</mujoco>
|
||||
)";
|
||||
std::array<char, 1024> error;
|
||||
mjModel* model = LoadModelFromString(xml, error.data(), error.size());
|
||||
ASSERT_THAT(model, NotNull());
|
||||
int geomid1 = mj_name2id(model, mjOBJ_GEOM, "B0G0_0");
|
||||
int geomid2 = mj_name2id(model, mjOBJ_GEOM, "B1G0_0");
|
||||
EXPECT_THAT(model->geom_group[geomid1], 2);
|
||||
int flexid1 = mj_name2id(model, mjOBJ_FLEX, "B0");
|
||||
int flexid2 = mj_name2id(model, mjOBJ_FLEX, "B1");
|
||||
EXPECT_THAT(model->flex_group[flexid1], 2);
|
||||
EXPECT_THAT(model->skin_group[0], 4);
|
||||
EXPECT_THAT(model->geom_group[geomid2], 4);
|
||||
EXPECT_THAT(model->flex_group[flexid2], 4);
|
||||
EXPECT_THAT(model->skin_group[1], 2);
|
||||
mj_deleteModel(model);
|
||||
}
|
||||
|
||||
@@ -914,13 +914,42 @@ TEST_F(XMLWriterTest, WritesSkin) {
|
||||
static constexpr char xml[] = R"(
|
||||
<mujoco>
|
||||
<worldbody>
|
||||
<composite type="grid" count="2 2 1" spacing="0.05">
|
||||
<skin texcoord="true"/>
|
||||
<geom size=".01"/>
|
||||
</composite>
|
||||
<body pos="1 -1 .6" name="B0_parent">
|
||||
<flexcomp name="B0" type="grid" count="4 4 1" spacing=".2 .2 .2" radius=".1" dim="2"/>
|
||||
</body>
|
||||
</worldbody>
|
||||
<deformable>
|
||||
<skin name="B0Skin" rgba="1 1 0 1" inflate="0.1"
|
||||
vertex="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
|
||||
face="0 4 5 0 5 1 1 5 6 1 6 2 2 6 7 2 7 3 4 8 9 4 9 5 5 9 10 5 10 6 6 10 11 6 11 7 8
|
||||
12 13 8 13 9 9 13 14 9 14 10 10 14 15 10 15 11 16 21 20 16 17 21 17 22 21 17 18
|
||||
22 18 23 22 18 19 23 20 25 24 20 21 25 21 26 25 21 22 26 22 27 26 22 23 27 24 29
|
||||
28 24 25 29 25 30 29 25 26 30 26 31 30 26 27 31 0 20 4 0 16 20 4 24 8 4 20 24 8
|
||||
28 12 8 24 28 3 7 23 3 23 19 7 11 27 7 27 23 11 15 31 11 31 27 0 1 17 0 17 16 1
|
||||
2 18 1 18 17 2 3 19 2 19 18 12 29 13 12 28 29 13 30 14 13 29 30 14 31 15 14 30 31">
|
||||
<bone body="B0_0" bindpos="0 0 0" bindquat="1 0 0 0" vertid="0 16" vertweight="1 1"/>
|
||||
<bone body="B0_1" bindpos="0 0 0" bindquat="1 0 0 0" vertid="1 17" vertweight="1 1"/>
|
||||
<bone body="B0_2" bindpos="0 0 0" bindquat="1 0 0 0" vertid="2 18" vertweight="1 1"/>
|
||||
<bone body="B0_3" bindpos="0 0 0" bindquat="1 0 0 0" vertid="3 19" vertweight="1 1"/>
|
||||
<bone body="B0_4" bindpos="0 0 0" bindquat="1 0 0 0" vertid="4 20" vertweight="1 1"/>
|
||||
<bone body="B0_5" bindpos="0 0 0" bindquat="1 0 0 0" vertid="5 21" vertweight="1 1"/>
|
||||
<bone body="B0_6" bindpos="0 0 0" bindquat="1 0 0 0" vertid="6 22" vertweight="1 1"/>
|
||||
<bone body="B0_7" bindpos="0 0 0" bindquat="1 0 0 0" vertid="7 23" vertweight="1 1"/>
|
||||
<bone body="B0_8" bindpos="0 0 0" bindquat="1 0 0 0" vertid="8 24" vertweight="1 1"/>
|
||||
<bone body="B0_9" bindpos="0 0 0" bindquat="1 0 0 0" vertid="9 25" vertweight="1 1"/>
|
||||
<bone body="B0_10" bindpos="0 0 0" bindquat="1 0 0 0" vertid="10 26" vertweight="1 1"/>
|
||||
<bone body="B0_11" bindpos="0 0 0" bindquat="1 0 0 0" vertid="11 27" vertweight="1 1"/>
|
||||
<bone body="B0_12" bindpos="0 0 0" bindquat="1 0 0 0" vertid="12 28" vertweight="1 1"/>
|
||||
<bone body="B0_13" bindpos="0 0 0" bindquat="1 0 0 0" vertid="13 29" vertweight="1 1"/>
|
||||
<bone body="B0_14" bindpos="0 0 0" bindquat="1 0 0 0" vertid="14 30" vertweight="1 1"/>
|
||||
<bone body="B0_15" bindpos="0 0 0" bindquat="1 0 0 0" vertid="15 31" vertweight="1 1"/>
|
||||
</skin>
|
||||
</deformable>
|
||||
</mujoco>
|
||||
)";
|
||||
|
||||
mjModel* model = LoadModelFromString(xml);
|
||||
ASSERT_THAT(model, NotNull());
|
||||
EXPECT_THAT(model->nskin, 1);
|
||||
|
||||
Reference in New Issue
Block a user