ConvolutedLadybug.comLeRobot Experiments

Simulation · Post 5 of 6

SO-101 in MuJoCo with live inverse kinematics

A simulated arm that implements the same Robot interface as the real one.

Hardware time is limited and a wrong command can slam a servo into the table. So we built a MuJoCo version of the SO-101 that can be driven with the keyboard. Following LeRobot's own simulation pages (for example the HIL-SERL simulation guide) this lives alongside the real robot rather than replacing it.

Design

  • Same interface. SOMujoco (registered as robot type so101_mujoco) implements LeRobot's Robot interface, so code that works with SO101Follower also works with the simulated arm.
  • One source of truth for kinematics. Forward and inverse kinematics come from LeRobot's RobotKinematics (placo, driven by the URDF). MuJoCo only steps physics and renders.
  • Keyboard end-effector control. The target moves with the arrow and Shift keys, IK solves the six joint angles, and the arm follows. Keys are read by the MuJoCo viewer window itself, so it works under X11 and Wayland.

Making the two models agree

The MuJoCo model comes from the official SO-ARM100 hardware repo. Its end-effector site matched the URDF's gripper frame in position (to about 2 µm) but differed by a constant 180° rotation about the local Y axis, a convention difference between the two exports. We added a corrected gripper_frame_link site and wrote a regression test, test_mjcf_matches_urdf_fk, that checks the MuJoCo pose against placo's forward kinematics across several joint configurations, to better than 2×10-5.

Try it

uv sync --extra mujoco-sim
uv run python examples/so101_mujoco/teleoperate.py
KeyAction
Up / DownEnd-effector Y
Left / RightEnd-effector X
Shift / Right ShiftEnd-effector Z
Left Ctrl / Right CtrlClose / open gripper
EscQuit

Mirroring to the real arm

Adding --sync-real --real-port /dev/ttyACM0 also sends each joint target to a physical SO-101 through the unmodified SO101Follower, with each arm applying its own max_relative_target safety clipping.

Status. This path is wired up and unit-tested up to the call to send_action(), but it was not exercised on hardware during development. Check joint signs at low speed before relying on it.

The simulation is documented in the repo as docs/source/so101_mujoco.mdx and linked from the SO-101 assembly page and the Simulation section of the docs navigation. The upstream SO-101 page is the hardware reference.