Sim-to-Real Troubleshooting¶
A cookbook of symptoms → likely causes → fixes. When a deployment goes sideways, start here.
High-frequency joint oscillation / “buzz”¶
Likely cause |
Check |
Fix |
|---|---|---|
State estimator velocity bias |
Log |
Tune the state estimator |
PD gains too high vs trained |
Compare driver Kp/Kd against owner YAML |
Match training values; or retrain with realistic Kp/Kd DR |
Action latency too low in training |
Sweep |
Retrain with measured-latency × 1.5 |
Velocity noise too low |
Compare encoder σ in sim vs hardware |
Increase |
Drift while standing / walking¶
Likely cause |
Check |
Fix |
|---|---|---|
IMU bias not calibrated |
Robot static, check |
Run 30-second calibration before policy start |
Foot contact misclassified |
Check contact event timestamps |
Hysteresis on contact force threshold |
Policy succeeds in sim, falls on hardware immediately¶
Almost always one of:
Joint order swapped. Inspect
policy.onnxinput width and the joint order in your motor driver. Useunilab-export-sceneto dump the training joint order.Action scale unit mismatch. Policy outputs unscaled values; the driver expects rad, but you fed it normalized [-1, 1]. Apply the
env.actions.joint_pos.scale/ default-angle convention from the training owner YAML before sending targets to the driver, reproducing the owner’s resolved per-actuator scale exactly.Observation layout mismatch. Compare what your hardware loop assembles against the owner’s
env.observations.actor.terms— term order first, then per-term history ordering.
Cube drops in Allegro inhand¶
Likely cause |
Check |
Fix |
|---|---|---|
Friction mismatch |
Real cube vs sim μ |
Sweep friction DR wider, retrain |
Grasp distribution mismatch |
Log operator grip poses |
Augment grasp generator |
Pose estimator latency |
Measure vision pipeline ms |
Add observation lag DR |
Policy succeeds in MuJoCo but fails in Motrix (or vice versa)¶
That’s a sim-to-sim problem, not sim-to-real. See Aligning Contact and Friction Between Backends and Reward Parity Across Backends.
What to capture before opening a bug report¶
When the lab WhatsApp blows up at 11 pm, save the following so the investigation tomorrow takes 30 minutes instead of 4 hours:
Full hardware trace (
obs / action / wall_clockfor the entire run).Sim-side YAML used to train:
runs/<run>/config.yaml.policy.onnxand the exact task owner YAML path it was trained from.One sim rollout video using the same seed:
eval --seed <same> --render-mode record.A
git diffbetween the run’s commit andmainif any.