Skip to content

Fix: Make lab_sim burner pushable under realistic gripper force#45

Open
davetcoleman wants to merge 1 commit into
mainfrom
fix/lab-sim-burner-movable
Open

Fix: Make lab_sim burner pushable under realistic gripper force#45
davetcoleman wants to merge 1 commit into
mainfrom
fix/lab-sim-burner-movable

Conversation

@davetcoleman
Copy link
Copy Markdown
Member

Root cause

The stirrer body in mujoco_assets/lab_desk/desk.xml had no <inertial>
block — MuJoCo auto-inferred ~9.7 kg from the 0.2×0.4×0.074 m collision box
at default density 1000 kg/m³. Combined with MuJoCo's MAX-rule friction-combine
and the desk's default friction=1.0, the burner-on-desk friction limit (~95 N
from self-weight alone) exceeded any horizontal force a realistic gripper push
produces.

Tutorial 1's Push Button Objective at force_threshold=1000 visibly contacts
the burner top but the burner stays pinned, matching
PickNikRobotics/moveit_pro#19151.

Fix

On the stirrer body:

  • Explicit <inertial mass="1.5"> overrides the 9.7 kg auto-inferred mass.
  • friction="0.3" + priority="1" on the collision geom. priority=1 wins
    the contact-pair friction combine over the desk's default 1.0; without it,
    the MAX rule keeps 1.0 and the burner stays pinned even with low burner
    friction.

Verification

Reverted desk.xml on this branch, restarted the lab_sim agent, re-ran
Push Button at force_threshold=1000 — burner stayed pinned (matching the
bug). Re-applied the fix — burner slides ~26 cm under the gripper's push.

Related: PickNikRobotics/moveit_pro#19151 — will be closed by the
moveit_pro_example_ws submodule-bump PR once that lands.

@L4co77
Copy link
Copy Markdown

L4co77 commented May 21, 2026

Surgical fix with a thorough write-up — root cause (1000 kg/m³ default density + MAX-rule friction combine) is identified, the priority=1 trick is the right idiom for asymmetric friction-combine, and the manual revert → repro → fix → confirm verification is exactly the right shape for a physics-tuning change. LGTM with two small things:

Diaginertia sanity-check. For a homogeneous 0.2 × 0.4 × 0.074 m box at 1.5 kg, the moments work out to roughly:

  • I_xx = (1/12) * 1.5 * (0.4² + 0.074²) ≈ 0.0207
  • I_yy = (1/12) * 1.5 * (0.2² + 0.074²) ≈ 0.00569
  • I_zz = (1/12) * 1.5 * (0.2² + 0.4²) ≈ 0.025

The PR uses 0.008 0.008 0.012 — symmetric in xx/yy and ~half the homogeneous-box I_zz, which suggests the mass is biased toward the center (stirrer base is denser than the visual mesh's extent). That's a plausible model for a real stirrer with its motor concentrated low and a thin top plate, but it's worth noting in the XML comment so future tuners know it's intentionally non-homogeneous rather than a numerical error. One line above the <inertial> along the lines of "diagonal mass distribution biased toward the base; do not regenerate from the collision box extents" would protect against the next person "fixing" it.

damping="1" on the freejoint is a behavior change. Replacing <freejoint/> (no damping) with <joint type="free" damping="1"/> matches the surrounding bodies (pump directly above), so the convention is consistent — but damping limits the slide distance. The PR description's "burner slides ~26 cm" verification is with damping=1; without it the burner would coast further. Worth confirming the 26 cm slide is what the tutorial expects (not too short to feel right under a Push Button) — if it's borderline, tightening to damping="0.5" or dropping it (matching the original <freejoint/>) is one knob.

Otherwise the fix is exactly the right shape for the bug, and the XML comment block explaining priority=1 is a nice touch — that combine rule trips up the next reader and the inline doc helps.

with the desk's default friction=1.0) pins it under any vertical-dominant
gripper push. priority="1" on the collision geom below makes the burner's
lower friction override the desk's, so the burner can actually slide. -->
<inertial pos="0 0 0.02" mass="1.5" diaginertia="0.008 0.008 0.012"/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diaginertia="0.008 0.008 0.012" doesn't match a uniform 1.5 kg box of 0.2×0.4×0.074 m. Computing from the box-of-uniform-density formula (m/12)·(a² + b²):

  • Ixx ≈ (1.5/12) · (0.4² + 0.074²) ≈ 0.0207
  • Iyy ≈ (1.5/12) · (0.2² + 0.074²) ≈ 0.00568
  • Izz ≈ (1.5/12) · (0.2² + 0.4²) ≈ 0.0250

The PR's values are symmetric in X/Y (the X≠Y asymmetry of the box is lost) and ~3× lower than the uniform-density assumption across all axes. Two clean ways forward:

  1. If the rotational response was hand-tuned (e.g. to make the burner spin more snappily under contact), keep the values but add a one-line comment so the next reader doesn't "fix" it back to uniform.
  2. Otherwise, drop diaginertia entirely and let MuJoCo auto-compute from mass + geom geometry — the result matches the physical box.

Not blocking the bug fix (mass + friction + priority is the load-bearing change), but the inertia values are surprising as-written.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with option 1 — added an explanatory block above <inertial> in e6bd41f. The rationale (mass biased toward base for motor + stand under thin top plate, xx/yy intentionally symmetric, all three values below the uniform-box numbers you computed) is inline in the XML now, with a 'do not regenerate from collision box extents' warning for the next tuner.

@davetcoleman davetcoleman force-pushed the fix/lab-sim-burner-movable branch from 75df69b to e6bd41f Compare May 22, 2026 00:56
@davetcoleman
Copy link
Copy Markdown
Member Author

Thanks @L4co77.

1. Diaginertia comment — applied (e6bd41f). Folded an explanation into the existing comment block above <inertial>: mass biased toward the base (motor + stand under thin top plate), xx/yy symmetric, all three values well below the homogeneous-box numbers you computed (~0.0207, ~0.00569, ~0.025), with a "do not regenerate from collision box extents" warning for the next tuner.

2. damping="1" on the freejoint — keeping it. You're right that swapping <freejoint/><joint type="free" damping="1"/> is a behavior change, not just syntax. The 26 cm slide under Push Button at force_threshold=1000 is the bug's acceptance criterion (the burner was previously fully pinned), and it matches the surrounding pump convention. If it turns out to feel too short in the tutorial we can tune down to 0.5 or drop, but that's a follow-up — not blocking this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants