The Jumping Contact Normal Bug

Discussion in 'Bug Reports' started by wlorenz65, Aug 15, 2016.

  1. The demonstration video has 210 Mb, that's too large to upload here. It can be downloaded from Google drive at Open it with VirtualDub because that's the only program I know that can reactively and fluidly step through single frames both forward and backward (the frame rate is 2000 fps).


    As the red pressure ball is sliding along the thread segment, it crosses a vertex from time to time and then the normal vector first bends and then suddenly jumps about 30°. Similar to a sawtooth wave form. The jump happens in a single timestep, no matter how low the simulation time step is set.

    Those jumps propagate across the model and when the total c(lamp)force gets higher and penetration gets deeper, they are causing the whole simulation to explode. Welding normally clamped objects like washers and covers to the worldbody makes the system more stable as the waves cannot propagate any more.

    Another problem can be seen at the transit between the grey and the violet thread segments. There are two normals vectors then. I don't know if the changes at that transition are smooth enough to prevent explosions because the sawtooth-like jumps are now also there. Maybe the mesh transition will cause unstabilities too at higher rotation speeds. Those two normals wouldn't be there if MuJoCo supported a concave collider. There are so many other options which only have subtle influences. A concave collider would also make mesh modelling more easier.
  2. Emo Todorov

    Emo Todorov Administrator Staff Member

    Nice model and video! I am guessing the arrangement of mesh vertices has some structure that the collision detector is picking up. Simplifying or somehow regularizing the mesh (in MeshLab for example) could help. If you send me the STL I would be happy to look into it.

    The two contacts at the transition between the two meshes are unavoidable with convex collisions, and not necessarily bad - as long as the net contact force ends up pointing in the same direction as before/after the transition.

    The absence of a concave collider reflects the high-level design goal: MuJoCo is a tool for model-based optimization that does simulation. From this perspective, having simulations that are too slow to be used within an optimization loop is of limited use, no matter how realistic they are. It would be nice to have that of course, but there are other missing features (most notably a built-in trajectory optimizer) that need to be developed first.

    In the Pro version, one can replace the default collision functions with any other library -- there is a table with function pointers, one for each pair of geom types. Then one can run the rest of the simulation pipeline with whatever contacts were generated by the user functions. Broad-phase collision detection is still done internally, but all near-phase collision detection functions can be replaced. Let me know if you are interested in experimenting with this and I can provide more details; I am planning to describe this in the documentation actually. So hooking up an external collider to MuJoCo is straightforward; the tricky part is deciding which one to use, how to tune it and how to handle all the messy situations that can arise with polygon-soup collisions. If you end up with a large number of contacts between the same two bodies, you would probably want to filter them somehow.
  3. The file is "Meshes\M8 thread segment 2.stl". All STL files including the OpenSCAD sources have been uploaded to the forum's resources section.

    Increasing the mesh resolution of the thread from $fn=60 to $fn=360 is contraproductive. Its only effect is that the bug now shows up 6 times more often.

    Setting mpr_iterations="5000" and mpr_tolerance="1e-8" has no effect on the bug.

    Three times more pressure balls in order to better distribute the load has only a slight effect. The simulation now explodes when the clampforce reaches 550 N instead of 488 N as in the video.

    I'll get the Pro version tomorrow. Even if I cannot fix this bug I will need it for the simulation of the humanoid body.
  4. Emo Todorov

    Emo Todorov Administrator Staff Member

    Wow, this is an amazing model! I played with Tool Test - M8 Nut. Several observations:

    I replaced the free joint with a slide-hinge joint, to remove any extraneous movements and impose rotational symmetry, like this:

    <!--joint type="free" /-->
    <joint type="hinge" pos="0 0 0" axis="0 0 1"/>
    <joint type="slide" pos="0 0 0" axis="0 0 1"/>

    This revealed that during a perfect rotation, your side boxes are jamming the thread, producing huge contact forces. So I guess you should adjust them. After I commented out the boxes, everything became nice and symmetric. In particular, I observed the contact-normal-turning effect (with the green balls, not the red ones) at each edge of the mesh, and not just occasionally. I think the reason you saw it occasionally is that you have more DOFs, and something else from another direction was pushing the system, making any given contact normal skip some of the mesh edges. I also loaded your mesh in MeshLab -- it looks perfectly nice and evenly triangulated. So I am guessing that given the mesh and the position of the ball, this is the "correct" normal according the MPR algorithm. It is hard to define mathematically the notion of a normal, since that the ball is smooth and the mesh is made of triangles, and there are multiple triangles intersecting the ball... Maybe if you made the green balls bigger the effect would be reduced?

    Also, when a green ball crosses the place where two meshes join, there is quite a lot of disturbance, at least with my modified model. It basically gets stuck for a while and needs more torque to keep turning (I am doing this with a SpaceNavigator 3D mouse). One solution could be to take out some of the material at the corners of the meshes, so that the balls lose contact rather than get stuck. As long as there are enough contact points elsewhere, this should not cause anything to fall through.

    Finally, as heroic as this modeling project is, I wonder what the high-level goal is and whether you can achieve it by having a 2-DOF slide-hinge joint, introduce joint friction, and a few internal contact points that will cause extra friction under load (i.e. Coulomb friction) so as to mimic jamming to some extent. It would not be perfect of course, but how close to perfect do you need it to be?
  5. The side boxes are frictionless. In "Tool Test - M8 Nut.xml" they are making only sporadically contacts with the thread:
      time      dzpos  turn  cforce  target  angvel  error  torque     side 0     side 1
         s          m            mN  angvel  mrad/s     ±%     mNm  thread 13  thread 13
    0.0965   0.000002    L        1   16000   14875     -8      15      0 0 0      0 0 0
    0.0970   0.000002    L        0   16000   16971      6      15                     
    0.0975   0.000002    L        0   16000   15542     -3      15                     
    0.0980   0.000001    L        0   16000   16212      1      15                     
    0.0985   0.000001    L        1   16000   17305      8      15                     
    0.0990   0.000001    L        1   16000   15343     -4      15                     
    0.0995   0.000001    L        2   16000   16223      1      15                     
    0.1000   0.000001    L        2   16000   15513     -3      15                     
    0.1005   0.000002    L        3   16000   16449      3      15                     
    0.1010   0.000002    L        1   16000   15670     -2      15                     
    0.1015   0.000002    L        3   16000   15875     -1      15                     
    0.1020   0.000002    L        1   16000   16317      2      15                38 0 0
    0.1025   0.000001    L        0   16000   11711    -37      15                 6 0 0
    0.1030   0.000002    L        1   16000   18267     14      15                 0 0 0
    0.1035   0.000002    L        0   16000   15565     -3      15                     
    0.1040   0.000002    L        0   16000   16753      5      15                     
    0.1045   0.000002    L        2   16000   15780     -1      15                     
    0.1050  -0.000005    L        0   16000   17188      7      15                     
    0.1055   0.000006    L        0   16000   15848     -1      15                     
    0.1060   0.000001    L        1   16000   16184      1      15                     
    0.1065   0.000001    L        0   16000   15833     -1      15                     
    0.1070   0.000002    L        0   16000   16542      3      15                     
    0.1075   0.000002    L        3   16000   15865     -1      15                     
    0.1080   0.000002    L        5   16000   16014      0      15                     
    0.1085   0.000001    L        1   16000   14528    -10      15                     
    0.1090   0.000001    L        1   16000    9987    -60      16                     
    0.1095   0.000002    L        1   16000   14466    -11      16                     
    0.1100   0.000002    L        2   16000   13802    -16      16                     
    0.1105   0.000002    L        1   16000   13475    -19      17                     
    0.1110   0.000002    L        1   16000   17438      9      16                     
    0.1115   0.000001    L        1   16000   18026     13      16                     
    0.1120   0.000001    L        1   16000   17918     12      16                     
    0.1125   0.000001    L        1   16000   17353      8      16                     
    0.1130   0.000002    L        1   16000   17110      7      16                     
    0.1135   0.000002    L        3   16000   17527     10      16                     
    0.1140   0.000002    L        3   16000   16792      5      16                     
    0.1145   0.000002    L       13   14034   16753     19      15                     
    0.1150   0.000002    L        4   16000   15458     -4      15                     
    0.1155   0.000002    L        5   16000   17330      8      15                     
    0.1160   0.000002    L        4   16000   15919     -1      15                     
    0.1165   0.000002    L        5   16000   16405      3      15                     
    0.1170   0.000002    L        5   16000   16568      4      15                     
    0.1175   0.000002    L        1   16000   16127      1      15                     
    0.1180  -0.000005    L        1   16000   18674     17      15                     
    0.1185   0.000006    L        1   16000   15037     -6      15                     
    The 38 and 6 N contact lasts only 1 ms, that's why it doesn't get displayed and I couldn't see it. At the same time, angvel drops from 16 to 11 rad/s, so it may be the reason for the jerky rotation in loose mode. There is a setting "play_sides = D * .001" in "visible M8 nut.scad". Changing it to "play_sides = 1" increases the space between the thread and the sides to 1 mm. It is now impossible to make a contact over such a large distance and the log doesn't list any more of them. Nevertheless rotation still gets smoother when the side boxes are commented out. So when it's not the contacts, what is it then?

    Those side boxes are also responsible for the mass of the nut -- the mesh is just visual. After removing them, the attribute mass="1e-9" in the line above must be removed, too. And voilá, the jerks are back again -- stronger as before. The simulation in loose mode is now so unstable that the nut sometimes jumps up and down for several millimeters.

    The green friction balls are only there to prevent the nut from rotating by itself in loose mode because of gravity. Their forces are below 0.5 N. Maybe their influence is so big in your modified model because the nut has no mass there.

    IMHO, replacing the free joint by a slide and a hinge joint is cheating. I want function and no cheap show effects. These joints also cause sporadic jumps along the z-axis (dzpos) which are not there with the free joint.

    The high-level goal is to replace my human body with a machine body. Because it hurts. I hate it. I don't want to be a stupid genetic slave. Intelligence should not be chained to the genes. Genes are bad masters. I believe that the universe, which is the boss of the genes, is a better master.

    As artificial intelligence does not exist yet, and robotics is the key to AI, and I cannot afford real hardware, and simulation allows normal PC users to experiment both with humanoids in the price range of $1M and full skin that will not be available before 2026, and I was a Windows programmer since the Nineties, and Gazebo is Linux and disqualifies itself with that 3D model boxing link on their homepage, I'm here with MuJoCo.