Instructions to use namenu/so101-pick-place-env with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LeRobot
How to use namenu/so101-pick-place-env with LeRobot:
- Notebooks
- Google Colab
- Kaggle
SO-101 pick-and-place (MuJoCo)
Pick the orange cube off the table and place it inside the green target zone, on a calibrated SO-101 arm. A LeRobot EnvHub environment.
from lerobot.envs import make_env
envs = make_env(
"namenu/so101-pick-place-env@<commit-sha>:env.py",
n_envs=1,
trust_remote_code=True,
)
env = envs["so101_pick_place"][0]
obs, info = env.reset(seed=0)
Pin a commit. @main works but tells you nothing about which scene produced a result.
Install the dependencies first
EnvHub does not install a repository's requirements.txt. Before loading:
pip install "gymnasium>=0.29" "mujoco>=3.2" "numpy>=1.26"
What a policy has to speak
| observation | pixels.up, pixels.side โ (480, 640, 3) uint8; agent_pos โ (6,) float32 |
| action | (6,) float32 โ joint position targets, degrees |
| control rate | 20 Hz (sim_dt 0.002 s, 25 substeps) |
| episode length | 200 steps |
| success | cube centre within 4 cm of the target site, back near table height, gripper open |
| reward | shaped: โโcube_xy โ target_xyโ, +1 per step while lifted, +10 terminal on success |
Observations follow LeRobot's gym convention, so preprocess_observation maps them onto
observation.images.up / observation.images.side / observation.state with no remap layer.
Joint units are degrees to match lerobot/svla_so101_pickplace, whose policies are trained on
that convention; the MJCF actuators are in radians and the env converts at the boundary.
SO101PickBin-v0 โ one front camera at 30 Hz, box into a wire bin, approximating the
namenu/pick-place-v1 real-hardware capture โ is also registered by the bundled package, though
this entry point exposes pick-and-place.
An assisted grasp, stated plainly
The SO-101's moulded jaws do not reliably hold the cube under contact physics alone. When the gripper is commanded closed within 4.5 cm of the cube, the cube is kinematically attached to the tool frame until the gripper opens. Scripted experts and learned policies get the same rule, so train and eval stay consistent โ but a success rate here is not a claim about contact-rich grasping.
No baseline numbers are published with this environment. Nothing has been measured on it under a protocol worth citing yet.
Why env.py downloads the repository
EnvHub fetches only the file named in the ref. The bundled so101_envs package and 16 MB of robot
meshes are not fetched with it, and their directory is never put on sys.path โ so env.py calls
snapshot_download for its own repo on first load, recovering the repo id and commit from the
cache path. A cloned checkout skips that entirely.
One trap if you copy the pattern: locate yourself with Path(__file__).absolute(), never
.resolve(). The cache exposes snapshots/<commit>/ as symlinks into a flat blobs/ store, and
resolving them discards both the repo name and the commit.
Worth knowing if you publish your own: an environment spanning more than one file does not work
through make_env unless it bootstraps this way.
Provenance
The robot model โ assets/so101/mjcf/so101_new_calib.xml and the 13 STL meshes โ comes from
TheRobotStudio/SO-ARM100 (Simulation/SO101/),
Apache-2.0. The only change is the MJCF's meshdir attribute, repointed at this layout; geometry,
joints, actuators, and calibration are untouched. See NOTICE.
The task scenes, the gym environments, and this entry point are original. The scene geometry is authored, not measured against a physical cell.