Simulation and Digital Twins
Gazebo, Webots, CoppeliaSim, Isaac Sim and MuJoCo compared; URDF models, physics step size and stability, and closing the sim-to-real gap.
On this page
- Why simulate
- The simulators compared
- Describing the robot: URDF and SDF
- Mass and inertia: the numbers that matter
- Physics engines: step size, contact and stability
- Simulation speed: the real-time factor
- Simulated sensors and noise
- Closing the gap between simulation and reality
- Simulation for testing and learning
- Digital twins
- FAQ
Why simulate
- Safety and cost: a crash in simulation costs nothing, and a gripper that would break a part just resets.
- Speed of iteration: test a change in minutes, run many cases in parallel, and run faster than real time.
- Repeatability: the same scenario every time, with exact ground truth for every quantity, which a real robot never gives you.
- Before the hardware exists: test the software, check reach and clearances, and size motors.
- Automated testing: run the navigation stack against hundreds of maps on every code change (see Software Practice).
- The limits: a simulation is a model, and it is wrong in ways you cannot predict. Treat it as a way to find bugs and bound behavior, not as proof that the real robot works.
The simulators compared
| Simulator | Strengths | Notes |
|---|---|---|
| Gazebo (Harmonic and later) | The standard with ROS 2; mobile robots, arms, sensors, worlds; plugin architecture | Open source; physics through DART, Bullet and others; many ready-made robot models and worlds |
| Webots | Easy to start; many built-in robots; runs on all major systems; good documentation | Open source; ROS 2 interface available |
| CoppeliaSim | Flexible scene building, strong for arms, grippers and conveyors, many languages and engines | Free for education; commercial license for companies |
| NVIDIA Isaac Sim | Photo-realistic sensors, synthetic data, GPU physics, large scenes | Needs a capable NVIDIA GPU; ROS 2 bridge |
| MuJoCo, PyBullet, Isaac Lab, Genesis | Fast, accurate contact physics for learning-based control; thousands of parallel environments | Usually used from Python; see Machine Learning |
| Vendor offline programmers | RobotStudio (ABB), ROBOGUIDE (FANUC), KUKA.Sim, RoboDK (many brands) | Simulate a specific industrial robot and its controller; export real robot programs (see Industrial Robotics) |
| Unity and Unreal | Visual realism, human interaction, VR | Weak physics for robotics unless supplemented; useful for perception data |
Describing the robot: URDF and SDF
A robot is described by links (rigid bodies, each with a shape, a mass and an inertia) joined by joints (fixed, revolute, continuous, prismatic) in a tree. The URDF (Unified Robot Description Format) is the ROS format; SDF is Gazebo’s richer format, which can describe whole worlds. Use xacro (XML with macros and parameters) so that a wheel is written once and used twice.
<robot name="diff_bot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<link name="base_link">
<visual><geometry><box size="0.30 0.20 0.10"/></geometry></visual>
<collision><geometry><box size="0.30 0.20 0.10"/></geometry></collision> <!-- simple shapes: fast and stable -->
<inertial>
<mass value="5.0"/>
<inertia ixx="0.0208" iyy="0.0417" izz="0.0542" ixy="0" ixz="0" iyz="0"/>
</inertial>
</link>
<xacro:macro name="wheel" params="name y">
<link name="${name}_wheel">
<collision><geometry><cylinder radius="0.05" length="0.03"/></geometry></collision>
<inertial><mass value="0.5"/><inertia ixx="0.00035" iyy="0.00035" izz="0.000625" ixy="0" ixz="0" iyz="0"/></inertial>
</link>
<joint name="${name}_wheel_joint" type="continuous">
<parent link="base_link"/><child link="${name}_wheel"/>
<origin xyz="0 ${y} -0.03" rpy="-1.5708 0 0"/><axis xyz="0 0 1"/>
</joint>
</xacro:macro>
<xacro:wheel name="left" y=" 0.10"/>
<xacro:wheel name="right" y="-0.10"/>
</robot>
- Separate visual and collision shapes: a detailed mesh for looks, a few boxes, cylinders and spheres for collisions (fast and stable).
- Units are SI, and angles are radians; frames follow REP 103 (see Frames, Transforms and Arm Kinematics).
- Check it:
check_urdf,urdf_to_graphvizand RViz show the tree and the frames; move each joint by hand withjoint_state_publisher_gui. - One description for everything: RViz, the simulator, the planner and the real robot’s
robot_state_publisherall read the same file.
Mass and inertia: the numbers that matter
The simulator needs each link’s mass and inertia tensor, and wrong values make a robot behave like a toy. Use the textbook formulas for simple shapes, or read them from CAD:
| Shape (mass m) | Ixx | Iyy | Izz |
|---|---|---|---|
| Box (x × y × z) | m (y² + z²) ÷ 12 | m (x² + z²) ÷ 12 | m (x² + y²) ÷ 12 |
| Solid cylinder (radius r, length h, axis z) | m (3 r² + h²) ÷ 12 | m (3 r² + h²) ÷ 12 | m r² ÷ 2 |
| Solid sphere (radius r) | 2 m r² ÷ 5 | 2 m r² ÷ 5 | 2 m r² ÷ 5 |
Worked example: the diff-bot in the URDF
- Body: a 5 kg box 0.30 × 0.20 × 0.10 m: Ixx = 5 × (0.20² + 0.10²) ÷ 12 = 0.0208, Iyy = 0.0417 and Izz = 0.0542 kg·m².
- Wheel: a 0.5 kg solid cylinder, r = 0.05 m, h = 0.03 m: Izz (about the axle) = 0.5 × 0.05² ÷ 2 = 0.000625, and Ixx = Iyy = 0.5 × (3 × 0.05² + 0.03²) ÷ 12 = 0.000350 kg·m².
- Why it matters: the wheel’s Izz sets how fast the motor can accelerate it; an inertia ten times too large makes the simulated robot sluggish, one that is zero crashes the solver.
- Common mistakes: mass in grams instead of kilograms, an inertia copied from a different body, center of mass off-center, and a tiny mass on a link that carries a heavy one (the solver oscillates).
Physics engines: step size, contact and stability
A physics engine advances the world in small time steps: it computes forces, integrates the motion, detects collisions and resolves the contacts. The step size is a trade between accuracy, speed and stability. Stiff things (contacts, high-gain controllers, springs) force small steps.
Worked example: a stiff contact and the step size
- A wheel resting on the ground is modeled as a spring: k = 1.00e+5 N/m under m = 1 kg. Its natural frequency is ω = √(k ÷ m) = 316 rad/s (50.3 Hz).
- An explicit integrator (semi-implicit Euler, as in most engines) is stable only if the step is below 2 ÷ ω = 6.3 ms. Starting with a 1 cm compression and simulating one second:
| Step | Steps per second | Largest displacement | Result |
|---|---|---|---|
| 1.0 ms | 1 000 steps/s | 1.01e-2 m | stable |
| 3.0 ms | 333 steps/s | 1.14e-2 m | stable |
| 6.0 ms | 167 steps/s | 3.16e-2 m | stable |
| 6.5 ms | 154 steps/s | 7.25e+29 m | unstable: grows without bound |
| 10.0 ms | 100 steps/s | 4.71e+87 m | unstable: grows without bound |
Beyond 6.3 ms the motion explodes, which is how a robot “shakes itself apart” in a simulator. Real engines add damping and constraint-based contacts (soft constraints) to allow larger steps, but the rule stands: the step must be small compared with the fastest dynamics, and a stiffer model needs a smaller step.
- Typical step sizes: 1 ms for robots with stiff joints and contacts; 2 to 5 ms for mobile robots and light arms; the controller loop must be an exact multiple of the physics step.
- Collision shapes: primitives and convex hulls are fast and stable; triangle meshes are slow and can snag. Leave a small margin (a few millimeters) so that resting contacts do not jitter.
- Friction and restitution matter more than anything for wheels and grasps: rubber on concrete is about 0.8 to 1.0, plastic on metal 0.2 to 0.4. Check them against a measurement.
- Joint limits, damping and friction in the URDF reflect the real joint; an undamped simulated joint swings far longer than a real one.
- Engines differ: the same robot can behave differently in two engines; try another before blaming your controller.
Simulation speed: the real-time factor
Worked example: real-time factor
The real-time factor (RTF) is simulated time divided by wall-clock time. With a 1 ms step costing 0.4 ms of computing, RTF = 1 ÷ 0.4 = 2.5: the simulation runs 2.5 times faster than real time. With a heavy scene at 2.5 ms per step the RTF is 0.40: a 60 s test takes 150 s. For a test suite, headless (no graphics) and as fast as possible; for development, near 1.0 so that you can watch.
- Run headless in CI (
gz sim -s -r), and in parallel containers. - Use simulation time (
use_sim_time:=true) in every node, so that a slow simulation does not break timeouts; the simulator publishes/clock. - Fewer, simpler objects and lower sensor rates (a lidar at 10 Hz, a camera at 15 Hz) raise the RTF the most; cameras and 3D lidar are the expensive sensors.
- Determinism: fix the random seeds so that a failure can be repeated.
Simulated sensors and noise
A simulated sensor returns perfect data unless you add the imperfections of the real one. The usual models are: Gaussian noise on each measurement, a slowly varying bias (an IMU’s gyroscope drifts), quantization, dropouts, latency and a limited range and field of view.
| Sensor | What to model | Typical values |
|---|---|---|
| 2D lidar | Range noise, dropouts on dark or shiny surfaces, minimum and maximum range, scan rate | σ = 0.01 m (0.2 % at 5 m), 5 to 15 Hz, 0.15 to 12 m |
| Camera | Resolution, field of view, exposure, motion blur, lens distortion, noise, rolling shutter | 640×480 to 1920×1080, 15 to 60 fps |
| Depth camera | Noise growing with distance squared, holes at edges, range limits | See Perception |
| IMU | Gyroscope and accelerometer noise density and bias random walk | Gyro bias 1 to 10 °/h (good) up to hundreds (cheap MEMS) |
| Wheel encoders | Quantization, slip, backlash | 360 to 4 096 counts per revolution |
| GNSS | Position noise, jumps, outages near buildings | 1 to 3 m (standard), 2 cm with RTK |
Closing the gap between simulation and reality
- Identify and measure the real robot: wheel diameter, track width, mass, center of mass, motor constants, friction and latency; put them in the model.
- Add delay and noise to the simulation so that controllers tuned there are not tuned for an ideal world: a controller that works only without delay will fail on hardware.
- Domain randomization: randomize the parameters you are unsure about, within a range, every run. If friction is 0.8 ± 40 % (here 0.48 to 1.12), a controller that works across the range is robust to the real value.
- Use the same interfaces, topics, message types and frame names, so the code is unchanged between simulation and hardware.
- Retune on the real robot at low speed, and compare logs of the same maneuver: where the simulation and the bag disagree, the model is wrong.
- Validate the simulation against reality, not only the robot against the simulation: drive a known path in both and compare.
- Do not tune to the simulator’s quirks: a trick that exploits a simulation artifact will fail outside it.
Simulation for testing and learning
Worked example: a parameter sweep
A navigation test with 3 × 4 × 3 × 5 values of four parameters (map, start pose, obstacle layout, noise level) has 180 cases. At 2 s each in a headless simulator that is 6 minutes of computing, about 0.8 minutes on eight parallel workers. Run it on every change and fail the build if the success rate drops: the cheapest regression test a robot can have.
- Scenario files: maps, start and goal poses and events written as data, so that tests are repeatable and reviewed.
- Pass-fail metrics: reached the goal, time, path length, minimum distance to obstacles, collisions, emergency stops.
- Replay bags into perception and localization code to test them on real data (see ROS 2 in Practice).
- Learning-based control: reinforcement learning needs millions of trials: use GPU-parallel engines (Isaac Lab, MuJoCo, Genesis) and randomization, and expect the policy to need adaptation on hardware.
- Synthetic data: a simulated camera renders labeled images for training detectors: 108 000 frames (an hour at 30 fps) of 640 × 480 color is 99.5 GB raw, so store compressed.
Digital twins
A digital twin is a simulation kept in step with a real machine by live data: it mirrors the real state, so that you can monitor it, predict what comes next, test a change on the twin before applying it, and replay a failure. For a robot cell that means the CAD-accurate model, the real I/O and joint states streamed into it, and the same program running on both. The value depends on how well the model is validated, so start with a narrow question (does the new tool collide? what is the cycle time?) and measure the twin against the machine.
Related
- Robotics Tools: the overview of this guide.
- ROS 2 in Practice: the graph that runs in both simulation and hardware.
- Frames, Transforms and Arm Kinematics: frames and joints in the URDF.
- Building, Testing and Safety: the real robot after the simulation.
- Numerical Methods: integrators, stability and step size.
FAQ
Which simulator should I start with?
Gazebo if you use ROS 2 for a mobile robot or arm; Webots for the gentlest start; MuJoCo or Isaac Lab for reinforcement learning; the maker’s tool (RobotStudio, ROBOGUIDE, RoboDK) for an industrial robot.
Why does my robot jitter or explode in the simulator?
Usually a step that is too large for a stiff contact or joint, wrong inertia (too small or zero), colliding shapes that overlap at the start, or an over-aggressive controller. Reduce the step, check the inertias and simplify the collision geometry.
How accurate must the simulation be?
Accurate enough to answer the question you ask it. Navigation logic needs approximate dynamics and realistic sensors; grasping and contact-rich tasks need careful friction and geometry; a controller’s final tuning is always done on the real robot.
Can I trust a controller tuned in simulation?
As a starting point, yes. Expect to retune on hardware: friction, delay, backlash and noise are worse in reality, and add them to the simulation to narrow the gap.
References
- Gazebo, Webots, CoppeliaSim and MuJoCo documentation; the URDF and SDF specifications; REP 103.
- Tobin, J. et al., “Domain randomization for transferring deep neural networks from simulation to the real world”, IROS, 2017.
- Featherstone, R., Rigid Body Dynamics Algorithms; Murray, R. M., Li, Z. and Sastry, S. S., A Mathematical Introduction to Robotic Manipulation.
Last reviewed: October 2026. Stability limits and timings are computed in the page builder for the example values: your engine and model will differ.
