-
Notifications
You must be signed in to change notification settings - Fork 2.9k
[WIP] Add RLBench simulator environment #2341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds RLBench support to LeRobot, enabling training and evaluation of policies on RLBench's 100+ vision-guided manipulation tasks. RLBench is a large-scale benchmark built on CoppeliaSim that provides infinite demonstrations via motion planning.
- Implements
RLBenchEnvwrapper with support for pixel-based observations and joint position actions - Adds configuration infrastructure for RLBench task suites (FS10_V1 through MT100_V1) with task descriptions
- Includes dataset collection script for converting RLBench demonstrations to LeRobot format
- Provides comprehensive documentation with installation and usage examples
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lerobot/envs/rlbench.py | Main environment wrapper implementing Gymnasium interface for RLBench tasks |
| src/lerobot/envs/rlbench_config.json | Configuration file mapping 106 RLBench tasks to IDs and descriptions |
| src/lerobot/envs/factory.py | Adds RLBench environment creation support to the factory function |
| src/lerobot/envs/configs.py | Defines RLBenchEnv configuration dataclass with features and observation mappings |
| pyproject.toml | Adds RLBench as optional dependency |
| examples/dataset/rlbench_collect_dataset.py | Script for collecting demonstrations and converting to LeRobot dataset format |
| docs/source/rlbench.mdx | Comprehensive documentation for RLBench integration |
| docs/source/_toctree.yml | Adds RLBench documentation to table of contents |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/lerobot/envs/rlbench_config.json
Outdated
| "close_jar": "Close the jar", | ||
| "close_laptop_lid": "Close laptop lid", | ||
| "close_microwave": "Close microwave", | ||
| "empty_container": "Empty the container in the to container", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete sentence with extra 'the to' - should likely be 'Empty the container into the container' or 'Empty the container in the container'.
| "empty_container": "Empty the container in the to container", | |
| "empty_container": "Empty the container into the container", |
src/lerobot/envs/rlbench_config.json
Outdated
| "empty_dishwasher": "Empty the dishwasher", | ||
| "get_ice_from_fridge": "Get ice from fridge", | ||
| "hang_frame_on_hanger": "Hang frame on hanger", | ||
| "hit_ball_with_queue": "Hit ball with queue in to the goal", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word 'queue' should be 'cue' (a billiards/pool cue). Also, 'in to' should be 'into'.
| "hit_ball_with_queue": "Hit ball with queue in to the goal", | |
| "hit_ball_with_queue": "Hit ball with cue into the goal", |
src/lerobot/envs/rlbench_config.json
Outdated
| "lift_numbered_block": "Pick up the block with the number", | ||
| "light_bulb_in": "Screw in the light bulb", | ||
| "light_bulb_out": "Put the bulb in the holder", | ||
| "meat_off_grill": "Take the off the grill", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing object noun after 'Take the' - should be 'Take the meat off the grill'.
| "meat_off_grill": "Take the off the grill", | |
| "meat_off_grill": "Take the meat off the grill", |
src/lerobot/envs/rlbench_config.json
Outdated
| "light_bulb_in": "Screw in the light bulb", | ||
| "light_bulb_out": "Put the bulb in the holder", | ||
| "meat_off_grill": "Take the off the grill", | ||
| "meat_on_grill": "Put the on the grill", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing object noun after 'Put the' - should be 'Put the meat on the grill'.
| "meat_on_grill": "Put the on the grill", | |
| "meat_on_grill": "Put the meat on the grill", |
src/lerobot/envs/rlbench_config.json
Outdated
| "open_wine_bottle": "Open wine bottle", | ||
| "phone_on_base": "Put the phone on the base", | ||
| "pick_and_lift": "Pick up the block and lift it up to the target", | ||
| "pick_and_lift_small": "Pick up the and lift it up to the target", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing object noun after 'Pick up the' - should be 'Pick up the block and lift it up to the target' or similar.
| "pick_and_lift_small": "Pick up the and lift it up to the target", | |
| "pick_and_lift_small": "Pick up the small block and lift it up to the target", |
src/lerobot/envs/rlbench_config.json
Outdated
| "take_money_out_safe": "Take the money out of the bottom shelf and place it on", | ||
| "take_off_weighing_scales": "Remove the pepper from the weighing scales and place it", |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete sentence ending with 'place it' - missing destination.
| "take_money_out_safe": "Take the money out of the bottom shelf and place it on", | |
| "take_off_weighing_scales": "Remove the pepper from the weighing scales and place it", | |
| "take_money_out_safe": "Take the money out of the bottom shelf and place it on the table", | |
| "take_off_weighing_scales": "Remove the pepper from the weighing scales and place it on the table", |
| agent_pos = np.concatenate( | ||
| raw_obs["joint_positions"], | ||
| [raw_obs["gripper_open"]], | ||
| ) |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect usage of np.concatenate. The function requires a sequence of arrays as a single argument, not separate arguments. Should be: np.concatenate([raw_obs['joint_positions'], [raw_obs['gripper_open']]])
| agent_pos = np.concatenate( | |
| raw_obs["joint_positions"], | |
| [raw_obs["gripper_open"]], | |
| ) | |
| agent_pos = np.concatenate([raw_obs["joint_positions"], [raw_obs["gripper_open"]]]) |
| obs = {"pixels": image.copy()} | ||
| elif self.obs_type == "pixels_agent_pos": | ||
| obs = { | ||
| "pixels": image.copy(), |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable image is undefined in this scope. The code stores images in the images dictionary but then references an undefined image variable. Should use one of the images from the images dictionary or from raw_obs.
| obs = {"pixels": image.copy()} | |
| elif self.obs_type == "pixels_agent_pos": | |
| obs = { | |
| "pixels": image.copy(), | |
| obs = {"pixels": images.copy()} | |
| elif self.obs_type == "pixels_agent_pos": | |
| obs = { | |
| "pixels": images.copy(), |
| ## Why RLBench? | ||
|
|
||
| - **Diverse and Challenging Tasks:** RLBench includes over 100 unique, hand-designed tasks, ranging from simple reaching and pushing to complex, multi-stage activities like opening an oven and placing a tray inside. This diversity tests an algorithm's ability to generalize across different objectives and dynamics. | ||
| - **Rich, Multi-Modal Observations:** The benchmark provides both proprioceptive (joint states) and visual observations. Visual data comes from multiple camera angles, including over-the-shoulder cameras and wrist camera, with options for RGB, depth, and segmentation masks. |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammatical inconsistency: 'wrist camera' should be plural 'wrist cameras' to match 'over-the-shoulder cameras'.
| - **Rich, Multi-Modal Observations:** The benchmark provides both proprioceptive (joint states) and visual observations. Visual data comes from multiple camera angles, including over-the-shoulder cameras and wrist camera, with options for RGB, depth, and segmentation masks. | |
| - **Rich, Multi-Modal Observations:** The benchmark provides both proprioceptive (joint states) and visual observations. Visual data comes from multiple camera angles, including over-the-shoulder cameras and wrist cameras, with options for RGB, depth, and segmentation masks. |
|
|
||
| # extract and type-check top-level dicts | ||
| TASK_DESCRIPTIONS: dict[str, str] = data.get("TASK_DESCRIPTIONS", {}) | ||
| TASK_NAME_TO_ID: dict[str, int] = data.get("TASK_NAME_TO_ID", {}) |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The global variable 'TASK_NAME_TO_ID' is not used.
| TASK_NAME_TO_ID: dict[str, int] = data.get("TASK_NAME_TO_ID", {}) |
|
ty for the PR! Can you provide a MRE so that we can take a look at what exactly is going on with multi-processing? it'd be useful to debug |
|
Sure! 1. Install CoppeliaSim# set env variables
export COPPELIASIM_ROOT=${HOME}/CoppeliaSim
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$COPPELIASIM_ROOT
export QT_QPA_PLATFORM_PLUGIN_PATH=$COPPELIASIM_ROOT
wget https://downloads.coppeliarobotics.com/V4_1_0/CoppeliaSim_Edu_V4_1_0_Ubuntu20_04.tar.xz
mkdir -p $COPPELIASIM_ROOT && tar -xf CoppeliaSim_Edu_V4_1_0_Ubuntu20_04.tar.xz -C $COPPELIASIM_ROOT --strip-components 1
rm -rf CoppeliaSim_Edu_V4_1_0_Ubuntu20_04.tar.xz2. Clone the forkgit clone https://github.com/RonPlusSign/lerobot.git
cd lerobot
git checkout add-rlbench-simulator3. Create a venv and install LeRobot + RLBenchconda create -n lerobot_rlbench python=3.10 -y
conda activate lerobot_rlbench
pip install pycparser # needed while cloning rlbench
pip install -e ".[rlbench,smolvla]" # smolvla is used in next steps for testing, but it's not directly linked with rlbench4. Run the test(here is when the problem occours) lerobot-eval \
--policy.path="RonPlusSign/smolvla_PutRubbishInBin" \
--env.type=rlbench \
--env.task=FS10_V1 \
--eval.batch_size=1 \
--eval.n_episodes=1In particular, it breaks when instantiating multiple environments in the for loop of line 413 of Useful links: RLBench#140, RLBench#161, PyRep parallelization. |
|
Hey @RonPlusSign great work! Do you have cases where RLBench work in this PR ? |
This pull request adds support for the RLBench benchmark to LeRobot, enabling users to train and evaluate policies on RLBench tasks. The integration includes environment configuration, dataset collection, documentation, and dependency management. The most important changes are grouped below.
RLBench Environment Integration
RLBenchEnvclass tosrc/lerobot/envs/configs.pyfor configuring RLBench environments, including support for multiple observation types, camera settings, and feature mappings.make_envfunction insrc/lerobot/envs/factory.pyto support RLBench environments by importing and callingcreate_rlbench_envswhen the environment type is RLBench.RLBench Dataset Collection
examples/dataset/rlbench_collect_dataset.pyfor collecting RLBench demonstrations and saving them in the LeRobot dataset format, with flexible action representations and camera configurations.Documentation Updates
docs/source/rlbench.mdx) describing the benchmark, its integration, setup instructions, and usage within LeRobot.docs/source/_toctree.yml) to include the new RLBench section.Dependency Management
pyproject.tomland included it in thealldependencies group to ensure easy installation.Reviews needed
How it was tested
I tested the code trying to load an evaluation of a model on the given environment, as reported below.
How to checkout & try? (for the reviewer)
After installing the CoppeliaSim as explained in the
docs/source/rlbench.mdxand installing the rlbench optional dependency (`pip install -e ".[rlbench]"), you can use rlbench as an env type:lerobot-eval \ --policy.path="RonPlusSign/smolvla_PutRubbishInBin" \ --env.type=rlbench \ --env.task=FS10_V1 \ --eval.batch_size=1 \ --eval.n_episodes=1I opened this PR because I'm working on VLA models on RLBench for my Master's thesis. This follows up an outdated PR (#290) and can be helpful for the issue I opened few days ago: #2259.
@jadechoghari, @fracapuano as reported in my issue #2259, here's the PR 😄
Any help from anybody to fix the concurrency issues would be very welcome!