On the Sim-to-Real Gap

Oct 22, 2026
•
15 min read

Key takeaways

  • The sim-to-real gap almost always traces back to one of three buckets: dynamics, perception, or task distribution.
  • Domain randomization hedges against the sim-to-real gap by widening the training distribution, but randomizing everything wastes capacity and can produce a worse, overly conservative policy.
  • Before blaming the sim-to-real gap, measure the simulation success rate with a confidence interval, since nine successes in ten rollouts is consistent with anything from about 56% to 99.7%.
  • Five hardware failure patterns, from early-step action collapse to workspace degradation, each point to a specific subsystem and a cheap check that localizes the sim-to-real gap.
  • Offline checks on sim and real frames, such as raw image statistics, embedding centroid distance, and linear probes, can find observation-side sim-to-real bugs without moving the robot.

The problem

Locomotion made this look solved

At CoRL 2021, an ETH Zurich and NVIDIA team put an ANYmal quadruped on stage beside a single workstation and launched training live during the talk, running thousands of simulated robots over varied terrain in Isaac Gym. Every 15 seconds, roughly 8 hours of simulated time, the latest policy was pushed to the physical robot. Within minutes, the robot was walking. Since then, quadruped locomotion has largely been considered solved.
Yet anyone who has worked on tabletop manipulation knows the more typical ritual: days of training in simulation, a huddle around the emergency stop (E-stop), and a first eval run in which a multi-thousand-dollar arm sweeps down with precision, closes cleanly on the mug, and lifts it just far enough to watch it slide out of its fingers.
But why is that the case?
Fundamentally, it's about how forgiving these tasks are of wrong assumptions. Think about how often you have misjudged the last step of a staircase without ending up on the floor. Now think about the last time you picked up a glass without realizing it was wet, and how quickly it left your hand. In both cases you could see perfectly well. The difference is not sensing. It is what a wrong contact model costs you. A quadruped has twelve actuated joints, several feet sharing the load, a gait in which every step is a new chance to place a foot, and a control loop fast enough to correct a bad one on the next stride. Contact error here is absorbed by the redundancy in the quadruped design. Manipulation, on the other hand, concentrates the whole task into one or two contact patches with no redundancy behind them. The friction coefficient at the fingertip is not a disturbance on the task. It is the task.
The same pattern shows up beyond robotics: methods succeed first where the domain forgives their assumptions. Across 155 deterministic benchmark Markov decision processes (MDPs), deep reinforcement learning (RL) tends to succeed where a task needs little lookahead beyond the random policy's Q-values. The environment's structure did the work, and the field credited the method. Sim-to-real cleared locomotion because locomotion is cheap to be wrong about.

The sim-to-real gap and domain randomization

When a policy trained in simulation fails on hardware, we blame the sim-to-real gap. The cause is almost always in one of three buckets. Dynamics: contact and friction models, link masses and inertias, joint damping, actuator lag and torque limits, transmission compliance, controller gains, and control rate. Perception: lighting and shadows, material textures and reflectance, background and table appearance, camera pose and intrinsics, exposure and white balance, depth noise and dropout on reflective surfaces. Task distribution: object pose and orientation ranges, object instances and their geometry, mass and size variation, clutter and distractors, workspace coverage of initial states, goal placements, and episode length or horizon.
Domain randomization is the standard response to the sim-to-real gap, and it works often enough to be the default. Randomize textures and lighting widely enough, and a detector trained without a single real image transfers to real scenes. Randomize masses and friction, and a pushing policy transfers to a physical arm.
What domain randomization is really doing is widening the training distribution until the real world falls inside it. It works because policies, whether trained by imitation or by RL, are reliable mostly on the states their training actually covered and degrade as deployment drifts away from that support.
Widening the distribution hedges against all three buckets at once. That is also its blind spot. Randomize all three together and capacity goes to variation that does not matter, and past a point you get a worse policy, one that has learned the conservative behavior fitting every unnecessary variation you added rather than the one that does the task well.
So after a zero-shot failure, the way forward is not more randomization. It is finding out, as cheaply as possible, which bucket you are in.

Before you diagnose

Get the setup right

Everything below assumes the unglamorous part is done. Your Unified Robot Description Format (URDF) file should carry measured masses, inertias, joint limits, and damping, not rounded spec-sheet values. Objects should match on geometry and texture, cameras on intrinsics and extrinsics, and those should be rechecked, since a bumped camera mount quietly undoes a good calibration. The action space, control frequency, and low-level controller should be identical in both places, since a policy trained against a 50 Hz position interface and deployed on a 200 Hz torque interface is not the same policy.
This matters because the items above are all specification problems, and a simulator reproduces them faithfully once you specify them faithfully. However, not everything in the dynamics bucket is like that. Friction and compliance are not parameters you look up and enter. They emerge from surface roughness and material deformation that no simulator resolves directly, which is why contact is the one place where careful setup still leaves you short. Collins et al. found that five physics engines modeled kinematics and control accurately against motion capture, with their deficits concentrated in dynamic robot-object interaction.
This setup work does not close the gap. It stops you from misattributing an avoidable error to an unavoidable one.

Establish the simulation number first

The cheapest check is the one people skip: the policy's simulation success rate, with a confidence interval. Nine of ten rollouts is not a 90% policy. The exact 95% interval runs from about 56% to 99.7%. Nine hundred of a thousand gives roughly 88% to 92%, and only that supports "it works in sim but not on hardware." Otherwise, a 40% hardware rate might be a reality gap, or a policy that was never as good as you thought, and you are about to spend a month debugging physics to explain a training problem. Run enough rollouts, in sim and on hardware, that both intervals are narrower than the drop you are trying to explain.

Order your evaluations by how much the task forgives

Karpathy's advice for debugging neural networks is to start simple and add complexity one piece at a time. The hardware version is to rank tasks by how much positional and force error they tolerate. Centimeter clearance and millimeter insertion are not two points on one difficulty curve. They are different diagnostic instruments. Start with the forgiving one. If it also fails, the problem is upstream of precision contact. If it succeeds and the tight one fails, you have localized the gap to precision-critical dynamics.

Diagnosing the sim-to-real gap

A taxonomy of hardware failures

With a trustworthy simulation number and a forgiving-to-tight task ordering, a hardware failure stops being an anecdote and becomes evidence: how and where the policy fails narrows the cause far more than whether it fails. The five patterns below cover a lot of what we see. Two trace back to the observation side, two to dynamics, and one sits between calibration and task coverage. For each, we give the observed failure, its likely cause, and a check.

Pattern 1: Early-step action collapse

Observed failure: The policy emits degenerate or near-constant actions from the first step, before any meaningful motion.
Likely cause: An observation plumbing mismatch between simulation and hardware: wrong normalization statistics, swapped channel order (RGB vs. BGR), a different resize filter, or mismatched proprioceptive units.
Check: Push one recorded real observation and one matched simulated observation through the frozen policy and compare the actions. Then compare the raw tensors using the raw statistics checks in the offline checks section below. A sharp difference means a pipeline bug, fixable without retraining or touching physics. Plumbing defects corrupt every observation identically, so the collapse looks the same in every scene.

Pattern 2: Trajectory tracking lag and offset

Observed failure: The executed trajectory has the right shape, but the end-effector is consistently offset or lags the commands.
Likely cause: Low-level tracking problems, such as controller gains, actuator latency, unmodeled motor dynamics, or a rate mismatch between the policy loop and the motor drivers.
Check: Replay joint command sequences spanning the workspace in sim and on hardware with no policy in the loop, and compare joint tracking error against task tolerance. With perception removed, any discrepancy is a control or dynamics defect. Actuator modeling was a large part of the ANYmal result we opened with: the pipeline learns a network model of the series elastic actuators, which resist analytic modeling.

Pattern 3: Contact transition instability

Observed failure: The policy reaches the object smoothly and fails at contact by slipping, penetrating, or knocking it away.
Likely cause: Inaccurate contact physics modeling in simulation, specifically miscalibrated coefficients of friction, surface compliance, or restitution parameters.
Check: Use the forgiving-to-tight task ordering from earlier. If the forgiving variant succeeds, the tight one fails, and Pattern 2's tracking error is within tolerance, contact modeling is what remains. For a direct test, replay a scripted open-loop grasp or push in sim and on hardware and compare the object's trajectory. Divergence after first contact points to the contact model. For contact-rich tasks, consider adding a simulated tactile or force-torque sensor.

Pattern 4: Visual sensitivity

Observed failure: Success varies across geometrically equivalent scenes. The pose and the reach are the same, but changing the lighting, background, table covering, or object instance flips the outcome.
Likely cause: Perception domain shift. Real images differ from rendered ones in ways training never covered, and whatever reads them, whether a pose estimator or the policy's own visual encoder, has latched onto features that exist only in simulation.
Check: If your policy consumes object poses, replace the perception pipeline on hardware with ground-truth poses from motion capture or fiducials such as AprilTags. A sharp jump in success localizes the gap to the perception stack. End-to-end image policies have nothing to swap, so start offline with the embedding comparison in the offline checks section below, then confirm on hardware by holding the scene geometry fixed and changing one visual factor at a time: lighting, then table covering, then object instance. If a single factor flips the outcome, that is where your visual randomization budget should go. Either way, the diagnostic signal is variance across scenes. Identical failure everywhere points to Pattern 1.

Pattern 5: Workspace inconsistency and spatial degradation

Observed failure: The policy is reliable in one region of the workspace and degrades toward the edges or other quadrants.
Likely cause: Either an incorrect extrinsic transform between camera and robot base, or training data that never covered those regions. Both correlate with position, so the failure pattern alone cannot separate them.
Check: First, reproject known 3D points into both sim and real cameras across a workspace grid. Calibration error is structured, typically growing away from the calibration region, so the error surface is the signature. Then plot your training initial-state distribution on the same grid. If reprojection error is flat and failures fall where coverage is thin, you have a distribution shift, which belongs in your randomization budget. If it grows toward the failing regions, recalibrate before collecting anything else, or new data will bake the offset in.
The five patterns at a glance:
PatternObserved failureLikely causeFirst check
1. Early-step action collapseDegenerate or near-constant actions from the first stepObservation plumbing mismatch, such as normalization, channel order, resize filter, or unitsPush matched real and simulated observations through the frozen policy and compare actions
2. Trajectory tracking lag and offsetRight trajectory shape, but the end-effector is offset or lagsController gains, actuator latency, motor dynamics, or a loop rate mismatchReplay joint commands with no policy in the loop and compare tracking error
3. Contact transition instabilitySmooth reach, then a slip, penetration, or knock-away at contactMiscalibrated friction, compliance, or restitutionReplay a scripted open-loop grasp or push and compare object trajectories
4. Visual sensitivityOutcome flips with lighting, background, table covering, or object instancePerception domain shiftSwap in ground-truth poses, or change one visual factor at a time
5. Workspace inconsistency and spatial degradationReliable in one region, worse toward the edgesBad camera-to-base extrinsics or thin training coverageReproject known 3D points across a workspace grid, then plot training coverage
The five sim-to-real failure patterns, with the observed failure, likely cause, and first check for each.
Real deployments rarely present one cause at a time. Poor calibration and thin edge coverage share an origin, since you set up and validated everything near the center. When a symptom fits two patterns, run both checks rather than picking the likelier one. Fix the causes in the order they contaminate each other: plumbing first, since it corrupts every observation, then tracking and calibration, since both move the gripper somewhere other than where the policy intended, then perception, and contact last.

Offline checks on your observation stack

Patterns 1 and 4 both lead here. Every check below runs offline on paired frames you can collect in an afternoon, with the robot never moving, so run them before any hardware check. Start by distrusting your eyes. The paired sim and real frames in Yardi et al. look near-identical to a person while models separate them cleanly, so a render beside a camera frame tells you nothing about what the encoder sees.
Measure instead. Collect paired sim and real frames of matched scenes, with the same object poses, camera placement, and task state. Push both through your encoder and compute normalized centroid distance between the embedding clouds after a common principal component analysis (PCA) projection. To see the gap directly, you can compute embeddings and a PCA projection with FiftyOne Brain, then color the Embeddings panel by sim or real. If you want to run this on your own frames without setting up infrastructure, you can try Voxel51 for free, no credit card required.
Then freeze the encoder and train a linear probe (a single linear layer) to predict demonstrated actions from the embeddings. Centroid distance tells you whether the encoder separates sim from real. The probe tells you whether it keeps what the policy needs. An encoder can win on the first by discarding everything, so read both as a ranking across candidates, not against a threshold.
Before blaming representations, check raw statistics on the same pairs: per-channel image means and standard deviations, depth percentiles, and joint-by-joint proprioceptive ranges. These take minutes and often explain an embedding gap outright. A channel swap, a different interpolation mode, depth in millimeters versus meters, or a normalization constant from the wrong dataset shows up as a clean offset.
Finally, check detections. If simulation gives the policy ground-truth poses or masks and hardware gives it a learned detector, those are different inputs, not noisy versions of one input. Ground truth degrades gracefully under occlusion, while an open-vocabulary detector such as Grounding DINO can drop the object or latch onto a neighbor. Run your real detector on your simulated frames and compare against ground truth. Any gap is self-inflicted and fixable without touching physics, either by training on detector output in sim or by aligning the two interfaces.

What each diagnosis buys you

Localization first tells you whether randomization is the right tool at all. Plumbing mismatches and calibration errors (the latter once reprojection confirms them) are bugs, not allocations. Randomizing around a swapped channel or a bad extrinsic spends budget covering an error you could delete, and it works just well enough to keep you from finding it.
For the rest, the symptom decides where the budget goes. Tracking failures call for system identification first, so that randomization is centered on the right values instead of hiding the offset. Contact failures call for a better contact model rather than a wider distribution over a wrong one, and they are where real data pays off most. Perception failures split two ways. If one candidate encoder places sim and real clearly closer while keeping its probe accuracy, swap to it. If every candidate keeps them far apart, the difference lives in the images, so spend on visual randomization or better rendering. Coverage failures, with flat reprojection error and failures where demonstrations are thin, are the one case where randomization is the direct answer, as long as it targets the failing regions or comes with new demonstrations there.
The gap does not close. It localizes. Each check turns a hardware failure into a specific claim about which subsystem is wrong. Most run in an afternoon, and several never touch the robot. Run them before you widen a distribution. Randomization is expensive and, worse, quiet: it covers an error rather than telling you it is there.

Frequently asked questions

Source list

Photo of Mohamad Louai Shehab
Technical Writer
Mohamad Louai Shehab is a postdoctoral researcher in the Robotics Department at the University of Michigan.
See all articles by Mohamad Louai Shehab

Try Voxel51 for yourself

Loading related posts...