mujoco icon indicating copy to clipboard operation
mujoco copied to clipboard

Unity plugin, Weld offset field leads to instability

Open Balint-H opened this issue 3 years ago • 2 comments

Hello,

I'm using Unity 2021.2.19, Windows 10, MuJoCo 2.2.2, and latest version of the plugin. I've been using "puppeteering" from reference animations using mocap bodies and weld constraints. It used to be (back with 2.2.0) that if no offset was provided to the MjWeld component, it would use the transformation between the two constrained bodies at startup as the offset. If this was not the desired behaviour, we could supply a dummy, identity transform in the serialized field, so no offset was applied.

Now if an offset is supplied, even if it is a transform with no localPosition or localRotation effects, the constraint leads to erratic movements from the constrained body, and very quickly an exception due to instability.

8ca5887c20d47f7534c9c22b3e363b64e4e8e36b added additional data stored in model->eq_data, so is this caused by MjTransformAtEntry in the C# MjWeld component returning addresses not appropriate for eq_data? I tried simply increasing the address by 3 in MjWeld's OnBindToRuntime , which resolved instability, but added an undesired offset in the vertical axis.

Balint-H avatar Sep 16 '22 17:09 Balint-H

Wanted to add, that if no Weld Offset transform is supplied then no weird behaviour happens, perhaps because then edits to eq_data are skipped. However this disables the option to have no offset between constrained objects, but start at different states, which can be useful particularly for puppeteering (where the mujoco body definition might be more convenient in a non T-pose for e.g. joint limits, but have the reference animation skeleton in a T-pose).

Here's a minimal scene XML, exported from Unity:

Mocap Scene
<mujoco>
 <worldbody>
   <geom density="1000" type="plane" size="10 10 1" pos="0 0 0" quat="-1 0 0 0" priority="0" contype="1" conaffinity="1" group="0" condim="3" solmix="1" solref="0.02 1" solimp="0.9 0.95 0.001" margin="0" gap="0" friction="1 0.005 0.0001" name="floor_0" />
   <body pos="0.999 0.132 0" quat="-1 0 0 0" mocap="true" name="mocap body_1" />
   <body pos="0 0 1" quat="-1 0 0 0" name="box_2">
     <freejoint name="freejoint_3" />
     <geom density="1000" type="box" size="0.1 0.1 0.1" pos="0 0 0" quat="-1 0 0 0" priority="0" contype="1" conaffinity="1" group="0" condim="3" solmix="1" solref="0.02 1" solimp="0.9 0.95 0.001" margin="0" gap="0" friction="1 0.005 0.0001" name="geom_4" />
   </body>
 </worldbody>
 <contact />
 <tendon />
 <equality>
   <weld body1="mocap body_1" body2="box_2" solref="0.02 1" solimp="0.9 0.95 0.001 0.5 2" name="equality_5" />
 </equality>
 <actuator />
 <sensor />
 <compiler coordinate="local" />
 <option gravity="0 0 -9.81" timestep="0.008333335" impratio="1" magnetic="0 0 0" wind="0 -0.5 0" density="0" viscosity="0" o_margin="0" o_solref="0.02 1" o_solimp="0.9 0.95 0.001 0.5 2" integrator="Euler" collision="all" cone="pyramidal" jacobian="auto" solver="Newton" iterations="100" tolerance="1E-08" noslip_iterations="0" noslip_tolerance="1E-06" mpr_iterations="50" mpr_tolerance="1E-06">
   <flag constraint="enable" equality="enable" frictionloss="enable" limit="enable" contact="enable" passive="enable" gravity="enable" clampctrl="enable" warmstart="enable" filterparent="enable" actuation="enable" refsafe="enable" override="disable" energy="disable" fwdinv="disable" sensornoise="disable" />
 </option>
 <size nuser_sensor="0" />
 <asset />
</mujoco>

Balint-H avatar Sep 16 '22 17:09 Balint-H

Your analysis is correct. I believe you can fix things by replacing MjEngineTool.MjTransformAtEntry(model->eq_data, MujocoId) with model->eq_data + MujocoId * 11 + 3 (11 being the new value of mjNEQDATA following the aforementioned change ). Let me know if that works out for you.

erez-tom avatar Sep 17 '22 15:09 erez-tom

Fixed by #491.

kevinzakka avatar Dec 06 '22 23:12 kevinzakka