Selecting and Tuning Physics Engines for Contact-Rich Gazebo Simulations
A decision guide for choosing and tuning Gazebo physics engines (ODE, Bullet, DART, Simbody) to resolve jitter and instability in contact-rich robot simulations.
12 Oct 2025, 02:56 UTC

The Challenge of Contact Fidelity
In robotics simulation, a common failure point is the "jitter" or "tunneling" (objects passing through each other) that occurs during high-impact contacts or complex manipulation. This usually stems from a mismatch between the physics engine's solver constraints and the robot's physical properties, such as stiff actuators or low-inertia links.
The primary goal is to balance Real-Time Factor (RTF)—the ratio of simulation time to wall-clock time—against the stability of contact forces. Choosing the wrong engine or leaving default solver parameters often leads to unstable simulations that do not translate to real-world hardware behavior.
Comparing Gazebo Physics Engines
Depending on your version of Gazebo (Classic or the modern gz-sim/Ignition), you have access to different physics backends. The choice depends on whether you prioritize raw speed, multi-body stability, or biomechanical accuracy.
| Engine | Primary Strength | Trade-off | Best Use Case |
|---|---|---|---|
| ODE | High performance / Low latency | Can jitter with high stiffness | Simple mobile robots, fast prototyping |
| Bullet | Robust cluttered contacts | Slower than ODE in simple scenes | Manipulation, grasping, debris |
| DART | Model-based control stability | Requires explicit plugin setup | Legged locomotion, optimal control |
| Simbody | High-fidelity biomechanics | Highest compute cost | Medical robotics, compliant joints |
Tuning the Solver for Stability
Regardless of the engine, the simulation stability is governed by the time step and the solver iterations. If a robot "explodes" upon contact, the first step is usually to decrease the max_step_size and increase the iters (iterations).
Key Parameter Definitions
- ERP (Error Reduction Parameter): Determines what fraction of a joint or contact error is corrected in the next simulation step. Higher values make contacts feel "stiffer" but can cause oscillations.
- CFM (Constraint Force Mixing): Adds a small amount of compliance to the constraint. A non-zero CFM prevents the solver from crashing when encountering mathematically "impossible" constraints.
- Max Step Size: The temporal resolution of the simulation. For high-speed impacts, 1ms (0.001s) is standard; highly dynamic systems may require 0.1ms.
Implementation: Configuring the World SDF
To apply these settings, modify the <physics> block in your world SDF file. The following example configures the ODE engine for a balance between stability and performance.
<sdf version='1.6'>
<world name='default'>
<physics name='stable_physics' type='ignored'>
<engineprecipitation>
<ode>
<max_step_size>0.001</max_step_size>
<real_time_factor>1.0</real_time_factor>
<solver>
<type>quick</type>
<iters>100</iters>
</solver>
<constraints>
<contact>
<erp>0.2</erp>
<cfm>0.00001</cfm>
</contact>
</constraints>
</ode>
</engineprecipitation>
</physics>
</world>
</sdf>
Execution and Permissions
Run the simulation using your standard Gazebo launch command (e.g., gz sim world_file.sdf). No root permissions are required for launching, but ensure that the physics plugins (especially for DART or Simbody) are installed via your system package manager (e.g., apt install libgazebo-dart-plugin) before attempting to switch engines.
Validation: The Drop Test
To verify if your physics settings are appropriate for your robot's mass and stiffness, perform a controlled drop test before integrating the full robot model.
- Setup: Create a minimal world with a ground plane and a 1 kg primitive cube placed 1 meter above the plane.
- Observation: Launch the simulation and observe the impact.
- Metrics:
- Penetration Depth: Does the cube sink into the floor? If yes, increase
itersor decreasemax_step_size. - Settling Time: Does the cube bounce indefinitely or jitter? If yes, lower the
erpor increasecfm. - RTF Check: Monitor the simulation clock. If the RTF drops significantly below 1.0, you may need to reduce the solver iterations.
- Penetration Depth: Does the cube sink into the floor? If yes, increase
Verification Command
To capture the average step time without the overhead of the GUI, run the simulation in headless mode:
gz sim -s -r --iterations 1000 world_file.sdf
Check the terminal output for the average simulation step time. If the time per step exceeds your max_step_size, your simulation will lag behind real-time.
Limitations and Risks
Reducing the step size increases the CPU load linearly. On edge devices or limited hardware, a 0.1ms step size may make the simulation unusable. Additionally, avoid using extremely high ERP values (e.g., > 0.8) with stiff joint controllers, as this often creates a positive feedback loop that leads to numerical instability and "exploding" models.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.