Short answer
For most contact‑rich, real‑time workloads, Bullet is the reasonable default on modern Gazebo releases (Harmonic and later already ship it as the default). Keep ODE as the fallback when a specific world shows contact instability under Bullet, and make the decision from a headless‑measured RTF target of 1.0 or higher on a representative world — not from the GUI's reported number.
Confirmed facts vs. likely explanation
Confirmed: Gazebo 9 and earlier defaulted to ODE; newer Gazebo (the gz generation, e.g., Harmonic) defaults to Bullet. RTF shown in the GUI conflates rendering load with physics cost, so GUI numbers can be misleading in either direction.
Likely, but workload‑dependent: Bullet tends to sustain a higher RTF in contact‑heavy scenes because of its optimized collision pipeline and better use of modern CPUs, while ODE can be more numerically forgiving for certain stiff multi‑body contact configurations. This is a tendency, not a guarantee — results vary with world complexity, contact count, solver iterations, and CPU. Treat any single benchmark as evidence only for the world you tested.
How to decide for your case
- Pick a world that represents your typical contact load (same models, similar contact count).
- Run headless with each engine and record RTF and CPU use:
gz sim -s -r --physics-engine gz-physics-bullet-plugin your_world.sdf\ngz sim -s -r --physics-engine gz-physics-ode-plugin your_world.sdf
(Exact plugin names vary by release; check gz sim --help or your installed gz-physics plugins.) Monitor RTF from the server output or by timing against /clock, and watch CPU with top in parallel.
- Choose the engine that holds RTF ≥ 1.0 with margin (aim for ~1.1+ to absorb load spikes) and produces stable contacts — no jitter, penetration, or energy blow‑up in stacked or grasping scenarios.
Version‑specific trade‑offs
- Gazebo 9 / classic: ODE is the battle‑tested default; Bullet support exists but is less exercised. Switching engines may require re‑tuning solver iterations and contact parameters.
- Harmonic and newer: Bullet is the default and the better‑supported path. ODE remains available via plugin but some ODE‑specific solver options have no direct Bullet equivalent.
- Migration: moving a world across engines (or major versions) usually requires re‑tuning mass, damping, friction, and constraint parameters to reproduce equivalent behavior. Budget validation time for this.
Uncertainty and recommendation
Whether ODE→Bullet yields a measurable RTF gain for your worlds is genuinely uncertain without your benchmark — published tendencies may not transfer. The defensible policy: default to Bullet on current releases, gate the choice on headless RTF ≥ 1.0 on your representative world, and fall back to ODE per‑world when contact stability degrades. If your worlds are dominated by a few stiff, high‑precision contact chains rather than many simultaneous contacts, run the ODE comparison before committing — that is the one case where the answer can flip.