Update Solid and Shell plugins to use FlexComp.
PiperOrigin-RevId: 573755821 Change-Id: I3b8d7fb27f0e940038fa9fd2b26ecc746df4f7ac
This commit is contained in:
committed by
Copybara-Service
parent
93d1c3c92e
commit
110ade1435
+16
-1
@@ -3765,7 +3765,7 @@ Associate this composite with an :ref:`engine plugin<exPlugin>`. Either :at:`plu
|
|||||||
|
|
||||||
.. _body-flexcomp-euler:
|
.. _body-flexcomp-euler:
|
||||||
|
|
||||||
.. _body-flexcomp-selfcollide:
|
.. _body-flexcomp-group:
|
||||||
|
|
||||||
.. _body-flexcomp-flatskin:
|
.. _body-flexcomp-flatskin:
|
||||||
|
|
||||||
@@ -3820,6 +3820,15 @@ Associate this composite with an :ref:`engine plugin<exPlugin>`. Either :at:`plu
|
|||||||
.. _flex-contact-gap:
|
.. _flex-contact-gap:
|
||||||
.. _flexcomp-contact-gap:
|
.. _flexcomp-contact-gap:
|
||||||
|
|
||||||
|
.. _flex-contact-internal:
|
||||||
|
.. _flexcomp-contact-internal:
|
||||||
|
|
||||||
|
.. _flex-contact-selfcollide:
|
||||||
|
.. _flexcomp-contact-selfcollide:
|
||||||
|
|
||||||
|
.. _flex-contact-activelayers:
|
||||||
|
.. _flexcomp-contact-activelayers:
|
||||||
|
|
||||||
.. _flexcomp-pin:
|
.. _flexcomp-pin:
|
||||||
|
|
||||||
.. _flexcomp-pin-id:
|
.. _flexcomp-pin-id:
|
||||||
@@ -3830,6 +3839,12 @@ Associate this composite with an :ref:`engine plugin<exPlugin>`. Either :at:`plu
|
|||||||
|
|
||||||
.. _flexcomp-pin-gridrange:
|
.. _flexcomp-pin-gridrange:
|
||||||
|
|
||||||
|
.. _flexcomp-plugin:
|
||||||
|
|
||||||
|
.. _flexcomp-plugin-plugin:
|
||||||
|
|
||||||
|
.. _flexcomp-plugin-instance:
|
||||||
|
|
||||||
|
|
||||||
.. _deformable:
|
.. _deformable:
|
||||||
|
|
||||||
|
|||||||
+27
-9
@@ -485,19 +485,19 @@
|
|||||||
| :ref:`flexcomp | \* | :class: mjcf-attributes |
|
| :ref:`flexcomp | \* | :class: mjcf-attributes |
|
||||||
| <body-flexcomp>` | | |
|
| <body-flexcomp>` | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`name<body-flexcomp-name>` | :ref:`class<body-flexcomp-class>` | :ref:`type<body-flexcomp-type>` | :ref:`dim<body-flexcomp-dim>` | |
|
| | | | :ref:`name<body-flexcomp-name>` | :ref:`class<body-flexcomp-class>` | :ref:`type<body-flexcomp-type>` | :ref:`group<body-flexcomp-group>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`flatskin<body-flexcomp-flatskin>` | :ref:`count<body-flexcomp-count>` | :ref:`spacing<body-flexcomp-spacing>` | :ref:`radius<body-flexcomp-radius>` | |
|
| | | | :ref:`dim<body-flexcomp-dim>` | :ref:`count<body-flexcomp-count>` | :ref:`spacing<body-flexcomp-spacing>` | :ref:`radius<body-flexcomp-radius>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`rigid<body-flexcomp-rigid>` | :ref:`mass<body-flexcomp-mass>` | :ref:`inertiabox<body-flexcomp-inertiabox>` | :ref:`scale<body-flexcomp-scale>` | |
|
| | | | :ref:`rigid<body-flexcomp-rigid>` | :ref:`mass<body-flexcomp-mass>` | :ref:`inertiabox<body-flexcomp-inertiabox>` | :ref:`scale<body-flexcomp-scale>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`file<body-flexcomp-file>` | :ref:`point<body-flexcomp-point>` | :ref:`element<body-flexcomp-element>` | :ref:`texcoord<body-flexcomp-texcoord>` | |
|
| | | | :ref:`file<body-flexcomp-file>` | :ref:`point<body-flexcomp-point>` | :ref:`element<body-flexcomp-element>` | :ref:`texcoord<body-flexcomp-texcoord>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`material<body-flexcomp-material>` | :ref:`rgba<body-flexcomp-rgba>` | :ref:`selfcollide<body-flexcomp-selfcollide>` | :ref:`flatskin<body-flexcomp-flatskin>` | |
|
| | | | :ref:`material<body-flexcomp-material>` | :ref:`rgba<body-flexcomp-rgba>` | :ref:`flatskin<body-flexcomp-flatskin>` | :ref:`pos<body-flexcomp-pos>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`pos<body-flexcomp-pos>` | :ref:`quat<body-flexcomp-quat>` | :ref:`axisangle<body-flexcomp-axisangle>` | :ref:`xyaxes<body-flexcomp-xyaxes>` | |
|
| | | | :ref:`quat<body-flexcomp-quat>` | :ref:`axisangle<body-flexcomp-axisangle>` | :ref:`xyaxes<body-flexcomp-xyaxes>` | :ref:`zaxis<body-flexcomp-zaxis>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`zaxis<body-flexcomp-zaxis>` | :ref:`euler<body-flexcomp-euler>` | | | |
|
| | | | :ref:`euler<body-flexcomp-euler>` | | | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
|
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
|
||||||
@@ -517,7 +517,9 @@
|
|||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`friction<flexcomp-contact-friction>` | :ref:`solmix<flexcomp-contact-solmix>` | :ref:`solref<flexcomp-contact-solref>` | :ref:`solimp<flexcomp-contact-solimp>` | |
|
| | | | :ref:`friction<flexcomp-contact-friction>` | :ref:`solmix<flexcomp-contact-solmix>` | :ref:`solref<flexcomp-contact-solref>` | :ref:`solimp<flexcomp-contact-solimp>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`margin<flexcomp-contact-margin>` | :ref:`gap<flexcomp-contact-gap>` | | | |
|
| | | | :ref:`margin<flexcomp-contact-margin>` | :ref:`gap<flexcomp-contact-gap>` | :ref:`internal<flexcomp-contact-internal>` | :ref:`selfcollide<flexcomp-contact-selfcollide>` | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
| | | | :ref:`activelayers<flexcomp-contact-activelayers>` | | | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
|
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
|
||||||
@@ -527,6 +529,20 @@
|
|||||||
| | | | :ref:`id<flexcomp-pin-id>` | :ref:`range<flexcomp-pin-range>` | :ref:`grid<flexcomp-pin-grid>` | :ref:`gridrange<flexcomp-pin-gridrange>` | |
|
| | | | :ref:`id<flexcomp-pin-id>` | :ref:`range<flexcomp-pin-range>` | :ref:`grid<flexcomp-pin-grid>` | :ref:`gridrange<flexcomp-pin-gridrange>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
|
||||||
|
| :ref:`plugin | \* | :class: mjcf-attributes |
|
||||||
|
| <flexcomp-plugin>` | | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
| | | | :ref:`plugin<flexcomp-plugin-plugin>` | :ref:`instance<flexcomp-plugin-instance>` | | | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
| |_3| plugin |br| |_3| |L| | | .. table:: |
|
||||||
|
| :ref:`config | \* | :class: mjcf-attributes |
|
||||||
|
| <plugin-config>` | | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
| | | | :ref:`key<plugin-config-key>` | :ref:`value<plugin-config-value>` | | | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| mujoco |br| |L| | | *no attributes* |
|
| mujoco |br| |L| | | *no attributes* |
|
||||||
| :ref:`deformable<deformable>` | | |
|
| :ref:`deformable<deformable>` | | |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
@@ -536,9 +552,9 @@
|
|||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`name<deformable-flex-name>` | :ref:`group<deformable-flex-group>` | :ref:`dim<deformable-flex-dim>` | :ref:`radius<deformable-flex-radius>` | |
|
| | | | :ref:`name<deformable-flex-name>` | :ref:`group<deformable-flex-group>` | :ref:`dim<deformable-flex-dim>` | :ref:`radius<deformable-flex-radius>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`material<deformable-flex-material>` | :ref:`rgba<deformable-flex-rgba>` | :ref:`flatskin<deformable-flex-flatskin>` | :ref:`selfcollide<deformable-flex-selfcollide>` | |
|
| | | | :ref:`material<deformable-flex-material>` | :ref:`rgba<deformable-flex-rgba>` | :ref:`flatskin<deformable-flex-flatskin>` | :ref:`body<deformable-flex-body>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`body<deformable-flex-body>` | :ref:`vertex<deformable-flex-vertex>` | :ref:`element<deformable-flex-element>` | :ref:`texcoord<deformable-flex-texcoord>` | |
|
| | | | :ref:`vertex<deformable-flex-vertex>` | :ref:`element<deformable-flex-element>` | :ref:`texcoord<deformable-flex-texcoord>` | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_2| flex |br| |_2| |L| | | .. table:: |
|
| |_2| flex |br| |_2| |L| | | .. table:: |
|
||||||
@@ -549,7 +565,9 @@
|
|||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`friction<flex-contact-friction>` | :ref:`solmix<flex-contact-solmix>` | :ref:`solref<flex-contact-solref>` | :ref:`solimp<flex-contact-solimp>` | |
|
| | | | :ref:`friction<flex-contact-friction>` | :ref:`solmix<flex-contact-solmix>` | :ref:`solref<flex-contact-solref>` | :ref:`solimp<flex-contact-solimp>` | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
| | | | :ref:`margin<flex-contact-margin>` | :ref:`gap<flex-contact-gap>` | | | |
|
| | | | :ref:`margin<flex-contact-margin>` | :ref:`gap<flex-contact-gap>` | :ref:`internal<flex-contact-internal>` | :ref:`selfcollide<flex-contact-selfcollide>` | |
|
||||||
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
|
| | | | :ref:`activelayers<flex-contact-activelayers>` | | | | |
|
||||||
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
|
||||||
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |_2| flex |br| |_2| |L| | | .. table:: |
|
| |_2| flex |br| |_2| |L| | | .. table:: |
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
<geom type="ellipsoid" size="0.025 0.01 0.025" rgba=".8 .2 .1 1" group="4"/>
|
<geom type="ellipsoid" size="0.025 0.01 0.025" rgba=".8 .2 .1 1" group="4"/>
|
||||||
<plugin plugin="mujoco.elasticity.shell">
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
<config key="poisson" value="0"/>
|
<config key="poisson" value="0"/>
|
||||||
<config key="damping" value="0.001"/>
|
|
||||||
<config key="thickness" value="1e-2"/>
|
<config key="thickness" value="1e-2"/>
|
||||||
<!--Units are in Pa (SI)-->
|
<!--Units are in Pa (SI)-->
|
||||||
<config key="young" value="3e6"/>
|
<config key="young" value="3e6"/>
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<!-- 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="Flag">
|
||||||
|
<!-- Degree of Freedom (nv): 340
|
||||||
|
Tendons (ntendon): 288
|
||||||
|
Actuators (nu): 0
|
||||||
|
Constraints (nefc): 0
|
||||||
|
This model of a flag passively flapping in the wind has no constraints and is designed to
|
||||||
|
exert smooth dynamics computations.
|
||||||
|
-->
|
||||||
|
<statistic center=".4 0 .8" extent="1.3"/>
|
||||||
|
|
||||||
|
<option wind="5 5 0" density="10" solver="CG" tolerance="1e-6">
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.elasticity.shell"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<geom name="floor" type="plane" size="0 0 .1"/>
|
||||||
|
<light diffuse=".6 .6 .6" specular="0.2 0.2 0.2" pos="0 0 4" dir="0 0 -1"/>
|
||||||
|
<body name="pin" pos="0 0 1.5">
|
||||||
|
<flexcomp type="grid" count="9 19 1" spacing=".05 .05 .05" mass="10"
|
||||||
|
name="flag" radius="0.001">
|
||||||
|
<edge equality="true" damping="0.001"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
|
<config key="poisson" value="0"/>
|
||||||
|
<config key="thickness" value="1e-2"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="3e6"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
|
||||||
|
<equality>
|
||||||
|
<connect body1="flag_0" anchor="0 0 0"/>
|
||||||
|
</equality>
|
||||||
|
</mujoco>
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<!-- 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="Floppy">
|
||||||
|
<include file="scene.xml"/>
|
||||||
|
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<compiler autolimits="true"/>
|
||||||
|
|
||||||
|
<option solver="CG" tolerance="1e-6" timestep=".001" integrator="implicitfast"/>
|
||||||
|
|
||||||
|
<size memory="100M"/>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map stiffness="100"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<flexcomp type="grid" count="24 4 4" spacing=".1 .1 .1" pos=".1 0 1.5"
|
||||||
|
radius=".0" rgba="0 .7 .7 1" name="softbody" dim="3" mass="7">
|
||||||
|
<contact condim="3" solref="0.01 1" solimp=".95 .99 .0001" selfcollide="none"/>
|
||||||
|
<edge damping="1"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid">
|
||||||
|
<config key="poisson" value="0.2"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="5e4"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<joint name="hinge" pos="0 0 .5" axis="0 1 0" damping="50"/>
|
||||||
|
<geom type="cylinder" size=".4" fromto="0 -.5 .5 0 .5 .5" density="300"/>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
|
||||||
|
<actuator>
|
||||||
|
<motor name="cylinder" joint="hinge" gear="1 0 0 0 0 0" ctrlrange="-100 100"/>
|
||||||
|
</actuator>
|
||||||
|
</mujoco>
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<!-- 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="Jelly">
|
||||||
|
<include file="scene.xml"/>
|
||||||
|
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<option solver="CG" tolerance="1e-6" timestep=".001" integrator="implicitfast"/>
|
||||||
|
|
||||||
|
<size memory="10M"/>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map stiffness="100"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<default class="wall">
|
||||||
|
<geom type="plane" size=".5 .5 .05"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1">
|
||||||
|
<geom type="capsule" size=".1 .1" group="1" condim="1"/>
|
||||||
|
</body>
|
||||||
|
<geom name="+x" class="wall" zaxis="1 0 0" pos="-.5 0 -.25"/>
|
||||||
|
<geom name="-x" class="wall" zaxis="-1 0 0" pos=".5 0 -.25"/>
|
||||||
|
<geom name="+y" class="wall" zaxis="0 1 0" pos="0 -.5 -.25"/>
|
||||||
|
<geom name="-y" class="wall" zaxis="0 -1 0" pos="0 .5 -.25"/>
|
||||||
|
<flexcomp type="grid" count="8 8 8" spacing=".07 .07 .07" pos="0 0 1" dim="3"
|
||||||
|
radius=".005" rgba="0 .7 .7 1" mass="5" name="softbody">
|
||||||
|
<edge damping="1"/>
|
||||||
|
<contact selfcollide="none"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid">
|
||||||
|
<config key="poisson" value="0"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="5e4"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
<skin inflate="0.0001" rgba=".4 0 .3 1" subgrid="1"/>
|
<skin inflate="0.0001" rgba=".4 0 .3 1" subgrid="1"/>
|
||||||
<plugin plugin="mujoco.elasticity.shell">
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
<config key="poisson" value="0"/>
|
<config key="poisson" value="0"/>
|
||||||
<config key="damping" value="0.001"/>
|
|
||||||
<config key="thickness" value="1e-2"/>
|
<config key="thickness" value="1e-2"/>
|
||||||
<!--Units are in Pa (SI)-->
|
<!--Units are in Pa (SI)-->
|
||||||
<config key="young" value="3e7"/>
|
<config key="young" value="3e7"/>
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<!-- 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="Plate">
|
||||||
|
<include file="scene.xml"/>
|
||||||
|
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.elasticity.shell"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<option solver="CG" tolerance="1e-6" integrator="implicitfast"/>
|
||||||
|
|
||||||
|
<size memory="10M"/>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map stiffness="100"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<default class="wall">
|
||||||
|
<geom type="plane" size=".5 .5 .05"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<body mocap="true" pos="-.1 .05 0" zaxis=".5 0 1">
|
||||||
|
<geom type="capsule" size=".1 .1" group="1"/>
|
||||||
|
</body>
|
||||||
|
<flexcomp type="grid" count="16 16 1" spacing=".05 .05 .05" pos="0 0 1"
|
||||||
|
radius=".001" mass="100" name="plate">
|
||||||
|
<contact condim="3" solref="0.01 1" solimp=".95 .99 .0001"/>
|
||||||
|
<edge equality="true" damping="0.001"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
|
<config key="poisson" value="0"/>
|
||||||
|
<config key="thickness" value="1e-2"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="3e7"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
@@ -1407,7 +1407,6 @@
|
|||||||
<skin inflate="0.001" rgba=".4 0 .3 1"/>
|
<skin inflate="0.001" rgba=".4 0 .3 1"/>
|
||||||
<plugin plugin="mujoco.elasticity.shell">
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
<config key="poisson" value="0"/>
|
<config key="poisson" value="0"/>
|
||||||
<config key="damping" value="0.001"/>
|
|
||||||
<config key="thickness" value="8e-3"/>
|
<config key="thickness" value="8e-3"/>
|
||||||
<!--Units are in Pa (SI)-->
|
<!--Units are in Pa (SI)-->
|
||||||
<config key="young" value="3e7"/>
|
<config key="young" value="3e7"/>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
|||||||
|
<!-- 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="Press">
|
||||||
|
<include file="scene.xml"/>
|
||||||
|
|
||||||
|
<extension>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<compiler autolimits="true"/>
|
||||||
|
|
||||||
|
<option solver="Newton" tolerance="1e-6" timestep=".001" integrator="implicitfast"/>
|
||||||
|
|
||||||
|
<size memory="10M"/>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map stiffness="100"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<flexcomp name="A" type="grid" count="4 4 4" spacing=".2 .2 .2" pos="0 0 .5"
|
||||||
|
radius=".005" rgba="0 .7 .7 1" dim="3" mass="5">
|
||||||
|
<contact condim="3" solref="0.01 1" solimp=".95 .99 .0001" selfcollide="none"/>
|
||||||
|
<edge damping="1"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid">
|
||||||
|
<config key="poisson" value="0.4"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="1e4"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
|
||||||
|
<flexcomp name="B" type="grid" count="4 4 4" spacing=".2 .2 .2" pos="1 0 .5"
|
||||||
|
radius=".005" rgba="0 .7 .7 1" dim="3" mass="5">
|
||||||
|
<contact condim="3" solref="0.01 1" solimp=".95 .99 .0001" selfcollide="none"/>
|
||||||
|
<edge damping="1"/>
|
||||||
|
<plugin plugin="mujoco.elasticity.solid">
|
||||||
|
<config key="poisson" value="0"/>
|
||||||
|
<!--Units are in Pa (SI)-->
|
||||||
|
<config key="young" value="5e4"/>
|
||||||
|
</plugin>
|
||||||
|
</flexcomp>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<joint name="soft" type="slide" axis="0 0 1" damping="500"/>
|
||||||
|
<geom type="box" size=".35 .35 0.05" pos=".1 .1 1" density="300"/>
|
||||||
|
</body>
|
||||||
|
<body>
|
||||||
|
<joint name="stiff" type="slide" axis="0 0 1" damping="500"/>
|
||||||
|
<geom type="box" size=".35 .35 0.05" pos="1.1 .1 1" density="300"/>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
|
||||||
|
<actuator>
|
||||||
|
<motor name="soft" joint="soft" gear="-1 0 0 0 0 0" ctrlrange="-150 300"/>
|
||||||
|
<motor name="stiff" joint="stiff" gear="-1 0 0 0 0 0" ctrlrange="-150 1600"/>
|
||||||
|
</actuator>
|
||||||
|
</mujoco>
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
|
||||||
@@ -47,19 +46,4 @@ bool CheckAttr(const char* name, const mjModel* m, int instance) {
|
|||||||
return end == value.data() + value.size();
|
return end == value.data() + value.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
mjtNum SquaredDist3(const mjtNum pos1[3], const mjtNum pos2[3]) {
|
|
||||||
mjtNum dif[3] = {pos1[0]-pos2[0], pos1[1]-pos2[1], pos1[2]-pos2[2]};
|
|
||||||
return dif[0]*dif[0] + dif[1]*dif[1] + dif[2]*dif[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateSquaredLengths(std::vector<mjtNum>& len,
|
|
||||||
const std::vector<std::pair<int, int> >& edges,
|
|
||||||
const mjtNum* x) {
|
|
||||||
for (int e = 0; e < len.size(); e++) {
|
|
||||||
const mjtNum* p0 = x + 3*edges[e].first;
|
|
||||||
const mjtNum* p1 = x + 3*edges[e].second;
|
|
||||||
len[e] = SquaredDist3(p0, p1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mujoco::plugin::elasticity
|
} // namespace mujoco::plugin::elasticity
|
||||||
|
|||||||
@@ -31,20 +31,27 @@ struct PairHash
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline mjtNum SquaredDist3(const mjtNum pos1[3], const mjtNum pos2[3]) {
|
||||||
|
mjtNum dif[3] = {pos1[0]-pos2[0], pos1[1]-pos2[1], pos1[2]-pos2[2]};
|
||||||
|
return dif[0]*dif[0] + dif[1]*dif[1] + dif[2]*dif[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UpdateSquaredLengths(std::vector<mjtNum>& len,
|
||||||
|
const std::vector<std::pair<int, int> >& edges,
|
||||||
|
const mjtNum* x) {
|
||||||
|
for (int e = 0; e < len.size(); e++) {
|
||||||
|
const mjtNum* p0 = x + 3*edges[e].first;
|
||||||
|
const mjtNum* p1 = x + 3*edges[e].second;
|
||||||
|
len[e] = SquaredDist3(p0, p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// copied from mjXUtil
|
// copied from mjXUtil
|
||||||
void String2Vector(const std::string& txt, std::vector<int>& vec);
|
void String2Vector(const std::string& txt, std::vector<int>& vec);
|
||||||
|
|
||||||
// reads numeric attributes
|
// reads numeric attributes
|
||||||
bool CheckAttr(const char* name, const mjModel* m, int instance);
|
bool CheckAttr(const char* name, const mjModel* m, int instance);
|
||||||
|
|
||||||
// Cartesian distance between 3D vectors
|
|
||||||
mjtNum SquaredDist3(const mjtNum pos1[3], const mjtNum pos2[3]);
|
|
||||||
|
|
||||||
// updates square lengths of edges
|
|
||||||
void UpdateSquaredLengths(std::vector<mjtNum>& len,
|
|
||||||
const std::vector<std::pair<int, int> >& edges,
|
|
||||||
const mjtNum* x);
|
|
||||||
|
|
||||||
} // namespace mujoco::plugin::elasticity
|
} // namespace mujoco::plugin::elasticity
|
||||||
|
|
||||||
#endif // MUJOCO_PLUGIN_ELASTICITY_ELASTICITY_H_
|
#endif // MUJOCO_PLUGIN_ELASTICITY_ELASTICITY_H_
|
||||||
|
|||||||
+21
-55
@@ -13,13 +13,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <functional>
|
|
||||||
#include <sstream>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@@ -29,6 +26,7 @@
|
|||||||
#include <mujoco/mjplugin.h>
|
#include <mujoco/mjplugin.h>
|
||||||
#include <mujoco/mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
#include "elasticity.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -40,22 +38,6 @@ constexpr int kNumEdges = Stencil2D::kNumEdges;
|
|||||||
constexpr int kNumVerts = Stencil2D::kNumVerts;
|
constexpr int kNumVerts = Stencil2D::kNumVerts;
|
||||||
constexpr int edge[kNumEdges][2] = {{1, 2}, {2, 0}, {0, 1}};
|
constexpr int edge[kNumEdges][2] = {{1, 2}, {2, 0}, {0, 1}};
|
||||||
|
|
||||||
// copied from void mjXUtil
|
|
||||||
void String2Vector(const std::string& txt, std::vector<int>& vec) {
|
|
||||||
std::stringstream strm(txt);
|
|
||||||
vec.clear();
|
|
||||||
|
|
||||||
while (!strm.eof()) {
|
|
||||||
int num;
|
|
||||||
strm >> num;
|
|
||||||
if (strm.fail()) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
vec.push_back(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cotangent between two edges
|
// cotangent between two edges
|
||||||
mjtNum cot(mjtNum* x, int v0, int v1, int v2) {
|
mjtNum cot(mjtNum* x, int v0, int v1, int v2) {
|
||||||
mjtNum normal[3];
|
mjtNum normal[3];
|
||||||
@@ -82,28 +64,12 @@ mjtNum ComputeVolume(const mjtNum* x, const int v[kNumVerts]) {
|
|||||||
return mju_norm3(normal) / 2;
|
return mju_norm3(normal) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reads numeric attributes
|
|
||||||
bool CheckAttr(const char* name, const mjModel* m, int instance) {
|
|
||||||
char* end;
|
|
||||||
std::string value = mj_getPluginConfig(m, instance, name);
|
|
||||||
value.erase(std::remove_if(value.begin(), value.end(), isspace), value.end());
|
|
||||||
strtod(value.c_str(), &end);
|
|
||||||
return end == value.data() + value.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PairHash
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
std::size_t operator() (const std::pair<T1, T2>& pair) const {
|
|
||||||
return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// factory function
|
// factory function
|
||||||
std::optional<Shell> Shell::Create(const mjModel* m, mjData* d, int instance) {
|
std::optional<Shell> Shell::Create(const mjModel* m, mjData* d, int instance) {
|
||||||
if (CheckAttr("face", m, instance) &&
|
if (CheckAttr("face", m, instance) &&
|
||||||
|
CheckAttr("edge", m, instance) &&
|
||||||
CheckAttr("poisson", m, instance) &&
|
CheckAttr("poisson", m, instance) &&
|
||||||
CheckAttr("young", m, instance) &&
|
CheckAttr("young", m, instance) &&
|
||||||
CheckAttr("thickness", m, instance)) {
|
CheckAttr("thickness", m, instance)) {
|
||||||
@@ -111,11 +77,10 @@ std::optional<Shell> Shell::Create(const mjModel* m, mjData* d, int instance) {
|
|||||||
mjtNum E = strtod(mj_getPluginConfig(m, instance, "young"), nullptr);
|
mjtNum E = strtod(mj_getPluginConfig(m, instance, "young"), nullptr);
|
||||||
mjtNum thick =
|
mjtNum thick =
|
||||||
strtod(mj_getPluginConfig(m, instance, "thickness"), nullptr);
|
strtod(mj_getPluginConfig(m, instance, "thickness"), nullptr);
|
||||||
mjtNum damp =
|
std::vector<int> face, edge;
|
||||||
strtod(mj_getPluginConfig(m, instance, "damping"), nullptr);
|
|
||||||
std::vector<int> face;
|
|
||||||
String2Vector(mj_getPluginConfig(m, instance, "face"), face);
|
String2Vector(mj_getPluginConfig(m, instance, "face"), face);
|
||||||
return Shell(m, d, instance, nu, E, damp, thick, face);
|
String2Vector(mj_getPluginConfig(m, instance, "edge"), edge);
|
||||||
|
return Shell(m, d, instance, nu, E, thick, face, edge);
|
||||||
} else {
|
} else {
|
||||||
mju_warning("Invalid parameter specification in shell plugin");
|
mju_warning("Invalid parameter specification in shell plugin");
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -123,13 +88,14 @@ std::optional<Shell> Shell::Create(const mjModel* m, mjData* d, int instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create map from triangles to vertices and edges and from edges to vertices
|
// create map from triangles to vertices and edges and from edges to vertices
|
||||||
void Shell::CreateStencils(const std::vector<int>& face) {
|
void Shell::CreateStencils(const std::vector<int>& simplex,
|
||||||
|
const std::vector<int>& edgeidx) {
|
||||||
// populate stencil
|
// populate stencil
|
||||||
nt = face.size() / kNumVerts;
|
nt = simplex.size() / kNumVerts;
|
||||||
elements.resize(nt);
|
elements.resize(nt);
|
||||||
for (int t = 0; t < nt; t++) {
|
for (int t = 0; t < nt; t++) {
|
||||||
for (int v = 0; v < kNumVerts; v++) {
|
for (int v = 0; v < kNumVerts; v++) {
|
||||||
elements[t].vertices[v] = face[kNumVerts*t+v]-1;
|
elements[t].vertices[v] = simplex[kNumVerts*t+v];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,14 +128,19 @@ void Shell::CreateStencils(const std::vector<int>& face) {
|
|||||||
elements[t].edges[e] = it->second;
|
elements[t].edges[e] = it->second;
|
||||||
flaps[it->second].vertices[3] = v[(edge[e][1]+1) % 3];
|
flaps[it->second].vertices[3] = v[(edge[e][1]+1) % 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!edgeidx.empty()) {
|
||||||
|
assert(elements[t].edges[e] == edgeidx[kNumEdges*t+e]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plugin constructor
|
// plugin constructor
|
||||||
Shell::Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
Shell::Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
||||||
mjtNum damp, mjtNum thick, const std::vector<int>& face)
|
mjtNum thick, const std::vector<int>& face,
|
||||||
: damping(damp), thickness(thick) {
|
const std::vector<int>& edgeidx)
|
||||||
|
: thickness(thick) {
|
||||||
// count plugin bodies
|
// count plugin bodies
|
||||||
nv = ne = 0;
|
nv = ne = 0;
|
||||||
for (int i = 1; i < m->nbody; i++) {
|
for (int i = 1; i < m->nbody; i++) {
|
||||||
@@ -181,7 +152,7 @@ Shell::Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate triangles from the vertices
|
// generate triangles from the vertices
|
||||||
CreateStencils(face);
|
CreateStencils(face, edgeidx);
|
||||||
|
|
||||||
// material parameters
|
// material parameters
|
||||||
mjtNum mu = E / (2*(1+nu));
|
mjtNum mu = E / (2*(1+nu));
|
||||||
@@ -234,10 +205,6 @@ Shell::Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Shell::Compute(const mjModel* m, mjData* d, int instance) {
|
void Shell::Compute(const mjModel* m, mjData* d, int instance) {
|
||||||
mjtNum kD = damping / m->opt.timestep;
|
|
||||||
|
|
||||||
// compute bending contribution
|
|
||||||
mjtNum embedding;
|
|
||||||
for (int e = 0; e < ne; e++) {
|
for (int e = 0; e < ne; e++) {
|
||||||
int* v = flaps[e].vertices;
|
int* v = flaps[e].vertices;
|
||||||
mjtNum force[12] = {0};
|
mjtNum force[12] = {0};
|
||||||
@@ -248,8 +215,7 @@ void Shell::Compute(const mjModel* m, mjData* d, int instance) {
|
|||||||
for (int i = 0; i < StencilFlap::kNumVerts; i++) {
|
for (int i = 0; i < StencilFlap::kNumVerts; i++) {
|
||||||
for (int j = 0; j < StencilFlap::kNumVerts; j++) {
|
for (int j = 0; j < StencilFlap::kNumVerts; j++) {
|
||||||
for (int x = 0; x < 3; x++) {
|
for (int x = 0; x < 3; x++) {
|
||||||
embedding = d->xpos[3*(i0+v[j])+x]*(kD+1) - position[3*v[j]+x]*kD;
|
force[3*i+x] += bending[16*e+4*i+j] * d->xpos[3*(i0+v[j])+x];
|
||||||
force[3*i+x] += bending[16*e+4*i+j] * embedding;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,8 +241,8 @@ void Shell::RegisterPlugin() {
|
|||||||
plugin.name = "mujoco.elasticity.shell";
|
plugin.name = "mujoco.elasticity.shell";
|
||||||
plugin.capabilityflags |= mjPLUGIN_PASSIVE;
|
plugin.capabilityflags |= mjPLUGIN_PASSIVE;
|
||||||
|
|
||||||
const char* attributes[] = {"face", "young", "poisson", "damping",
|
const char* attributes[] = {"face", "edge", "young",
|
||||||
"thickness"};
|
"poisson", "thickness"};
|
||||||
plugin.nattribute = sizeof(attributes) / sizeof(attributes[0]);
|
plugin.nattribute = sizeof(attributes) / sizeof(attributes[0]);
|
||||||
plugin.attributes = attributes;
|
plugin.attributes = attributes;
|
||||||
plugin.nstate = +[](const mjModel* m, int instance) { return 0; };
|
plugin.nstate = +[](const mjModel* m, int instance) { return 0; };
|
||||||
|
|||||||
@@ -64,14 +64,15 @@ class Shell {
|
|||||||
std::vector<mjtNum> position; // previous-step positions (nv x 3)
|
std::vector<mjtNum> position; // previous-step positions (nv x 3)
|
||||||
std::vector<mjtNum> bending; // bending Hessian (ne x 16)
|
std::vector<mjtNum> bending; // bending Hessian (ne x 16)
|
||||||
|
|
||||||
mjtNum damping;
|
|
||||||
mjtNum thickness;
|
mjtNum thickness;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
Shell(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
||||||
mjtNum damp, mjtNum thick, const std::vector<int>& face);
|
mjtNum thick, const std::vector<int>& face,
|
||||||
|
const std::vector<int>& edgeidx);
|
||||||
|
|
||||||
void CreateStencils(const std::vector<int>& face);
|
void CreateStencils(const std::vector<int>& simplex,
|
||||||
|
const std::vector<int>& edgeidx);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mujoco::plugin::elasticity
|
} // namespace mujoco::plugin::elasticity
|
||||||
|
|||||||
+43
-14
@@ -13,6 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -100,15 +101,17 @@ void GradSquaredLengths(mjtNum gradient[kNumEdges][2][3],
|
|||||||
// factory function
|
// factory function
|
||||||
std::optional<Solid> Solid::Create(const mjModel* m, mjData* d, int instance) {
|
std::optional<Solid> Solid::Create(const mjModel* m, mjData* d, int instance) {
|
||||||
if (CheckAttr("face", m, instance) &&
|
if (CheckAttr("face", m, instance) &&
|
||||||
|
CheckAttr("edge", m, instance) &&
|
||||||
CheckAttr("poisson", m, instance) &&
|
CheckAttr("poisson", m, instance) &&
|
||||||
CheckAttr("young", m, instance)) {
|
CheckAttr("young", m, instance)) {
|
||||||
mjtNum nu = strtod(mj_getPluginConfig(m, instance, "poisson"), nullptr);
|
mjtNum nu = strtod(mj_getPluginConfig(m, instance, "poisson"), nullptr);
|
||||||
mjtNum E = strtod(mj_getPluginConfig(m, instance, "young"), nullptr);
|
mjtNum E = strtod(mj_getPluginConfig(m, instance, "young"), nullptr);
|
||||||
mjtNum damp =
|
mjtNum damp =
|
||||||
strtod(mj_getPluginConfig(m, instance, "damping"), nullptr);
|
strtod(mj_getPluginConfig(m, instance, "damping"), nullptr);
|
||||||
std::vector<int> face;
|
std::vector<int> face, edge;
|
||||||
String2Vector(mj_getPluginConfig(m, instance, "face"), face);
|
String2Vector(mj_getPluginConfig(m, instance, "face"), face);
|
||||||
return Solid(m, d, instance, nu, E, damp, face);
|
String2Vector(mj_getPluginConfig(m, instance, "edge"), edge);
|
||||||
|
return Solid(m, d, instance, nu, E, damp, face, edge);
|
||||||
} else {
|
} else {
|
||||||
mju_warning("Invalid parameter specification in solid plugin");
|
mju_warning("Invalid parameter specification in solid plugin");
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -116,13 +119,14 @@ std::optional<Solid> Solid::Create(const mjModel* m, mjData* d, int instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create map from tetrahedra to vertices and edges and from edges to vertices
|
// create map from tetrahedra to vertices and edges and from edges to vertices
|
||||||
void Solid::CreateStencils(const std::vector<int>& simplex) {
|
void Solid::CreateStencils(const std::vector<int>& simplex,
|
||||||
|
const std::vector<int>& edgeidx) {
|
||||||
// populate stencil
|
// populate stencil
|
||||||
nt = simplex.size() / kNumVerts;
|
nt = simplex.size() / kNumVerts;
|
||||||
elements.resize(nt);
|
elements.resize(nt);
|
||||||
for (int t = 0; t < nt; t++) {
|
for (int t = 0; t < nt; t++) {
|
||||||
for (int v = 0; v < kNumVerts; v++) {
|
for (int v = 0; v < kNumVerts; v++) {
|
||||||
elements[t].vertices[v] = simplex[kNumVerts*t+v]-1;
|
elements[t].vertices[v] = simplex[kNumVerts*t+v];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,14 +153,19 @@ void Solid::CreateStencils(const std::vector<int>& simplex) {
|
|||||||
} else {
|
} else {
|
||||||
elements[t].edges[e] = it->second;
|
elements[t].edges[e] = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!edgeidx.empty()) {
|
||||||
|
assert(elements[t].edges[e] == edgeidx[kNumEdges*t+e]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plugin constructor
|
// plugin constructor
|
||||||
Solid::Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
Solid::Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
||||||
mjtNum damp, const std::vector<int>& simplex)
|
mjtNum damp, const std::vector<int>& simplex,
|
||||||
: damping(damp) {
|
const std::vector<int>& edgeidx)
|
||||||
|
: f0(-1), damping(damp) {
|
||||||
// count plugin bodies
|
// count plugin bodies
|
||||||
nv = ne = 0;
|
nv = ne = 0;
|
||||||
for (int i = 1; i < m->nbody; i++) {
|
for (int i = 1; i < m->nbody; i++) {
|
||||||
@@ -167,8 +176,16 @@ Solid::Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// count flexes
|
||||||
|
for (int i = 0; i < m->nflex; i++) {
|
||||||
|
if (m->flex_vertbodyid[m->flex_vertadr[i]] == i0) {
|
||||||
|
f0 = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate tetrahedra from the vertices
|
// generate tetrahedra from the vertices
|
||||||
CreateStencils(simplex);
|
CreateStencils(simplex, edgeidx);
|
||||||
|
|
||||||
// allocate arrays
|
// allocate arrays
|
||||||
metric.assign(kNumEdges*kNumEdges*nt, 0);
|
metric.assign(kNumEdges*kNumEdges*nt, 0);
|
||||||
@@ -238,7 +255,10 @@ Solid::Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Solid::Compute(const mjModel* m, mjData* d, int instance) {
|
void Solid::Compute(const mjModel* m, mjData* d, int instance) {
|
||||||
UpdateSquaredLengths(deformed, edges, d->xpos+3*i0);
|
// update edges if no flex
|
||||||
|
if (f0 < 0) {
|
||||||
|
UpdateSquaredLengths(deformed, edges, d->xpos+3*i0);
|
||||||
|
}
|
||||||
|
|
||||||
// loop over all elements
|
// loop over all elements
|
||||||
for (int t = 0; t < nt; t++) {
|
for (int t = 0; t < nt; t++) {
|
||||||
@@ -254,11 +274,18 @@ void Solid::Compute(const mjModel* m, mjData* d, int instance) {
|
|||||||
|
|
||||||
// compute elongation
|
// compute elongation
|
||||||
mjtNum elongation[kNumEdges];
|
mjtNum elongation[kNumEdges];
|
||||||
mjtNum kD = damping / m->opt.timestep;
|
|
||||||
for (int e = 0; e < kNumEdges; e++) {
|
for (int e = 0; e < kNumEdges; e++) {
|
||||||
int idx = elements[t].edges[e];
|
if (f0 < 0) {
|
||||||
elongation[e] = deformed[idx] - reference[idx] +
|
int idx = elements[t].edges[e];
|
||||||
( deformed[idx] - previous[idx] ) * kD;
|
mjtNum kD = damping / m->opt.timestep;
|
||||||
|
elongation[e] = deformed[idx] - reference[idx] +
|
||||||
|
( deformed[idx] - previous[idx] ) * kD;
|
||||||
|
} else {
|
||||||
|
int idx = elements[t].edges[e] + m->flex_edgeadr[f0];
|
||||||
|
mjtNum deformed = d->flexedge_length[idx]*d->flexedge_length[idx];
|
||||||
|
mjtNum reference = m->flexedge_length0[idx]*m->flexedge_length0[idx];
|
||||||
|
elongation[e] = deformed - reference;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we now multiply the elongations by the precomputed metric tensor,
|
// we now multiply the elongations by the precomputed metric tensor,
|
||||||
@@ -289,7 +316,9 @@ void Solid::Compute(const mjModel* m, mjData* d, int instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update stored lengths
|
// update stored lengths
|
||||||
previous = deformed;
|
if (f0 < 0) {
|
||||||
|
previous = deformed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -301,7 +330,7 @@ void Solid::RegisterPlugin() {
|
|||||||
plugin.name = "mujoco.elasticity.solid";
|
plugin.name = "mujoco.elasticity.solid";
|
||||||
plugin.capabilityflags |= mjPLUGIN_PASSIVE;
|
plugin.capabilityflags |= mjPLUGIN_PASSIVE;
|
||||||
|
|
||||||
const char* attributes[] = {"face", "young", "poisson", "damping"};
|
const char* attributes[] = {"face", "edge", "young", "poisson", "damping"};
|
||||||
plugin.nattribute = sizeof(attributes) / sizeof(attributes[0]);
|
plugin.nattribute = sizeof(attributes) / sizeof(attributes[0]);
|
||||||
plugin.attributes = attributes;
|
plugin.attributes = attributes;
|
||||||
plugin.nstate = +[](const mjModel* m, int instance) { return 0; };
|
plugin.nstate = +[](const mjModel* m, int instance) { return 0; };
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class Solid {
|
|||||||
|
|
||||||
static void RegisterPlugin();
|
static void RegisterPlugin();
|
||||||
|
|
||||||
|
int f0; // index of corresponding flex
|
||||||
int i0; // index of first body
|
int i0; // index of first body
|
||||||
int nc; // number of cubes in the grid
|
int nc; // number of cubes in the grid
|
||||||
int nv; // number of vertices (bodies) in the solid
|
int nv; // number of vertices (bodies) in the solid
|
||||||
@@ -64,9 +65,11 @@ class Solid {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
Solid(const mjModel* m, mjData* d, int instance, mjtNum nu, mjtNum E,
|
||||||
mjtNum damp, const std::vector<int>& simplex);
|
mjtNum damp, const std::vector<int>& simplex,
|
||||||
|
const std::vector<int>& edgeidx);
|
||||||
|
|
||||||
void CreateStencils(const std::vector<int>& simplex);
|
void CreateStencils(const std::vector<int>& simplex,
|
||||||
|
const std::vector<int>& edgeidx);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mujoco::plugin::elasticity
|
} // namespace mujoco::plugin::elasticity
|
||||||
|
|||||||
@@ -1814,6 +1814,8 @@ void mj_collideFlexSAP(const mjModel* m, mjData* d, int f) {
|
|||||||
|
|
||||||
// test a geom and an elem for collision, add to contact list
|
// test a geom and an elem for collision, add to contact list
|
||||||
void mj_collideGeomElem(const mjModel* m, mjData* d, int g, int f, int e) {
|
void mj_collideGeomElem(const mjModel* m, mjData* d, int g, int f, int e) {
|
||||||
|
TM_START;
|
||||||
|
|
||||||
mjtNum margin = mj_assignMargin(m, mju_max(m->geom_margin[g], m->flex_margin[f]));
|
mjtNum margin = mj_assignMargin(m, mju_max(m->geom_margin[g], m->flex_margin[f]));
|
||||||
int dim = m->flex_dim[f], type = m->geom_type[g];
|
int dim = m->flex_dim[f], type = m->geom_type[g];
|
||||||
int num;
|
int num;
|
||||||
@@ -1927,6 +1929,9 @@ void mj_collideGeomElem(const mjModel* m, mjData* d, int g, int f, int e) {
|
|||||||
|
|
||||||
// move arena pointer back to the end of the contact array
|
// move arena pointer back to the end of the contact array
|
||||||
resetArena(d);
|
resetArena(d);
|
||||||
|
|
||||||
|
// add duration without incrementing counter
|
||||||
|
TM_ADD(mjTIMER_COL_NARROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1934,6 +1939,7 @@ void mj_collideGeomElem(const mjModel* m, mjData* d, int g, int f, int e) {
|
|||||||
// test two elems for collision, add to contact list
|
// test two elems for collision, add to contact list
|
||||||
void mj_collideElems(const mjModel* m, mjData* d, int f1, int e1, int f2, int e2) {
|
void mj_collideElems(const mjModel* m, mjData* d, int f1, int e1, int f2, int e2) {
|
||||||
TM_START;
|
TM_START;
|
||||||
|
|
||||||
mjtNum margin = mj_assignMargin(m, mju_max(m->flex_margin[f1], m->flex_margin[f2]));
|
mjtNum margin = mj_assignMargin(m, mju_max(m->flex_margin[f1], m->flex_margin[f2]));
|
||||||
int dim1 = m->flex_dim[f1], dim2 = m->flex_dim[f2];
|
int dim1 = m->flex_dim[f1], dim2 = m->flex_dim[f2];
|
||||||
int num;
|
int num;
|
||||||
|
|||||||
@@ -537,9 +537,7 @@ void mj_flex(const mjModel* m, mjData* d) {
|
|||||||
// compute lengths and Jacobians of edges
|
// compute lengths and Jacobians of edges
|
||||||
for (int f=0; f < m->nflex; f++) {
|
for (int f=0; f < m->nflex; f++) {
|
||||||
// skip if edges cannot generate forces
|
// skip if edges cannot generate forces
|
||||||
if (m->flex_rigid[f] ||
|
if (m->flex_rigid[f]) {
|
||||||
(m->flex_edgeequality[f] == 0 &&
|
|
||||||
m->flex_edgestiffness[f] == 0 && m->flex_edgedamping[f] == 0)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -948,11 +948,11 @@ void mj_energyPos(const mjModel* m, mjData* d) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add flex-level springs
|
// add flex-level springs for dim=1 (dim>1 requires plugins)
|
||||||
if (!mjDISABLED(mjDSBL_PASSIVE)) {
|
if (!mjDISABLED(mjDSBL_PASSIVE)) {
|
||||||
for (int i=0; i < m->nflex; i++) {
|
for (int i=0; i < m->nflex; i++) {
|
||||||
stiffness = m->flex_edgestiffness[i];
|
stiffness = m->flex_edgestiffness[i];
|
||||||
if (m->flex_rigid[i] || stiffness == 0) {
|
if (m->flex_rigid[i] || stiffness == 0 || m->flex_dim[i] > 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-10
@@ -370,7 +370,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
};
|
};
|
||||||
for (int s = 0; s < 6; s++) {
|
for (int s = 0; s < 6; s++) {
|
||||||
for (int v = 0; v < 4; v++) {
|
for (int v = 0; v < 4; v++) {
|
||||||
face.push_back(vert[cube2tets[s][v]]+1);
|
face.push_back(vert[cube2tets[s][v]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
};
|
};
|
||||||
for (int s = 0; s < 2; s++) {
|
for (int s = 0; s < 2; s++) {
|
||||||
for (int v = 0; v < 3; v++) {
|
for (int v = 0; v < 3; v++) {
|
||||||
face.push_back(vert[quad2tri[s][v]]+1);
|
face.push_back(vert[quad2tri[s][v]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -398,6 +398,8 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
} else {
|
} else {
|
||||||
dim = 2; // can only load a surface for now
|
dim = 2; // can only load a surface for now
|
||||||
mjXUtil::String2Vector(userface, face);
|
mjXUtil::String2Vector(userface, face);
|
||||||
|
for (int i=0; i<face.size(); face[i++]--) {};
|
||||||
|
mjXUtil::Vector2String(userface, face);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute volume
|
// compute volume
|
||||||
@@ -414,13 +416,13 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
mjtNum edge2[3];
|
mjtNum edge2[3];
|
||||||
|
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
edge1[i] = uservert[3*(face[3*j+1]-1)+i] - uservert[3*(face[3*j]-1)+i];
|
edge1[i] = uservert[3*face[3*j+1]+i] - uservert[3*face[3*j]+i];
|
||||||
edge2[i] = uservert[3*(face[3*j+2]-1)+i] - uservert[3*(face[3*j]-1)+i];
|
edge2[i] = uservert[3*face[3*j+2]+i] - uservert[3*face[3*j]+i];
|
||||||
}
|
}
|
||||||
|
|
||||||
mjuu_crossvec(area, edge1, edge2);
|
mjuu_crossvec(area, edge1, edge2);
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
volume[face[3*j+i]-1] += sqrt(mjuu_dot3(area, area)) / 2 * t;
|
volume[face[3*j+i]] += sqrt(mjuu_dot3(area, area)) / 2 * t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -489,6 +491,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
b->plugin_instance->config_attribs["face"] = userface;
|
b->plugin_instance->config_attribs["face"] = userface;
|
||||||
|
b->plugin_instance->config_attribs["edge"] = "";
|
||||||
|
|
||||||
// update density
|
// update density
|
||||||
if (dim == 2) {
|
if (dim == 2) {
|
||||||
@@ -505,8 +508,8 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjCBody* body, char* error, int
|
|||||||
// create edges
|
// create edges
|
||||||
for (int i=0; i<face.size()/3; i++) {
|
for (int i=0; i<face.size()/3; i++) {
|
||||||
for (int j=0; j<3; j++) {
|
for (int j=0; j<3; j++) {
|
||||||
int v0 = face[3*i+(j+0)%3]-1;
|
int v0 = face[3*i+(j+0)%3];
|
||||||
int v1 = face[3*i+(j+1)%3]-1;
|
int v1 = face[3*i+(j+1)%3];
|
||||||
edge.push_back(v0 < v1 ? std::pair(v0, v1) : std::pair(v1, v0));
|
edge.push_back(v0 < v1 ? std::pair(v0, v1) : std::pair(v1, v0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1271,9 +1274,9 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<face.size()/3; i++) {
|
for (int i=0; i<face.size()/3; i++) {
|
||||||
skin->face.push_back(j*nvert+face[3*i]-1);
|
skin->face.push_back(j*nvert+face[3*i]);
|
||||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 1 : 2)]-1);
|
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 1 : 2)]);
|
||||||
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 2 : 1)]-1);
|
skin->face.push_back(j*nvert+face[3*i+(j==0 ? 2 : 1)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,11 +65,12 @@ mjCFlexcomp::mjCFlexcomp(void) {
|
|||||||
mjuu_setvec(scale, 1, 1, 1);
|
mjuu_setvec(scale, 1, 1, 1);
|
||||||
mass = 1;
|
mass = 1;
|
||||||
inertiabox = 0.005;
|
inertiabox = 0.005;
|
||||||
equality = true;
|
equality = false;
|
||||||
mjuu_setvec(pos, 0, 0, 0);
|
mjuu_setvec(pos, 0, 0, 0);
|
||||||
mjuu_setvec(quat, 1, 0, 0, 0);
|
mjuu_setvec(quat, 1, 0, 0, 0);
|
||||||
rigid = false;
|
rigid = false;
|
||||||
centered = false;
|
centered = false;
|
||||||
|
plugin_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -453,6 +454,14 @@ bool mjCFlexcomp::Make(mjCModel* model, mjCBody* body, char* error, int error_sz
|
|||||||
pf->vert[3*i+1] = 0;
|
pf->vert[3*i+1] = 0;
|
||||||
pf->vert[3*i+2] = 0;
|
pf->vert[3*i+2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add plugin
|
||||||
|
if (plugin_instance) {
|
||||||
|
pb->is_plugin = true;
|
||||||
|
pb->plugin_name = plugin_name;
|
||||||
|
pb->plugin_instance = plugin_instance;
|
||||||
|
pb->plugin_instance_name = plugin_instance_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,12 @@ class mjCFlexcomp {
|
|||||||
std::vector<bool> used; // is point used by any element (false: skip)
|
std::vector<bool> used; // is point used by any element (false: skip)
|
||||||
std::vector<int> element; // flex elements
|
std::vector<int> element; // flex elements
|
||||||
std::vector<float> texcoord; // vertex texture coordinates
|
std::vector<float> texcoord; // vertex texture coordinates
|
||||||
|
|
||||||
|
// plugin support
|
||||||
|
bool is_plugin;
|
||||||
|
std::string plugin_name;
|
||||||
|
std::string plugin_instance_name;
|
||||||
|
mjCPlugin* plugin_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MUJOCO_SRC_USER_USER_FLEXCOMP_H_
|
#endif // MUJOCO_SRC_USER_USER_FLEXCOMP_H_
|
||||||
|
|||||||
+59
-31
@@ -18,9 +18,11 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -59,6 +61,7 @@
|
|||||||
#include "user/user_model.h"
|
#include "user/user_model.h"
|
||||||
#include "user/user_objects.h"
|
#include "user/user_objects.h"
|
||||||
#include "user/user_util.h"
|
#include "user/user_util.h"
|
||||||
|
#include "xml/xml_util.h"
|
||||||
#include <tiny_obj_loader.h>
|
#include <tiny_obj_loader.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -2157,6 +2160,24 @@ void mjCSkin::LoadSKN(mjResource* resource) {
|
|||||||
|
|
||||||
//------------------ class mjCFlex implementation --------------------------------------------------
|
//------------------ class mjCFlex implementation --------------------------------------------------
|
||||||
|
|
||||||
|
// hash function for std::pair
|
||||||
|
struct PairHash
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
std::size_t operator() (const std::pair<T1, T2>& pair) const {
|
||||||
|
return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// simplex connectivity
|
||||||
|
constexpr int kNumEdges[3] = {1, 3, 6};
|
||||||
|
constexpr int eledge[3][6][2] = {{{ 0, 1}, {-1, -1}, {-1, -1},
|
||||||
|
{-1, -1}, {-1, -1}, {-1, -1}},
|
||||||
|
{{ 1, 2}, { 2, 0}, { 0, 1},
|
||||||
|
{-1, -1}, {-1, -1}, {-1, -1}},
|
||||||
|
{{ 0, 1}, { 1, 2}, { 2, 0},
|
||||||
|
{ 2, 3}, { 0, 3}, { 1, 3}}};
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
mjCFlex::mjCFlex(mjCModel* _model) {
|
mjCFlex::mjCFlex(mjCModel* _model) {
|
||||||
// set model
|
// set model
|
||||||
@@ -2216,6 +2237,9 @@ void mjCFlex::Compile(const mjVFS* vfs) {
|
|||||||
if (vert.size() % 3) {
|
if (vert.size() % 3) {
|
||||||
throw mjCError(this, "vert size must be a multiple of 3");
|
throw mjCError(this, "vert size must be a multiple of 3");
|
||||||
}
|
}
|
||||||
|
if (edgestiffness>0 && dim>1) {
|
||||||
|
throw mjCError(this, "edge stiffness only available for dim=1, please use elasticity plugins");
|
||||||
|
}
|
||||||
nelem = (int)elem.size()/(dim+1);
|
nelem = (int)elem.size()/(dim+1);
|
||||||
|
|
||||||
// set nvert, rigid, centered; check size
|
// set nvert, rigid, centered; check size
|
||||||
@@ -2276,42 +2300,34 @@ void mjCFlex::Compile(const mjVFS* vfs) {
|
|||||||
throw mjCError(this, "repeated vertex in element");
|
throw mjCError(this, "repeated vertex in element");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make edges from sorted element
|
|
||||||
switch (dim) {
|
|
||||||
case 1: // line
|
|
||||||
edge.push_back(std::make_pair(el[0], el[1]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // triangle
|
|
||||||
edge.push_back(std::make_pair(el[0], el[1]));
|
|
||||||
edge.push_back(std::make_pair(el[1], el[2]));
|
|
||||||
edge.push_back(std::make_pair(el[0], el[2]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // tetrahedron
|
|
||||||
edge.push_back(std::make_pair(el[0], el[1]));
|
|
||||||
edge.push_back(std::make_pair(el[1], el[2]));
|
|
||||||
edge.push_back(std::make_pair(el[2], el[3]));
|
|
||||||
edge.push_back(std::make_pair(el[0], el[2]));
|
|
||||||
edge.push_back(std::make_pair(el[0], el[3]));
|
|
||||||
edge.push_back(std::make_pair(el[1], el[3]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort edges
|
// create edges
|
||||||
std::sort(edge.begin(), edge.end());
|
std::vector<int> edgeidx(elem.size()*kNumEdges[dim-1]);
|
||||||
|
|
||||||
// remove repeated edges
|
// map from edge vertices to their index in `edges` vector
|
||||||
std::vector<std::pair<int,int>> edge1;
|
std::unordered_map<std::pair<int, int>, int, PairHash> edge_indices;
|
||||||
edge1.push_back(edge[0]);
|
|
||||||
for (int i=1; i<(int)edge.size(); i++) {
|
// insert local edges into global vector
|
||||||
if (edge1[edge1.size()-1]!=edge[i]) {
|
for (int f = 0; f < (int)elem.size()/(dim+1); f++) {
|
||||||
edge1.push_back(edge[i]);
|
int* v = elem.data() + f*(dim+1);
|
||||||
|
for (int e = 0; e < kNumEdges[dim-1]; e++) {
|
||||||
|
auto pair = std::pair(
|
||||||
|
std::min(v[eledge[dim-1][e][0]], v[eledge[dim-1][e][1]]),
|
||||||
|
std::max(v[eledge[dim-1][e][0]], v[eledge[dim-1][e][1]])
|
||||||
|
);
|
||||||
|
|
||||||
|
// if edge is already present in the vector only store its index
|
||||||
|
auto [it, inserted] = edge_indices.insert({pair, nedge});
|
||||||
|
|
||||||
|
if (inserted) {
|
||||||
|
edge.push_back(pair);
|
||||||
|
edgeidx[f*kNumEdges[dim-1]+e] = nedge++;
|
||||||
|
} else {
|
||||||
|
edgeidx[f*kNumEdges[dim-1]+e] = it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edge = edge1;
|
|
||||||
|
|
||||||
// set size
|
// set size
|
||||||
nedge = (int)edge.size();
|
nedge = (int)edge.size();
|
||||||
@@ -2378,6 +2394,18 @@ void mjCFlex::Compile(const mjVFS* vfs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add plugins
|
||||||
|
std::string userface, useredge;
|
||||||
|
mjXUtil::Vector2String(userface, elem);
|
||||||
|
mjXUtil::Vector2String(useredge, edgeidx);
|
||||||
|
|
||||||
|
for (int i=0; i<(int)vertbodyid.size(); i++) {
|
||||||
|
if (model->bodies[vertbodyid[i]]->plugin_instance) {
|
||||||
|
model->bodies[vertbodyid[i]]->plugin_instance->config_attribs["face"] = userface;
|
||||||
|
model->bodies[vertbodyid[i]]->plugin_instance->config_attribs["edge"] = useredge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create shell fragments and element-vertex collision pairs
|
// create shell fragments and element-vertex collision pairs
|
||||||
CreateShellPair();
|
CreateShellPair();
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjCPlugin* pp) {
|
|||||||
|
|
||||||
//---------------------------------- MJCF schema ---------------------------------------------------
|
//---------------------------------- MJCF schema ---------------------------------------------------
|
||||||
|
|
||||||
static const int nMJCF = 223;
|
static const int nMJCF = 227;
|
||||||
static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
||||||
{"mujoco", "!", "1", "model"},
|
{"mujoco", "!", "1", "model"},
|
||||||
{"<"},
|
{"<"},
|
||||||
@@ -293,25 +293,31 @@ static const char* MJCF[nMJCF][mjXATTRNUM] = {
|
|||||||
{"config", "*", "2", "key", "value"},
|
{"config", "*", "2", "key", "value"},
|
||||||
{">"},
|
{">"},
|
||||||
{">"},
|
{">"},
|
||||||
{"flexcomp", "*", "26", "name", "class", "type", "dim", "flatskin",
|
{"flexcomp", "*", "25", "name", "class", "type", "group", "dim",
|
||||||
"count", "spacing", "radius", "rigid", "mass", "inertiabox",
|
"count", "spacing", "radius", "rigid", "mass", "inertiabox",
|
||||||
"scale", "file", "point", "element", "texcoord", "material", "rgba", "selfcollide",
|
"scale", "file", "point", "element", "texcoord", "material", "rgba",
|
||||||
"flatskin", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler"},
|
"flatskin", "pos", "quat", "axisangle", "xyaxes", "zaxis", "euler"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"edge", "?", "5", "equality", "solref", "solimp", "stiffness", "damping"},
|
{"edge", "?", "5", "equality", "solref", "solimp", "stiffness", "damping"},
|
||||||
{"contact", "?", "10", "contype", "conaffinity", "condim", "priority",
|
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
|
||||||
"friction", "solmix", "solref", "solimp", "margin", "gap"},
|
"friction", "solmix", "solref", "solimp", "margin", "gap",
|
||||||
|
"internal", "selfcollide", "activelayers"},
|
||||||
{"pin", "*", "4", "id", "range", "grid", "gridrange"},
|
{"pin", "*", "4", "id", "range", "grid", "gridrange"},
|
||||||
|
{"plugin", "*", "2", "plugin", "instance"},
|
||||||
|
{"<"},
|
||||||
|
{"config", "*", "2", "key", "value"},
|
||||||
|
{">"},
|
||||||
{">"},
|
{">"},
|
||||||
{">"},
|
{">"},
|
||||||
|
|
||||||
{"deformable", "*", "0"},
|
{"deformable", "*", "0"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"flex", "*", "12", "name", "group", "dim", "radius", "material", "rgba", "flatskin",
|
{"flex", "*", "11", "name", "group", "dim", "radius", "material",
|
||||||
"selfcollide", "body", "vertex", "element", "texcoord"},
|
"rgba", "flatskin", "body", "vertex", "element", "texcoord"},
|
||||||
{"<"},
|
{"<"},
|
||||||
{"contact", "?", "10", "contype", "conaffinity", "condim", "priority",
|
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
|
||||||
"friction", "solmix", "solref", "solimp", "margin", "gap"},
|
"friction", "solmix", "solref", "solimp", "margin", "gap",
|
||||||
|
"internal", "selfcollide", "activelayers"},
|
||||||
{"edge", "?", "2", "stiffness", "damping"},
|
{"edge", "?", "2", "stiffness", "damping"},
|
||||||
{">"},
|
{">"},
|
||||||
{"skin", "*", "9", "name", "file", "material", "rgba", "inflate",
|
{"skin", "*", "9", "name", "file", "material", "rgba", "inflate",
|
||||||
@@ -2366,6 +2372,21 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjCBody* pbody) {
|
|||||||
epin = epin->NextSiblingElement("pin");
|
epin = epin->NextSiblingElement("pin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// plugin
|
||||||
|
XMLElement* eplugin = elem->FirstChildElement("plugin");
|
||||||
|
if (eplugin) {
|
||||||
|
ReadAttrTxt(eplugin, "plugin", fcomp.plugin_name);
|
||||||
|
ReadAttrTxt(eplugin, "instance", fcomp.plugin_instance_name);
|
||||||
|
if (fcomp.plugin_instance_name.empty()) {
|
||||||
|
fcomp.plugin_instance = model->AddPlugin();
|
||||||
|
fcomp.plugin_instance->name = "flexcomp_" + fcomp.name;
|
||||||
|
fcomp.plugin_instance_name = fcomp.plugin_instance->name;
|
||||||
|
} else {
|
||||||
|
model->hasImplicitPluginElem = true;
|
||||||
|
}
|
||||||
|
ReadPluginConfigs(eplugin, fcomp.plugin_instance);
|
||||||
|
}
|
||||||
|
|
||||||
// make flexcomp
|
// make flexcomp
|
||||||
char error[200];
|
char error[200];
|
||||||
bool res = fcomp.Make(pbody->model, pbody, error, 200);
|
bool res = fcomp.Make(pbody->model, pbody, error, 200);
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ TEST_F(ElasticityTest, ElasticEnergyShell) {
|
|||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<composite type="particle" count="8 8 1" spacing="1">
|
<flexcomp type="grid" count="8 8 1" spacing="1 1 1"
|
||||||
<geom size=".025" group="4"/>
|
radius=".025" name="test" dim="2">
|
||||||
<plugin plugin="mujoco.elasticity.shell">
|
<plugin plugin="mujoco.elasticity.shell">
|
||||||
<config key="poisson" value="0"/>
|
<config key="poisson" value="0"/>
|
||||||
<config key="young" value="2"/>
|
<config key="young" value="2"/>
|
||||||
<config key="thickness" value="1"/>
|
<config key="thickness" value="1"/>
|
||||||
</plugin>
|
</plugin>
|
||||||
</composite>
|
</flexcomp>
|
||||||
</worldbody>
|
</worldbody>
|
||||||
</mujoco>
|
</mujoco>
|
||||||
)";
|
)";
|
||||||
@@ -93,13 +93,14 @@ TEST_F(ElasticityTest, ElasticEnergySolid) {
|
|||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<composite type="particle" count="8 8 8" spacing="1">
|
<flexcomp type="grid" count="8 8 8" spacing="1 1 1"
|
||||||
<geom size=".025" group="4"/>
|
radius=".025" name="test" dim="3">
|
||||||
<plugin plugin="mujoco.elasticity.solid">
|
<plugin plugin="mujoco.elasticity.solid">
|
||||||
<config key="poisson" value="0"/>
|
<config key="poisson" value="0"/>
|
||||||
<config key="young" value="2"/>
|
<config key="young" value="2"/>
|
||||||
</plugin>
|
</plugin>
|
||||||
</composite>
|
<edge equality="false"/>
|
||||||
|
</flexcomp>
|
||||||
</worldbody>
|
</worldbody>
|
||||||
</mujoco>
|
</mujoco>
|
||||||
)";
|
)";
|
||||||
@@ -110,6 +111,9 @@ TEST_F(ElasticityTest, ElasticEnergySolid) {
|
|||||||
mjData* d = mj_makeData(m);
|
mjData* d = mj_makeData(m);
|
||||||
auto* solid = reinterpret_cast<plugin::elasticity::Solid*>(d->plugin_data[0]);
|
auto* solid = reinterpret_cast<plugin::elasticity::Solid*>(d->plugin_data[0]);
|
||||||
|
|
||||||
|
mj_kinematics(m, d);
|
||||||
|
mj_flex(m, d);
|
||||||
|
|
||||||
// check that if the entire geometry is rescaled by a factor "scale", then
|
// check that if the entire geometry is rescaled by a factor "scale", then
|
||||||
// trace(strain^2) = 3*scale^2
|
// trace(strain^2) = 3*scale^2
|
||||||
|
|
||||||
@@ -119,10 +123,12 @@ TEST_F(ElasticityTest, ElasticEnergySolid) {
|
|||||||
mjtNum volume = 1./6.;
|
mjtNum volume = 1./6.;
|
||||||
for (int e1 = 0; e1 < 6; e1++) {
|
for (int e1 = 0; e1 < 6; e1++) {
|
||||||
for (int e2 = 0; e2 < 6; e2++) {
|
for (int e2 = 0; e2 < 6; e2++) {
|
||||||
int idx1 = solid->elements[t].edges[e1];
|
int idx1 = solid->elements[t].edges[e1] + m->flex_edgeadr[0];
|
||||||
int idx2 = solid->elements[t].edges[e2];
|
int idx2 = solid->elements[t].edges[e2] + m->flex_edgeadr[0];
|
||||||
mjtNum elongation1 = scale*solid->reference[idx1];
|
mjtNum elongation1 =
|
||||||
mjtNum elongation2 = scale*solid->reference[idx2];
|
scale * m->flexedge_length0[idx1] * m->flexedge_length0[idx1];
|
||||||
|
mjtNum elongation2 =
|
||||||
|
scale * m->flexedge_length0[idx2] * m->flexedge_length0[idx2];
|
||||||
energy += solid->metric[36*t+6*e2+e1] * elongation1 * elongation2;
|
energy += solid->metric[36*t+6*e2+e1] * elongation1 * elongation2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user