Accurate collisions for complex meshes

as part of our research project, we want to train robots for industrial assembly tasks. One of these applications is the assembly of gears. I have built a simple test scenario in Create to test the interaction between two gears.

Unfortunately, the collision mesh for the large gear is very inaccurate (see pictures, complex decomposition is used to generate the collision mesh), which leads to unrealistic collision behavior (see video). So far, I have not found a better way to create the collision mesh in Omniverse.
Is there some workaround to create a more accurate collision mesh?

At this year’s GTC I learned about signed-distance-field (sdf) based collisions. This looks very promising for our application. Unfortunately, it is not clear to me how to implement this myself.

I’ve run the Preview scenes in Create, so I know that it is supported in the current Omniverse version. But is it possible to apply sdf-based collisions myself to custom meshes, like the gears in the example? Or will this only be possible in future versions?

Many thanks in advance!

Hi Axel,

SDF collision detection is still an experimental feature but you can test it as follows:

  1. Add the SDF resolution custom attribute to the collision mesh using the script below
  2. On the collision mesh PhysicsMeshCollisionAPI, set the Collider Approximation to Triangle Mesh ("none" is the attribute value).
  3. When you start simulating, it’ll look like the simulation stalled, but it is cooking the SDF data which can take minutes (we don’t have a progress bar for this yet). Do not use exceedingly high resolution as it will take a very long time (and then lots of memory). I had good results with 256-512 so far.

You can also display the SDF using the Physics debug visualization (when sim is running)

The SDF will be stored into the cooked data API after the initial cooking, so subsequent simulations are faster, and you can save individual assets with their SDF data pre-computed (which is what we do for the demos to speedup startup time). See, for example:

(This asset also shows another nice approach: Use group collision filtering and a second convex collider for collisions that can be convex-approximated.)

Hope this helps!

The script to add the custom sdf resolution attribute:

from pxr import Usd, UsdGeom, Sdf
import omni.usd

stage = omni.usd.get_context().get_stage()

prim = stage.GetPrimAtPath("/World/Path/To/Collision/Mesh")

prim.CreateAttribute("physxsdfcollision:resolution", Sdf.ValueTypeNames.Int, True).Set(256)

Hi Philipp,

thanks for the tip, your solution worked great!

The simulation looks much more realistic now.

I also played a bit with the simulation debug visualization. Especially the contact forces are interesting for us. I assume that the length of the contact vector indicates the contact force. What scaling is used for this? If I set the scaling in the simulation debug visualization to 1, does one unit of length (depending on the global setting of meters per unit) equal 1 newton of force?

Hi Axel,

Very nice to see that it is working well for you - thank you for sharing the video!

For the contacts, you should have a look at the contact report tutorials in the physics demo scenes:

Unfortunately, I found that we have a bug with SDF rigid body contact reports causing a crash. But I am looking into it and we will try to fix asap (but it might not be fixed until 2022.2) - I will update you.


1 Like

Hi Philipp,

thanks for the tip!

I have looked into the tutorials and the contact report function seems promising. With a little effort, you can probably extract the forces acting on a body from it.

Too bad it’s currently not working with sdf collisions. Now I have something to look forward to in the next update.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.