gazebosim / gz-physics

Abstract physics interface designed to support simulation and rapid development of robot applications.
https://gazebosim.org
Apache License 2.0
64 stars 39 forks source link

Slow rate when multiple objects are in constant collision #284

Open joxoby opened 3 years ago

joxoby commented 3 years ago

Hi all,

I have a use case in which multiple objects are in constant collision with each other, e.g. a stack of boxes. The default DART physics engine seems to struggle with this case, slowing down the sim rate (RTF) to 25% on my machine. In contrast, when using the Bullet physics engine (https://github.com/ignitionrobotics/ign-physics/pull/208), the simulation seems to run smoothly at a ~97% rate. Check links to images below:

DART Bullet

What's interesting is that when using DART physics engine but selecting dart::collision::BulletCollisionDetector as the collision detector, the sim still runs slow at a 25% rate. Can anyone provide an explanation, or give some intuition regarding this phenomenon? I would much rather keep using DART with an improved collision detector than completely switch the physics engine.

joxoby commented 3 years ago

Researching more about this, it seems that the main difference between Bullet and DART is in how the dynamics are computed. While DART uses a reduced coordinates approach (which is more precise), Bullet uses maximal coordinates (which is faster). Presentation by Erwin Coumans

However, Bullet does let the user define multibody entities that use reduced coordinates for its dynamics.

The main question is: If Bullet can, at least in theory, provide the precision and speed by supporting both maximal and reduced coordinates, are there any advantages of using DART as the default engine?

azeey commented 3 years ago

The two things I can think of off the top of my head are

joxoby commented 3 years ago

Hi @azeey,

By default, DART uses the Dantzig constraint solver, which is more accurate than the other available solver, but can be slow for a large number of contacts. Can you test with the Pgs solver to see if it helps? (See https://github.com/ignitionrobotics/ign-gazebo/blob/ign-gazebo5/tutorials/physics.md#engine-configuration)

I tried PGS solver, and it actually made the sim slower, to 17% instead of 25%.

The corrective impulses applied when objects penetrate each other might be too small in DART by default. Perhaps tweaking the values in https://github.com/dartsim/dart/blob/71c7cfb97e8b583aa1ada639b6d1cf9a1835c1da/dart/constraint/ContactConstraint.cpp#L62-L63 might help.

I tried tweaking those values, up to x100, resulting in no noticeable impact.

traversaro commented 3 years ago

DART uses a reduced coordinates approach (which is more precise), Bullet uses maximal coordinates (which is faster).

Just a curiosity, where did you find that maximal coordinates are faster? For system with a lot of joints (so different from your use case) reduced coordinates need to integrate a lot less variable and have much less explicit constraint that could lead to faster simulation as well, even if in practice which method is actually faster depend a lot on the system being simulated and the actual code implementation.

joxoby commented 3 years ago

Just a curiosity, where did you find that maximal coordinates are faster? For system with a lot of joints (so different from your use case) reduced coordinates need to integrate a lot less variable and have much less explicit constraint that could lead to faster simulation as well, even if in practice which method is actually faster depend a lot on the system being simulated and the actual code implementation.

I completely agree. My statement was mostly about this specific use case.

mxgrey commented 2 years ago

One possible explanation for the difference is that Bullet is a physics engine meant for video game development, and I believe it's common practice for such engines to skip simulating the physics for objects that have come to rest, until they get perturbed or acted upon by a moving object. If Bullet is using that simulation shortcut, that could easily explain the significant difference, since right now DART does not use any such shortcut.

chapulina commented 2 years ago

skip simulating the physics for objects that have come to rest, until they get perturbed or acted upon by a moving object

As a reference, on SDF that's toggled by the allow_auto_disable flag:

http://sdformat.org/spec?ver=1.8&elem=model#model_allow_auto_disable

That flag is not supported on Ignition Physics right now, but it's possible that this is the default behaviour for Bullet, I haven't checked.

joxoby commented 2 years ago

One possible explanation for the difference is that Bullet is a physics engine meant for video game development, and I believe it's common practice for such engines to skip simulating the physics for objects that have come to rest, until they get perturbed or acted upon by a moving object. If Bullet is using that simulation shortcut, that could easily explain the significant difference, since right now DART does not use any such shortcut.

Yes, I have seen this behavior impacting significantly the RTF of some simulation instances. However, in this specific example, sleeping is disabled: https://github.com/ignitionrobotics/ign-physics/blob/77a6826f7756cd5f9aba150eaa321e9e17e8a04f/bullet/src/SDFFeatures.cc#L180

abstanton commented 2 years ago

Is there a fundamental reason why allow-auto-disable can't be implemented? Also struggling when dealing with a large number of entity collisions, however almost all of them should be static 95% of the time so allow_auto_disable would be a big help for us. If there is no obstacle in the way to implementing it I would be happy to have a look.