Gazebo reports a realtime factor (RTF) at the bottom of the GUI — the ratio of simulated time to wall-clock time. RTF of 1.0 means the sim is running at real-world speed; RTF of 0.5 means simulation is running half as fast as reality. For interactive debugging this is annoying; for RL training, low RTF directly multiplies training time. A 1k-episode training run that takes 12 hours at RTF=1.0 takes 24 at RTF=0.5.
There are five common culprits, in order of frequency:
1 — Too many sensor plugins
Each sensor plugin in Gazebo costs cycles. Six VL53L0X plugins at 25 Hz, one TF-Luna at 100 Hz, one PMW3901 at 60 Hz, a camera at 30 Hz — they add up. The 2D laser-scan plugin in particular is expensive because it raycasts a fan every tick.
Diagnostic: disable plugins one at a time in your model.sdf and check RTF. The one that recovers the most is the culprit.
Fix: lower sensor publication rates (most sensors don’t need 100 Hz; 50 Hz is fine for indoor) or disable plugins that aren’t critical for the current experiment.
2 — GPU not actually being used
If Gazebo’s GPU acceleration isn’t engaging, the renderer fall back to CPU rasterization which is dramatically slower.
Diagnostic: nvidia-smi while Gazebo is running. If you see no gz sim processes attached to the GPU, GPU acceleration isn’t working.
Fix: check NVIDIA driver version (Gazebo Harmonic wants ≥535), check LIBGL_ALWAYS_SOFTWARE isn’t set, check the X server has GPU access.
3 — Physics step too small
Gazebo’s default physics step is 1 ms (1000 Hz). For most quadcopter simulation, 4 ms (250 Hz) is more than enough fidelity and runs ~4× faster.
Diagnostic: gz topic -e -t /world/<name>/clock and check the per-second step count.
Fix: in the world .sdf:
<physics name="default_physics" default="0" type="dart">
<max_step_size>0.004</max_step_size>
<real_time_factor>1.0</real_time_factor>
</physics>
4 — Headless render still running
If you start Gazebo without --headless, the GUI takes a significant chunk of GPU even if you’re not looking at it. RL training doesn’t need the GUI.
Diagnostic: gz sim running with -s (server-only) vs the default.
Fix: always run training in headless mode: ./help_scripts/launch.sh --headless.
5 — Other processes hogging CPU
Trivial but worth checking — if htop shows another process at 100% CPU, that’s competing with Gazebo.
Fix: kill the competing process, or nice it down.
Where to go next
- Custom motor physics plugin — what we changed in the physics engine
- Simulation hub — what’s running on top of Gazebo
- Troubleshooting hub — sibling diagnostic pages