Differential-drive + caster under-rotates: achieves only ~50% of commanded yaw at low ω — invariant to friction, drive gain, contact shape

5.1.0

Operating System

Ubuntu 24.04
Ubuntu 22.04

GPU Information

  • Model:RTX 5060
  • Driver Version:580.159.03

Topic Description

I’m trying to build a Digital Twin for my mobile robot, facing the following problem while trying to simulate realistic differential drive behavior

Environment

▎ - Isaac Sim 5.1; CPU dynamics (enableGPUDynamics=False)
▎ - Scene: solverType=TGS, frictionType=patch, frictionCorrelationDistance=0.025,
▎ frictionOffsetThreshold=0.04, enableStabilization=True, collisionSystem=PCM, enableCCD=True, timeStepsPerSecond=60

▎ Robot (URDF import): differential drive — two rear drive wheels (r=0.107 m, mount track 0.618 m)
▎ + one passive centered front caster (r=0.0625 m, trail ~0.042 m, carries ~48% of weight). Mass
▎ 400 kg, base Izz 41 kg·m² (both validated against CAD). Articulation: WheeledRobot +
▎ DifferentialController; each physics step I call
▎ articulation_controller.apply_action(ArticulationAction(joint_velocities=[L,R],
▎ joint_indices=wheel_dofs)).

▎ Drive config: velocity mode (stiffness=0), damping=500 (verified at runtime via get_gains()),
▎ maxForce=400 N·m, joint velocity limit 20 rad/s. Solver iters: position 32, velocity 8.
▎ physics_dt=1/60.

▎ Problem: commanded angular velocity is badly under-achieved while linear velocity tracks ~95%.
▎ Body yaw measured via get_angular_velocity()[2]:
▎ - In-place rotation: achieved/commanded = 0.52 @ ω=0.2, 0.75 @ ω=0.5, 0.79 @ ω= 1.0 (ratio improves with speed).
▎ - Gentle arc (v=0.2, ω=0.2): body yaws ~0.10 rad/s (~52%).
▎ - The physical robot tracks commanded yaw accurately.

▎ Wheel-level telemetry (commanded vs actual joint velocity):
▎ - In-place, low ω: wheels do reach their commanded ± speeds, but the body still under-rotates → wheels are slipping/scrubbing in place.
▎ - In arcs: the outer wheel never reaches its commanded speed (e.g. cmd 2.45 rad/s, actual
▎ ~1.6–1.8 — sits at body forward-rolling speed); inner wheel tracks.

▎ Already ruled out (no measurable change to the yaw deficit):
▎ - Caster wheel μ: 0.8 → 0.2 → 0.02 (near-frictionless)
▎ - Drive-tyre collider width: cylinder height 0.089 → 0.02 m
▎ - Drive wheel collider shape: cylinder → sphere (point contact)
▎ - Drive velocity gain kd: 100 → 500 → 1500 (confirmed applied)
▎ - Drive wheel μ: 0.8 → 1.5
▎ - Drive maxForce: 200 → 400 N·m
▎ - Mass/inertia validated against CAD

▎ Questions:
▎ 1. With wheels tracking their velocity targets but the body under-rotating (in-place), and the outer wheel failing to reach target (arcs) — what governs this slip, independent of friction/contact/gain?
▎ 2. The ratio improving with command magnitude looks stiction-like — could enableStabilization and/or patch friction (frictionCorrelationDistance) be damping low-speed yaw? Recommended scene settings for a velocity-driven wheeled robot?


▎ Can share URDF/USD and a minimal repro. I spent a lot of time trying to get to the bottom of this, i might have missed something fundamental. Kindly help me out in resolving this problem, any new insights are appreciated.

Hi @kbr9112014,

Thanks for the posting this issue. Here are some pointers:

A couple of directions worth checking:

  • Low-speed contact/solver regime.

Ratio improves with speed, invariant to the friction coefficient

Could be an artifact of the solvers residuals. Try raising the physics rate to 120–240 Hz and bumping physxArticulation:solverPositionIterationCount (e.g. 32+).

  • Confirm the slip by logging each drive wheel’s contact-point lateral
    velocity during the turn.

Could you share the URDF + minimal repro you mentioned? With your exact
masses/inertia (Izz=41), COM, and caster geometry if possible — a hand-built model is too sensitive to mass distribution to match your numbers without it.