LeRobot documentation
RoboTwin 2.0
RoboTwin 2.0
The commands below run the simulator locally. To keep its dependencies away from your policy's, serve it instead with `lerobot-env-server --config_path=docker/sim/configs/robotwin.yaml --sim.task=--docker=true`, where ` ` is the command's `--env.task`, and add `--env.server.endpoint=tcp/127.0.0.1:7448` to the command. A server runs the task it was started with (see [Simulation: local or served](./simulation)).
RoboTwin 2.0 is a large-scale dual-arm manipulation benchmark built on the SAPIEN physics engine. It provides a standardized evaluation protocol for bimanual robotic policies across 50 tasks (as of upstream main) with strong domain randomization (clutter, lighting, background, tabletop height, and language instructions).
- Paper: RoboTwin 2.0: A Scalable Data Generator and Benchmark with Strong Domain Randomization for Robust Bimanual Robotic Manipulation
- GitHub: RoboTwin-Platform/RoboTwin
- Leaderboard: robotwin-platform.github.io/leaderboard
- Dataset: lerobot/robotwin_unified

Overview
| Property | Value |
|---|---|
| Tasks | 50 dual-arm manipulation tasks |
| Robot | Aloha-AgileX bimanual (14 DOF, 7 per arm) |
| Action space | 14-dim joint-space, continuous in [-1, 1] |
| Cameras | head_camera, left_camera, right_camera |
| Simulator | SAPIEN (not MuJoCo) |
| Eval protocol | 100 episodes/task, 50 demo_clean demonstrations |
| Eval settings | Easy (demo_clean) and Hard (demo_randomized) |
Available tasks
RoboTwin 2.0 ships 50 dual-arm manipulation tasks in its upstream envs/ directory. The canonical list is the ROBOTWIN_TASKS tuple in src/lerobot/sim/integrations/robotwin.py, mirrored verbatim from the upstream repo. Example tasks:
| Task | CLI name | Category |
|---|---|---|
| Beat block with hammer | beat_block_hammer | Tool use |
| Click bell / alarm clock | click_bell | Precision press |
| Stack blocks (2 / 3) | stack_blocks_two/three | Stacking |
| Stack bowls (2 / 3) | stack_bowls_two/three | Stacking |
| Handover block / mic | handover_block | Bimanual coord. |
| Lift pot | lift_pot | Bimanual lift |
| Shake bottle | shake_bottle | Continuous motion |
| Turn switch | turn_switch | Articulated obj |
| Stamp seal | stamp_seal | Precision place |
| Scan object | scan_object | Mobile manip. |
Pass a comma-separated list to --env.task to run multiple tasks in a single eval sweep.
`open_laptop` is currently broken upstream (its `check_success()` uses `self.arm_tag`, which is only set inside the scripted-expert `play_once()` path and therefore unavailable during normal policy eval). Avoid it until the upstream bug is fixed, or patch the task to default `self.arm_tag = "left"` in `load_actors()`.
Dataset
The RoboTwin 2.0 dataset is available in LeRobot v3.0 format on the Hugging Face Hub:
lerobot/robotwin_unified
It contains over 100,000 pre-collected trajectories across all 50 tasks (79.6 GB, Apache 2.0 license). No format conversion is needed — it is already in the correct LeRobot v3.0 schema with video observations and action labels.
You can load it directly with the HF Datasets library:
from datasets import load_dataset
ds = load_dataset("lerobot/robotwin_unified", split="train")Installation
RoboTwin 2.0 requires Linux with an NVIDIA GPU (SAPIEN renders with Vulkan). Its planners, CuRobo and pytorch3d, compile CUDA code against torch 2.7.1, which does not match LeRobot’s torch, so RoboTwin runs in its own environment behind lerobot-env-server and the policy side only needs LeRobot.
Served image (recommended)
lerobot-env-server --config_path=docker/sim/configs/robotwin.yaml --sim.task=beat_block_hammer --docker=trueThe first run builds the robotwin_native stage of docker/Dockerfile.sim (about 20 minutes, mostly pytorch3d and CuRobo). On a small machine, build the image yourself first with bounded memory; the server then reuses it:
docker build -f docker/Dockerfile.sim --build-arg SIM=robotwin \
--build-arg MAX_JOBS=1 --build-arg CUROBO_CUDA_ARCHS=8.6 -t lerobot-sim-robotwin:local .where 8.6 is your GPU’s compute capability. Add --env.server.endpoint=tcp/127.0.0.1:7448 to the evaluation commands below.
Native environment
To run the server without Docker, reproduce the robotwin_native stage of docker/Dockerfile.sim in a separate virtual environment, which is the tested recipe: the CUDA 12.8 nvcc, torch 2.7.1, the pinned RoboTwin commit and assets, CuRobo v0.7.8, and RoboTwin’s mplib and SAPIEN patches. Then install LeRobot with --no-deps plus docker/sim/requirements.txt, and drop --docker=true from the command above (see Simulation: local or served).
Evaluation
Standard evaluation (recommended)
Evaluate a policy on a single task with the official protocol (100 episodes):
lerobot-eval \
--policy.path="your-hf-policy-id" \
--env.type=robotwin \
--env.task=beat_block_hammer \
--eval.batch_size=1 \
--eval.n_episodes=100Single-task quick check
lerobot-eval \
--policy.path="your-hf-policy-id" \
--env.type=robotwin \
--env.task=beat_block_hammer \
--eval.batch_size=1 \
--eval.n_episodes=5Multi-task sweep
Evaluate on several tasks in one run:
lerobot-eval \
--policy.path="your-hf-policy-id" \
--env.type=robotwin \
--env.task=beat_block_hammer,click_bell,handover_block,stack_blocks_two \
--eval.batch_size=1 \
--eval.n_episodes=100Full benchmark (all 50 tasks)
lerobot-eval \
--policy.path="your-hf-policy-id" \
--env.type=robotwin \
--env.task=adjust_bottle,beat_block_hammer,blocks_ranking_rgb,blocks_ranking_size,click_alarmclock,click_bell,dump_bin_bigbin,grab_roller,handover_block,handover_mic,hanging_mug,lift_pot,move_can_pot,move_pillbottle_pad,move_playingcard_away,move_stapler_pad,open_microwave,pick_diverse_bottles,pick_dual_bottles,place_a2b_left,place_a2b_right,place_bread_basket,place_bread_skillet,place_burger_fries,place_can_basket,place_cans_plasticbox,place_container_plate,place_dual_shoes,place_empty_cup,place_fan,place_mouse_pad,place_object_basket,place_object_scale,place_object_stand,place_phone_stand,place_shoe,press_stapler,put_bottles_dustbin,put_object_cabinet,rotate_qrcode,scan_object,shake_bottle,shake_bottle_horizontally,stack_blocks_three,stack_blocks_two,stack_bowls_three,stack_bowls_two,stamp_seal,turn_switch \
--eval.batch_size=1 \
--eval.n_episodes=100`open_laptop` is intentionally omitted above because of the upstream `self.arm_tag` bug (see the **Available tasks** section). Re-add it once the upstream fix lands.
Camera configuration
By default, all three cameras are included:
| Camera key | Description |
|---|---|
head_camera | Torso-mounted overhead view |
left_camera | Left arm wrist-mounted camera |
right_camera | Right arm wrist-mounted camera |
To use a subset of cameras, override --env.camera_names:
lerobot-eval \
--policy.path="your-hf-policy-id" \
--env.type=robotwin \
--env.task=beat_block_hammer \
--env.camera_names="head_camera,left_camera" \
--eval.batch_size=1 \
--eval.n_episodes=10Environment config reference
Key parameters for RoboTwinEnvConfig:
| Parameter | Default | Description |
|---|---|---|
task | "beat_block_hammer" | Comma-separated task name(s) |
fps | 25 | Simulation FPS |
episode_length | 1200 | Max steps per episode |
obs_type | "pixels_agent_pos" | "pixels" or "pixels_agent_pos" |
camera_names | "head_camera,left_camera,right_camera" | Comma-separated active cameras |
observation_height | 240 | Camera pixel height |
observation_width | 320 | Camera pixel width |
Leaderboard submission
Results can be submitted to the RoboTwin 2.0 leaderboard. The official protocol requires:
- Training on 50
demo_cleandemonstrations per task - Evaluating 100 episodes per task
- Reporting success rate separately for Easy (
demo_clean) and Hard (demo_randomized) settings
For submission instructions, refer to the RoboTwin 2.0 documentation.
Update on GitHub