Files
Mujoco_WASM/model/flex/drape.xml
T
Alessio 2a3554c8a3 Integrate passive flex contact implicitly
Contact of a flex with `passive` collisions enabled was applied as an
explicit spring of fixed stiffness 1e4, which the timestep bounds: any
stiffness worth having oscillates faster than the step can resolve, so
the force was too soft to keep sheets apart and interpenetration was
routine.

Carry its curvature in the effective metric M + K instead, alongside the
flex's own stretch and bending stiffness. The contact block k*J^T*J is
appended to the per-vertex candidate list already assembled for the flex
stencils, so it costs additional entries in an existing matrix rather
than a new one, and the accompanying shift -h*K*v is what damps the
stiff modes. At a 2 ms timestep this holds roughly 50x the stiffness an
explicit force of the same step could.

With the timestep no longer setting the bound, the stiffness is chosen
as a natural frequency scaled by the participating vertex mass rather
than left at a fixed 1e4, so one value suits models of any scale.

Passive handling is scoped to contacts whose every dof is a flex vertex
carried by the metric: flex against flex, flex against itself, and flex
against static geometry, which contributes no dofs of its own. For those
the Hessian is assembled in full. Contact with a body that can move
would have that body's dofs dropped from it, and is left on the
constraint solver.

The feature now requires an integrator whose constraint solve runs in
that metric, and is rejected with an error otherwise.

Add model/flex/drape.xml as the example model, replacing sphere_passive,
whose contacts no longer demonstrated the feature.
2026-08-06 15:38:05 +01:00

53 lines
2.6 KiB
XML

<!-- Copyright 2026 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="Drape">
<include file="scene.xml"/>
<!-- Three cloths dropped over a sphere. Every contact here is handled by the passive path: cloth
against cloth, each cloth against itself, and cloth against the sphere, which is static and
so contributes no dofs of its own. Their stiffness is carried implicitly by the effective
metric, which is why the sheets rest on each other without interpenetrating. -->
<!-- The metric solve for qacc_smooth is iterative and its blocks do not see the vertex-to-vertex
coupling that contact introduces, so a contact-rich scene like this one needs a larger
iteration budget than the default to converge it. -->
<option timestep="0.002" solver="CG" tolerance="1e-6" iterations="400" integrator="implicitfast"/>
<size memory="50M"/>
<worldbody>
<geom name="ball" type="sphere" size=".3" pos="0 0 .3" rgba=".45 .45 .5 1"/>
<flexcomp type="grid" count="13 13 1" spacing=".055 .055 .055" pos="0 0 .68"
radius=".004" mass=".25" name="cloth1" dim="2" rgba=".85 .35 .25 1">
<contact selfcollide="auto" passive="true" solref="0.01 1" solimp=".95 .99 .0001"/>
<elasticity young="2e4" poisson=".2" thickness="1e-3" elastic2d="both" damping="1e-4"/>
</flexcomp>
<flexcomp type="grid" count="13 13 1" spacing=".055 .055 .055" pos=".06 -.04 .78"
radius=".004" mass=".25" name="cloth2" dim="2" rgba=".25 .55 .8 1">
<contact selfcollide="auto" passive="true" solref="0.01 1" solimp=".95 .99 .0001"/>
<elasticity young="2e4" poisson=".2" thickness="1e-3" elastic2d="both" damping="1e-4"/>
</flexcomp>
<flexcomp type="grid" count="13 13 1" spacing=".055 .055 .055" pos="-.05 .05 .88"
radius=".004" mass=".25" name="cloth3" dim="2" rgba=".95 .8 .3 1">
<contact selfcollide="auto" passive="true" solref="0.01 1" solimp=".95 .99 .0001"/>
<elasticity young="2e4" poisson=".2" thickness="1e-3" elastic2d="both" damping="1e-4"/>
</flexcomp>
</worldbody>
</mujoco>