Package folder structure (#1417)

* Move files

* Replace imports & paths

* Update relative paths

* Update doc symlinks

* Update instructions paths

* Fix imports

* Update grpc files

* Update more instructions

* Downgrade grpc-tools

* Update manifest

* Update more paths

* Update config paths

* Update CI paths

* Update bandit exclusions

* Remove walkthrough section
This commit is contained in:
Simon Alibert
2025-07-01 16:34:46 +02:00
committed by GitHub
parent 483be9aac2
commit d4ee470b00
268 changed files with 862 additions and 890 deletions

View File

@@ -24,7 +24,7 @@ Examples:
pytest -sx tests/test_stuff.py::test_something pytest -sx tests/test_stuff.py::test_something
``` ```
```bash ```bash
python lerobot/scripts/train.py --some.option=true python -m lerobot.scripts.train --some.option=true
``` ```
## SECTION TO REMOVE BEFORE SUBMITTING YOUR PR ## SECTION TO REMOVE BEFORE SUBMITTING YOUR PR

View File

@@ -44,7 +44,7 @@ jobs:
working-directory: /lerobot working-directory: /lerobot
steps: steps:
- name: Tests - name: Tests
run: pytest -v --cov=./lerobot --disable-warnings tests run: pytest -v --cov=./src/lerobot --disable-warnings tests
- name: Tests end-to-end - name: Tests end-to-end
run: make test-end-to-end run: make test-end-to-end
@@ -74,7 +74,7 @@ jobs:
run: nvidia-smi run: nvidia-smi
- name: Test - name: Test
run: pytest -v --cov=./lerobot --cov-report=xml --disable-warnings tests run: pytest -v --cov=./src/lerobot --cov-report=xml --disable-warnings tests
# TODO(aliberts): Link with HF Codecov account # TODO(aliberts): Link with HF Codecov account
# - name: Upload coverage reports to Codecov with GitHub Action # - name: Upload coverage reports to Codecov with GitHub Action
# uses: codecov/codecov-action@v4 # uses: codecov/codecov-action@v4

View File

@@ -17,7 +17,7 @@ name: Tests
on: on:
pull_request: pull_request:
paths: paths:
- "lerobot/**" - "src/**"
- "tests/**" - "tests/**"
- "examples/**" - "examples/**"
- ".github/**" - ".github/**"
@@ -29,7 +29,7 @@ on:
branches: branches:
- main - main
paths: paths:
- "lerobot/**" - "src/**"
- "tests/**" - "tests/**"
- "examples/**" - "examples/**"
- ".github/**" - ".github/**"
@@ -73,7 +73,7 @@ jobs:
- name: Test with pytest - name: Test with pytest
run: | run: |
uv run pytest tests -v --cov=./lerobot --durations=0 \ uv run pytest tests -v --cov=./src/lerobot --durations=0 \
-W ignore::DeprecationWarning:imageio_ffmpeg._utils:7 \ -W ignore::DeprecationWarning:imageio_ffmpeg._utils:7 \
-W ignore::UserWarning:torch.utils.data.dataloader:558 \ -W ignore::UserWarning:torch.utils.data.dataloader:558 \
-W ignore::UserWarning:gymnasium.utils.env_checker:247 \ -W ignore::UserWarning:gymnasium.utils.env_checker:247 \
@@ -105,7 +105,7 @@ jobs:
- name: Test with pytest - name: Test with pytest
run: | run: |
uv run pytest tests -v --cov=./lerobot --durations=0 \ uv run pytest tests -v --cov=./src/lerobot --durations=0 \
-W ignore::DeprecationWarning:imageio_ffmpeg._utils:7 \ -W ignore::DeprecationWarning:imageio_ffmpeg._utils:7 \
-W ignore::UserWarning:torch.utils.data.dataloader:558 \ -W ignore::UserWarning:torch.utils.data.dataloader:558 \
-W ignore::UserWarning:gymnasium.utils.env_checker:247 \ -W ignore::UserWarning:gymnasium.utils.env_checker:247 \

View File

@@ -67,7 +67,7 @@ post it.
## Adding new policies, datasets or environments ## Adding new policies, datasets or environments
Look at our implementations for [datasets](./lerobot/common/datasets/), [policies](./lerobot/common/policies/), Look at our implementations for [datasets](./src/lerobot/datasets/), [policies](./src/lerobot/policies/),
environments ([aloha](https://github.com/huggingface/gym-aloha), environments ([aloha](https://github.com/huggingface/gym-aloha),
[xarm](https://github.com/huggingface/gym-xarm), [xarm](https://github.com/huggingface/gym-xarm),
[pusht](https://github.com/huggingface/gym-pusht)) [pusht](https://github.com/huggingface/gym-pusht))

View File

@@ -1,2 +1,2 @@
include lerobot/templates/lerobot_modelcard_template.md include src/lerobot/templates/lerobot_modelcard_template.md
include lerobot/common/datasets/card_template.md include src/lerobot/datasets/card_template.md

View File

@@ -44,7 +44,7 @@ test-end-to-end:
${MAKE} DEVICE=$(DEVICE) test-smolvla-ete-eval ${MAKE} DEVICE=$(DEVICE) test-smolvla-ete-eval
test-act-ete-train: test-act-ete-train:
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=act \ --policy.type=act \
--policy.dim_model=64 \ --policy.dim_model=64 \
--policy.n_action_steps=20 \ --policy.n_action_steps=20 \
@@ -68,12 +68,12 @@ test-act-ete-train:
--output_dir=tests/outputs/act/ --output_dir=tests/outputs/act/
test-act-ete-train-resume: test-act-ete-train-resume:
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=tests/outputs/act/checkpoints/000002/pretrained_model/train_config.json \ --config_path=tests/outputs/act/checkpoints/000002/pretrained_model/train_config.json \
--resume=true --resume=true
test-act-ete-eval: test-act-ete-eval:
python lerobot/scripts/eval.py \ python -m lerobot.scripts.eval \
--policy.path=tests/outputs/act/checkpoints/000004/pretrained_model \ --policy.path=tests/outputs/act/checkpoints/000004/pretrained_model \
--policy.device=$(DEVICE) \ --policy.device=$(DEVICE) \
--env.type=aloha \ --env.type=aloha \
@@ -82,7 +82,7 @@ test-act-ete-eval:
--eval.batch_size=1 --eval.batch_size=1
test-diffusion-ete-train: test-diffusion-ete-train:
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=diffusion \ --policy.type=diffusion \
--policy.down_dims='[64,128,256]' \ --policy.down_dims='[64,128,256]' \
--policy.diffusion_step_embed_dim=32 \ --policy.diffusion_step_embed_dim=32 \
@@ -106,7 +106,7 @@ test-diffusion-ete-train:
--output_dir=tests/outputs/diffusion/ --output_dir=tests/outputs/diffusion/
test-diffusion-ete-eval: test-diffusion-ete-eval:
python lerobot/scripts/eval.py \ python -m lerobot.scripts.eval \
--policy.path=tests/outputs/diffusion/checkpoints/000002/pretrained_model \ --policy.path=tests/outputs/diffusion/checkpoints/000002/pretrained_model \
--policy.device=$(DEVICE) \ --policy.device=$(DEVICE) \
--env.type=pusht \ --env.type=pusht \
@@ -115,7 +115,7 @@ test-diffusion-ete-eval:
--eval.batch_size=1 --eval.batch_size=1
test-tdmpc-ete-train: test-tdmpc-ete-train:
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=tdmpc \ --policy.type=tdmpc \
--policy.device=$(DEVICE) \ --policy.device=$(DEVICE) \
--policy.push_to_hub=false \ --policy.push_to_hub=false \
@@ -137,7 +137,7 @@ test-tdmpc-ete-train:
--output_dir=tests/outputs/tdmpc/ --output_dir=tests/outputs/tdmpc/
test-tdmpc-ete-eval: test-tdmpc-ete-eval:
python lerobot/scripts/eval.py \ python -m lerobot.scripts.eval \
--policy.path=tests/outputs/tdmpc/checkpoints/000002/pretrained_model \ --policy.path=tests/outputs/tdmpc/checkpoints/000002/pretrained_model \
--policy.device=$(DEVICE) \ --policy.device=$(DEVICE) \
--env.type=xarm \ --env.type=xarm \
@@ -148,7 +148,7 @@ test-tdmpc-ete-eval:
test-smolvla-ete-train: test-smolvla-ete-train:
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=smolvla \ --policy.type=smolvla \
--policy.n_action_steps=20 \ --policy.n_action_steps=20 \
--policy.chunk_size=20 \ --policy.chunk_size=20 \
@@ -171,7 +171,7 @@ test-smolvla-ete-train:
--output_dir=tests/outputs/smolvla/ --output_dir=tests/outputs/smolvla/
test-smolvla-ete-eval: test-smolvla-ete-eval:
python lerobot/scripts/eval.py \ python -m lerobot.scripts.eval \
--policy.path=tests/outputs/smolvla/checkpoints/000004/pretrained_model \ --policy.path=tests/outputs/smolvla/checkpoints/000004/pretrained_model \
--policy.device=$(DEVICE) \ --policy.device=$(DEVICE) \
--env.type=aloha \ --env.type=aloha \

View File

@@ -149,44 +149,20 @@ wandb login
(note: you will also need to enable WandB in the configuration. See below.) (note: you will also need to enable WandB in the configuration. See below.)
## Walkthrough
```
.
├── examples # contains demonstration examples, start here to learn about LeRobot
| └── advanced # contains even more examples for those who have mastered the basics
├── lerobot
| ├── configs # contains config classes with all options that you can override in the command line
| ├── common # contains classes and utilities
| | ├── datasets # various datasets of human demonstrations: aloha, pusht, xarm
| | ├── envs # various sim environments: aloha, pusht, xarm
| | ├── policies # various policies: act, diffusion, tdmpc
| | ├── robot_devices # various real devices: dynamixel motors, opencv cameras, koch robots
| | └── utils # various utilities
| └── scripts # contains functions to execute via command line
| ├── eval.py # load policy and evaluate it on an environment
| ├── train.py # train a policy via imitation learning and/or reinforcement learning
| ├── control_robot.py # teleoperate a real robot, record data, run a policy
| ├── push_dataset_to_hub.py # convert your dataset into LeRobot dataset format and upload it to the Hugging Face hub
| └── visualize_dataset.py # load a dataset and render its demonstrations
├── outputs # contains results of scripts execution: logs, videos, model checkpoints
└── tests # contains pytest utilities for continuous integration
```
### Visualize datasets ### Visualize datasets
Check out [example 1](./examples/1_load_lerobot_dataset.py) that illustrates how to use our dataset class which automatically downloads data from the Hugging Face hub. Check out [example 1](./examples/1_load_lerobot_dataset.py) that illustrates how to use our dataset class which automatically downloads data from the Hugging Face hub.
You can also locally visualize episodes from a dataset on the hub by executing our script from the command line: You can also locally visualize episodes from a dataset on the hub by executing our script from the command line:
```bash ```bash
python lerobot/scripts/visualize_dataset.py \ python -m lerobot.scripts.visualize_dataset \
--repo-id lerobot/pusht \ --repo-id lerobot/pusht \
--episode-index 0 --episode-index 0
``` ```
or from a dataset in a local folder with the `root` option and the `--local-files-only` (in the following case the dataset will be searched for in `./my_local_data_dir/lerobot/pusht`) or from a dataset in a local folder with the `root` option and the `--local-files-only` (in the following case the dataset will be searched for in `./my_local_data_dir/lerobot/pusht`)
```bash ```bash
python lerobot/scripts/visualize_dataset.py \ python -m lerobot.scripts.visualize_dataset \
--repo-id lerobot/pusht \ --repo-id lerobot/pusht \
--root ./my_local_data_dir \ --root ./my_local_data_dir \
--local-files-only 1 \ --local-files-only 1 \
@@ -199,7 +175,7 @@ It will open `rerun.io` and display the camera streams, robot states and actions
https://github-production-user-asset-6210df.s3.amazonaws.com/4681518/328035972-fd46b787-b532-47e2-bb6f-fd536a55a7ed.mov?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240505%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240505T172924Z&X-Amz-Expires=300&X-Amz-Signature=d680b26c532eeaf80740f08af3320d22ad0b8a4e4da1bcc4f33142c15b509eda&X-Amz-SignedHeaders=host&actor_id=24889239&key_id=0&repo_id=748713144 https://github-production-user-asset-6210df.s3.amazonaws.com/4681518/328035972-fd46b787-b532-47e2-bb6f-fd536a55a7ed.mov?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240505%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240505T172924Z&X-Amz-Expires=300&X-Amz-Signature=d680b26c532eeaf80740f08af3320d22ad0b8a4e4da1bcc4f33142c15b509eda&X-Amz-SignedHeaders=host&actor_id=24889239&key_id=0&repo_id=748713144
Our script can also visualize datasets stored on a distant server. See `python lerobot/scripts/visualize_dataset.py --help` for more instructions. Our script can also visualize datasets stored on a distant server. See `python -m lerobot.scripts.visualize_dataset --help` for more instructions.
### The `LeRobotDataset` format ### The `LeRobotDataset` format
@@ -252,7 +228,7 @@ Check out [example 2](./examples/2_evaluate_pretrained_policy.py) that illustrat
We also provide a more capable script to parallelize the evaluation over multiple environments during the same rollout. Here is an example with a pretrained model hosted on [lerobot/diffusion_pusht](https://huggingface.co/lerobot/diffusion_pusht): We also provide a more capable script to parallelize the evaluation over multiple environments during the same rollout. Here is an example with a pretrained model hosted on [lerobot/diffusion_pusht](https://huggingface.co/lerobot/diffusion_pusht):
```bash ```bash
python lerobot/scripts/eval.py \ python -m lerobot.scripts.eval \
--policy.path=lerobot/diffusion_pusht \ --policy.path=lerobot/diffusion_pusht \
--env.type=pusht \ --env.type=pusht \
--eval.batch_size=10 \ --eval.batch_size=10 \
@@ -264,10 +240,10 @@ python lerobot/scripts/eval.py \
Note: After training your own policy, you can re-evaluate the checkpoints with: Note: After training your own policy, you can re-evaluate the checkpoints with:
```bash ```bash
python lerobot/scripts/eval.py --policy.path={OUTPUT_DIR}/checkpoints/last/pretrained_model python -m lerobot.scripts.eval --policy.path={OUTPUT_DIR}/checkpoints/last/pretrained_model
``` ```
See `python lerobot/scripts/eval.py --help` for more instructions. See `python -m lerobot.scripts.eval --help` for more instructions.
### Train your own policy ### Train your own policy
@@ -279,14 +255,14 @@ A link to the wandb logs for the run will also show up in yellow in your termina
![](media/wandb.png) ![](media/wandb.png)
Note: For efficiency, during training every checkpoint is evaluated on a low number of episodes. You may use `--eval.n_episodes=500` to evaluate on more episodes than the default. Or, after training, you may want to re-evaluate your best checkpoints on more episodes or change the evaluation settings. See `python lerobot/scripts/eval.py --help` for more instructions. Note: For efficiency, during training every checkpoint is evaluated on a low number of episodes. You may use `--eval.n_episodes=500` to evaluate on more episodes than the default. Or, after training, you may want to re-evaluate your best checkpoints on more episodes or change the evaluation settings. See `python -m lerobot.scripts.eval --help` for more instructions.
#### Reproduce state-of-the-art (SOTA) #### Reproduce state-of-the-art (SOTA)
We provide some pretrained policies on our [hub page](https://huggingface.co/lerobot) that can achieve state-of-the-art performances. We provide some pretrained policies on our [hub page](https://huggingface.co/lerobot) that can achieve state-of-the-art performances.
You can reproduce their training by loading the config from their run. Simply running: You can reproduce their training by loading the config from their run. Simply running:
```bash ```bash
python lerobot/scripts/train.py --config_path=lerobot/diffusion_pusht python -m lerobot.scripts.train --config_path=lerobot/diffusion_pusht
``` ```
reproduces SOTA results for Diffusion Policy on the PushT task. reproduces SOTA results for Diffusion Policy on the PushT task.
@@ -312,7 +288,7 @@ python lerobot/scripts/push_dataset_to_hub.py \
See `python lerobot/scripts/push_dataset_to_hub.py --help` for more instructions. See `python lerobot/scripts/push_dataset_to_hub.py --help` for more instructions.
If your dataset format is not supported, implement your own in `lerobot/common/datasets/push_dataset_to_hub/${raw_format}_format.py` by copying examples like [pusht_zarr](https://github.com/huggingface/lerobot/blob/main/lerobot/common/datasets/push_dataset_to_hub/pusht_zarr_format.py), [umi_zarr](https://github.com/huggingface/lerobot/blob/main/lerobot/common/datasets/push_dataset_to_hub/umi_zarr_format.py), [aloha_hdf5](https://github.com/huggingface/lerobot/blob/main/lerobot/common/datasets/push_dataset_to_hub/aloha_hdf5_format.py), or [xarm_pkl](https://github.com/huggingface/lerobot/blob/main/lerobot/common/datasets/push_dataset_to_hub/xarm_pkl_format.py). --> If your dataset format is not supported, implement your own in `lerobot/datasets/push_dataset_to_hub/${raw_format}_format.py` by copying examples like [pusht_zarr](https://github.com/huggingface/lerobot/blob/main/lerobot/datasets/push_dataset_to_hub/pusht_zarr_format.py), [umi_zarr](https://github.com/huggingface/lerobot/blob/main/lerobot/datasets/push_dataset_to_hub/umi_zarr_format.py), [aloha_hdf5](https://github.com/huggingface/lerobot/blob/main/lerobot/datasets/push_dataset_to_hub/aloha_hdf5_format.py), or [xarm_pkl](https://github.com/huggingface/lerobot/blob/main/lerobot/datasets/push_dataset_to_hub/xarm_pkl_format.py). -->
### Add a pretrained policy ### Add a pretrained policy

View File

@@ -35,12 +35,12 @@ import torch
from skimage.metrics import mean_squared_error, peak_signal_noise_ratio, structural_similarity from skimage.metrics import mean_squared_error, peak_signal_noise_ratio, structural_similarity
from tqdm import tqdm from tqdm import tqdm
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.datasets.video_utils import ( from lerobot.datasets.video_utils import (
decode_video_frames_torchvision, decode_video_frames_torchvision,
encode_video_frames, encode_video_frames,
) )
from lerobot.common.utils.benchmark import TimeBenchmark from lerobot.utils.benchmark import TimeBenchmark
BASE_ENCODING = OrderedDict( BASE_ENCODING = OrderedDict(
[ [

View File

@@ -8,7 +8,7 @@ To instantiate a camera, you need a camera identifier. This identifier might cha
To find the camera indices of the cameras plugged into your system, run the following script: To find the camera indices of the cameras plugged into your system, run the following script:
```bash ```bash
python lerobot/find_cameras.py opencv # or realsense for Intel Realsense cameras python -m lerobot.find_cameras opencv # or realsense for Intel Realsense cameras
``` ```
The output will look something like this if you have two cameras connected: The output will look something like this if you have two cameras connected:
@@ -44,9 +44,9 @@ Below are two examples, demonstrating how to work with the API.
<hfoption id="Open CV Camera"> <hfoption id="Open CV Camera">
```python ```python
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.common.cameras.opencv.camera_opencv import OpenCVCamera from lerobot.cameras.opencv.camera_opencv import OpenCVCamera
from lerobot.common.cameras.configs import ColorMode, Cv2Rotation from lerobot.cameras.configs import ColorMode, Cv2Rotation
# Construct an `OpenCVCameraConfig` with your desired FPS, resolution, color mode, and rotation. # Construct an `OpenCVCameraConfig` with your desired FPS, resolution, color mode, and rotation.
config = OpenCVCameraConfig( config = OpenCVCameraConfig(
@@ -75,9 +75,9 @@ finally:
<hfoption id="Intel Realsense Camera"> <hfoption id="Intel Realsense Camera">
```python ```python
from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig
from lerobot.common.cameras.realsense.camera_realsense import RealSenseCamera from lerobot.cameras.realsense.camera_realsense import RealSenseCamera
from lerobot.common.cameras.configs import ColorMode, Cv2Rotation from lerobot.cameras.configs import ColorMode, Cv2Rotation
# Create a `RealSenseCameraConfig` specifying your cameras serial number and enabling depth. # Create a `RealSenseCameraConfig` specifying your cameras serial number and enabling depth.
config = RealSenseCameraConfig( config = RealSenseCameraConfig(

View File

@@ -50,12 +50,12 @@ pip install -e ".[hilserl]"
### Understanding Configuration ### Understanding Configuration
The training process begins with proper configuration for the HILSerl environment. The configuration class of interest is `HILSerlRobotEnvConfig` in `lerobot/common/envs/configs.py`. Which is defined as: The training process begins with proper configuration for the HILSerl environment. The configuration class of interest is `HILSerlRobotEnvConfig` in `lerobot/envs/configs.py`. Which is defined as:
```python ```python
class HILSerlRobotEnvConfig(EnvConfig): class HILSerlRobotEnvConfig(EnvConfig):
robot: RobotConfig | None = None # Main robot agent (defined in `lerobot/common/robots`) robot: RobotConfig | None = None # Main robot agent (defined in `lerobot/robots`)
teleop: TeleoperatorConfig | None = None # Teleoperator agent, e.g., gamepad or leader arm, (defined in `lerobot/common/teleoperators`) teleop: TeleoperatorConfig | None = None # Teleoperator agent, e.g., gamepad or leader arm, (defined in `lerobot/teleoperators`)
wrapper: EnvTransformConfig | None = None # Environment wrapper settings; check `lerobot/scripts/server/gym_manipulator.py` wrapper: EnvTransformConfig | None = None # Environment wrapper settings; check `lerobot/scripts/server/gym_manipulator.py`
fps: int = 10 # Control frequency fps: int = 10 # Control frequency
name: str = "real_robot" # Environment name name: str = "real_robot" # Environment name
@@ -172,7 +172,7 @@ class SO100FollowerEndEffectorConfig(SO100FollowerConfig):
) )
``` ```
The `Teleoperator` defines the teleoperation device. You can check the list of available teleoperators in `lerobot/common/teleoperators`. The `Teleoperator` defines the teleoperation device. You can check the list of available teleoperators in `lerobot/teleoperators`.
**Setting up the Gamepad** **Setting up the Gamepad**
@@ -226,7 +226,7 @@ During the online training, press `space` to take over the policy and `space` ag
Start the recording process, an example of the config file can be found [here](https://huggingface.co/datasets/aractingi/lerobot-example-config-files/blob/main/env_config_so100.json): Start the recording process, an example of the config file can be found [here](https://huggingface.co/datasets/aractingi/lerobot-example-config-files/blob/main/env_config_so100.json):
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path lerobot/configs/env_config_so100.json python -m lerobot.scripts.rl.gym_manipulator --config_path src/lerobot/configs/env_config_so100.json
``` ```
During recording: During recording:
@@ -256,7 +256,7 @@ Note: If you already know the crop parameters, you can skip this step and just s
Use the `crop_dataset_roi.py` script to interactively select regions of interest in your camera images: Use the `crop_dataset_roi.py` script to interactively select regions of interest in your camera images:
```bash ```bash
python lerobot/scripts/rl/crop_dataset_roi.py --repo-id username/pick_lift_cube python -m lerobot.scripts.rl.crop_dataset_roi --repo-id username/pick_lift_cube
``` ```
1. For each camera view, the script will display the first frame 1. For each camera view, the script will display the first frame
@@ -313,7 +313,7 @@ Before training, you need to collect a dataset with labeled examples. The `recor
To collect a dataset, you need to modify some parameters in the environment configuration based on HILSerlRobotEnvConfig. To collect a dataset, you need to modify some parameters in the environment configuration based on HILSerlRobotEnvConfig.
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path lerobot/configs/reward_classifier_train_config.json python -m lerobot.scripts.rl.gym_manipulator --config_path src/lerobot/configs/reward_classifier_train_config.json
``` ```
**Key Parameters for Data Collection** **Key Parameters for Data Collection**
@@ -387,7 +387,7 @@ Example configuration for training the [reward classifier](https://huggingface.c
To train the classifier, use the `train.py` script with your configuration: To train the classifier, use the `train.py` script with your configuration:
```bash ```bash
python lerobot/scripts/train.py --config_path path/to/reward_classifier_train_config.json python -m lerobot.scripts.train --config_path path/to/reward_classifier_train_config.json
``` ```
**Deploying and Testing the Model** **Deploying and Testing the Model**
@@ -410,7 +410,7 @@ or set the argument in the json config file.
Run `gym_manipulator.py` to test the model. Run `gym_manipulator.py` to test the model.
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/env_config.json python -m lerobot.scripts.rl.gym_manipulator --config_path path/to/env_config.json
``` ```
The reward classifier will automatically provide rewards based on the visual input from the robot's cameras. The reward classifier will automatically provide rewards based on the visual input from the robot's cameras.
@@ -422,17 +422,17 @@ The reward classifier will automatically provide rewards based on the visual inp
2. **Collect a dataset**: 2. **Collect a dataset**:
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path lerobot/configs/env_config.json python -m lerobot.scripts.rl.gym_manipulator --config_path src/lerobot/configs/env_config.json
``` ```
3. **Train the classifier**: 3. **Train the classifier**:
```bash ```bash
python lerobot/scripts/train.py --config_path lerobot/configs/reward_classifier_train_config.json python -m lerobot.scripts.train --config_path src/lerobot/configs/reward_classifier_train_config.json
``` ```
4. **Test the classifier**: 4. **Test the classifier**:
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path lerobot/configs/env_config.json python -m lerobot.scripts.rl.gym_manipulator --config_path src/lerobot/configs/env_config.json
``` ```
### Training with Actor-Learner ### Training with Actor-Learner
@@ -446,7 +446,7 @@ Create a training configuration file (example available [here](https://huggingfa
1. Configure the policy settings (`type="sac"`, `device`, etc.) 1. Configure the policy settings (`type="sac"`, `device`, etc.)
2. Set `dataset` to your cropped dataset 2. Set `dataset` to your cropped dataset
3. Configure environment settings with crop parameters 3. Configure environment settings with crop parameters
4. Check the other parameters related to SAC in [configuration_sac.py](https://github.com/huggingface/lerobot/blob/19bb621a7d0a31c20cd3cc08b1dbab68d3031454/lerobot/common/policies/sac/configuration_sac.py#L79). 4. Check the other parameters related to SAC in [configuration_sac.py](https://github.com/huggingface/lerobot/blob/19bb621a7d0a31c20cd3cc08b1dbab68d3031454/lerobot/policies/sac/configuration_sac.py#L79).
5. Verify that the `policy` config is correct with the right `input_features` and `output_features` for your task. 5. Verify that the `policy` config is correct with the right `input_features` and `output_features` for your task.
**Starting the Learner** **Starting the Learner**
@@ -454,7 +454,7 @@ Create a training configuration file (example available [here](https://huggingfa
First, start the learner server process: First, start the learner server process:
```bash ```bash
python lerobot/scripts/rl/learner.py --config_path lerobot/configs/train_config_hilserl_so100.json python -m lerobot.scripts.rl.learner --config_path src/lerobot/configs/train_config_hilserl_so100.json
``` ```
The learner: The learner:
@@ -468,7 +468,7 @@ The learner:
In a separate terminal, start the actor process with the same configuration: In a separate terminal, start the actor process with the same configuration:
```bash ```bash
python lerobot/scripts/rl/actor.py --config_path lerobot/configs/train_config_hilserl_so100.json python -m lerobot.scripts.rl.actor --config_path src/lerobot/configs/train_config_hilserl_so100.json
``` ```
The actor: The actor:

View File

@@ -77,7 +77,7 @@ Important parameters:
To run the environment, set mode to null: To run the environment, set mode to null:
```python ```python
python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/gym_hil_env.json python -m lerobot.scripts.rl.gym_manipulator --config_path path/to/gym_hil_env.json
``` ```
### Recording a Dataset ### Recording a Dataset
@@ -85,7 +85,7 @@ python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/gym_hil_env.j
To collect a dataset, set the mode to `record` whilst defining the repo_id and number of episodes to record: To collect a dataset, set the mode to `record` whilst defining the repo_id and number of episodes to record:
```python ```python
python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/gym_hil_env.json python -m lerobot.scripts.rl.gym_manipulator --config_path path/to/gym_hil_env.json
``` ```
### Training a Policy ### Training a Policy
@@ -93,13 +93,13 @@ python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/gym_hil_env.j
To train a policy, checkout the configuration example available [here](https://huggingface.co/datasets/aractingi/lerobot-example-config-files/blob/main/train_gym_hil_env.json) and run the actor and learner servers: To train a policy, checkout the configuration example available [here](https://huggingface.co/datasets/aractingi/lerobot-example-config-files/blob/main/train_gym_hil_env.json) and run the actor and learner servers:
```python ```python
python lerobot/scripts/rl/actor.py --config_path path/to/train_gym_hil_env.json python -m lerobot.scripts.rl.actor --config_path path/to/train_gym_hil_env.json
``` ```
In a different terminal, run the learner server: In a different terminal, run the learner server:
```python ```python
python lerobot/scripts/rl/learner.py --config_path path/to/train_gym_hil_env.json python -m lerobot.scripts.rl.learner --config_path path/to/train_gym_hil_env.json
``` ```
The simulation environment provides a safe and repeatable way to develop and test your Human-In-the-Loop reinforcement learning components before deploying to real robots. The simulation environment provides a safe and repeatable way to develop and test your Human-In-the-Loop reinforcement learning components before deploying to real robots.

View File

@@ -52,8 +52,8 @@ python -m lerobot.teleoperate \
</hfoption> </hfoption>
<hfoption id="API example"> <hfoption id="API example">
```python ```python
from lerobot.common.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader from lerobot.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader
from lerobot.common.robots.so101_follower import SO101FollowerConfig, SO101Follower from lerobot.robots.so101_follower import SO101FollowerConfig, SO101Follower
robot_config = SO101FollowerConfig( robot_config = SO101FollowerConfig(
port="/dev/tty.usbmodem58760431541", port="/dev/tty.usbmodem58760431541",
@@ -105,9 +105,9 @@ python -m lerobot.teleoperate \
</hfoption> </hfoption>
<hfoption id="API example"> <hfoption id="API example">
```python ```python
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.common.teleoperators.koch_leader import KochLeaderConfig, KochLeader from lerobot.teleoperators.koch_leader import KochLeaderConfig, KochLeader
from lerobot.common.robots.koch_follower import KochFollowerConfig, KochFollower from lerobot.robots.koch_follower import KochFollowerConfig, KochFollower
camera_config = { camera_config = {
"front": OpenCVCameraConfig(index_or_path=0, width=1920, height=1080, fps=30) "front": OpenCVCameraConfig(index_or_path=0, width=1920, height=1080, fps=30)
@@ -175,15 +175,15 @@ python -m lerobot.record \
</hfoption> </hfoption>
<hfoption id="API example"> <hfoption id="API example">
```python ```python
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.datasets.utils import hw_to_dataset_features from lerobot.datasets.utils import hw_to_dataset_features
from lerobot.common.robots.so100_follower import SO100Follower, SO100FollowerConfig from lerobot.robots.so100_follower import SO100Follower, SO100FollowerConfig
from lerobot.common.teleoperators.so100_leader.config_so100_leader import SO100LeaderConfig from lerobot.teleoperators.so100_leader.config_so100_leader import SO100LeaderConfig
from lerobot.common.teleoperators.so100_leader.so100_leader import SO100Leader from lerobot.teleoperators.so100_leader.so100_leader import SO100Leader
from lerobot.common.utils.control_utils import init_keyboard_listener from lerobot.utils.control_utils import init_keyboard_listener
from lerobot.common.utils.utils import log_say from lerobot.utils.utils import log_say
from lerobot.common.utils.visualization_utils import _init_rerun from lerobot.utils.visualization_utils import _init_rerun
from lerobot.record import record_loop from lerobot.record import record_loop
NUM_EPISODES = 5 NUM_EPISODES = 5
@@ -353,11 +353,11 @@ python -m lerobot.replay \
```python ```python
import time import time
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.robots.so100_follower.config_so100_follower import SO100FollowerConfig from lerobot.robots.so100_follower.config_so100_follower import SO100FollowerConfig
from lerobot.common.robots.so100_follower.so100_follower import SO100Follower from lerobot.robots.so100_follower.so100_follower import SO100Follower
from lerobot.common.utils.robot_utils import busy_wait from lerobot.utils.robot_utils import busy_wait
from lerobot.common.utils.utils import log_say from lerobot.utils.utils import log_say
episode_idx = 0 episode_idx = 0
@@ -389,9 +389,9 @@ Your robot should replicate movements similar to those you recorded. For example
## Train a policy ## Train a policy
To train a policy to control your robot, use the [`python lerobot/scripts/train.py`](../lerobot/scripts/train.py) script. A few arguments are required. Here is an example command: To train a policy to control your robot, use the [`python -m lerobot.scripts.train`](../src/lerobot/scripts/train.py) script. A few arguments are required. Here is an example command:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--dataset.repo_id=${HF_USER}/so101_test \ --dataset.repo_id=${HF_USER}/so101_test \
--policy.type=act \ --policy.type=act \
--output_dir=outputs/train/act_so101_test \ --output_dir=outputs/train/act_so101_test \
@@ -403,7 +403,7 @@ python lerobot/scripts/train.py \
Let's explain the command: Let's explain the command:
1. We provided the dataset as argument with `--dataset.repo_id=${HF_USER}/so101_test`. 1. We provided the dataset as argument with `--dataset.repo_id=${HF_USER}/so101_test`.
2. We provided the policy with `policy.type=act`. This loads configurations from [`configuration_act.py`](../lerobot/common/policies/act/configuration_act.py). Importantly, this policy will automatically adapt to the number of motor states, motor actions and cameras of your robot (e.g. `laptop` and `phone`) which have been saved in your dataset. 2. We provided the policy with `policy.type=act`. This loads configurations from [`configuration_act.py`](../src/lerobot/policies/act/configuration_act.py). Importantly, this policy will automatically adapt to the number of motor states, motor actions and cameras of your robot (e.g. `laptop` and `phone`) which have been saved in your dataset.
4. We provided `policy.device=cuda` since we are training on a Nvidia GPU, but you could use `policy.device=mps` to train on Apple silicon. 4. We provided `policy.device=cuda` since we are training on a Nvidia GPU, but you could use `policy.device=mps` to train on Apple silicon.
5. We provided `wandb.enable=true` to use [Weights and Biases](https://docs.wandb.ai/quickstart) for visualizing training plots. This is optional but if you use it, make sure you are logged in by running `wandb login`. 5. We provided `wandb.enable=true` to use [Weights and Biases](https://docs.wandb.ai/quickstart) for visualizing training plots. This is optional but if you use it, make sure you are logged in by running `wandb login`.
@@ -411,7 +411,7 @@ Training should take several hours. You will find checkpoints in `outputs/train/
To resume training from a checkpoint, below is an example command to resume from `last` checkpoint of the `act_so101_test` policy: To resume training from a checkpoint, below is an example command to resume from `last` checkpoint of the `act_so101_test` policy:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \ --config_path=outputs/train/act_so101_test/checkpoints/last/pretrained_model/train_config.json \
--resume=true --resume=true
``` ```
@@ -462,15 +462,15 @@ python -m lerobot.record \
</hfoption> </hfoption>
<hfoption id="API example"> <hfoption id="API example">
```python ```python
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.datasets.utils import hw_to_dataset_features from lerobot.datasets.utils import hw_to_dataset_features
from lerobot.common.policies.act.modeling_act import ACTPolicy from lerobot.policies.act.modeling_act import ACTPolicy
from lerobot.common.robots.so100_follower.config_so100_follower import SO100FollowerConfig from lerobot.robots.so100_follower.config_so100_follower import SO100FollowerConfig
from lerobot.common.robots.so100_follower.so100_follower import SO100Follower from lerobot.robots.so100_follower.so100_follower import SO100Follower
from lerobot.common.utils.control_utils import init_keyboard_listener from lerobot.utils.control_utils import init_keyboard_listener
from lerobot.common.utils.utils import log_say from lerobot.utils.utils import log_say
from lerobot.common.utils.visualization_utils import _init_rerun from lerobot.utils.visualization_utils import _init_rerun
from lerobot.record import record_loop from lerobot.record import record_loop
NUM_EPISODES = 5 NUM_EPISODES = 5

View File

@@ -35,14 +35,14 @@ Then we can run this command to start:
<hfoption id="Linux"> <hfoption id="Linux">
```bash ```bash
python lerobot/scripts/rl/gym_manipulator.py --config_path path/to/env_config_gym_hil_il.json python -m lerobot.scripts.rl.gym_manipulator --config_path path/to/env_config_gym_hil_il.json
``` ```
</hfoption> </hfoption>
<hfoption id="MacOS"> <hfoption id="MacOS">
```bash ```bash
mjpython lerobot/scripts/rl/gym_manipulator.py --config_path path/to/env_config_gym_hil_il.json mjpython -m lerobot.scripts.rl.gym_manipulator --config_path path/to/env_config_gym_hil_il.json
``` ```
</hfoption> </hfoption>
@@ -81,9 +81,9 @@ If you uploaded your dataset to the hub you can [visualize your dataset online](
## Train a policy ## Train a policy
To train a policy to control your robot, use the [`python lerobot/scripts/train.py`](../lerobot/scripts/train.py) script. A few arguments are required. Here is an example command: To train a policy to control your robot, use the [`python -m lerobot.scripts.train`](../src/lerobot/scripts/train.py) script. A few arguments are required. Here is an example command:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--dataset.repo_id=${HF_USER}/il_gym \ --dataset.repo_id=${HF_USER}/il_gym \
--policy.type=act \ --policy.type=act \
--output_dir=outputs/train/il_sim_test \ --output_dir=outputs/train/il_sim_test \
@@ -94,7 +94,7 @@ python lerobot/scripts/train.py \
Let's explain the command: Let's explain the command:
1. We provided the dataset as argument with `--dataset.repo_id=${HF_USER}/il_gym`. 1. We provided the dataset as argument with `--dataset.repo_id=${HF_USER}/il_gym`.
2. We provided the policy with `policy.type=act`. This loads configurations from [`configuration_act.py`](../lerobot/common/policies/act/configuration_act.py). Importantly, this policy will automatically adapt to the number of motor states, motor actions and cameras of your robot (e.g. `laptop` and `phone`) which have been saved in your dataset. 2. We provided the policy with `policy.type=act`. This loads configurations from [`configuration_act.py`](../src/lerobot/policies/act/configuration_act.py). Importantly, this policy will automatically adapt to the number of motor states, motor actions and cameras of your robot (e.g. `laptop` and `phone`) which have been saved in your dataset.
4. We provided `policy.device=cuda` since we are training on a Nvidia GPU, but you could use `policy.device=mps` to train on Apple silicon. 4. We provided `policy.device=cuda` since we are training on a Nvidia GPU, but you could use `policy.device=mps` to train on Apple silicon.
5. We provided `wandb.enable=true` to use [Weights and Biases](https://docs.wandb.ai/quickstart) for visualizing training plots. This is optional but if you use it, make sure you are logged in by running `wandb login`. 5. We provided `wandb.enable=true` to use [Weights and Biases](https://docs.wandb.ai/quickstart) for visualizing training plots. This is optional but if you use it, make sure you are logged in by running `wandb login`.
@@ -130,14 +130,14 @@ Then you can run this command to visualize your trained policy
<hfoption id="Linux"> <hfoption id="Linux">
```bash ```bash
python lerobot/scripts/rl/eval_policy.py --config_path=path/to/eval_config_gym_hil.json python -m lerobot.scripts.rl.eval_policy --config_path=path/to/eval_config_gym_hil.json
``` ```
</hfoption> </hfoption>
<hfoption id="MacOS"> <hfoption id="MacOS">
```bash ```bash
mjpython lerobot/scripts/rl/eval_policy.py --config_path=path/to/eval_config_gym_hil.json mjpython -m lerobot.scripts.rl.eval_policy --config_path=path/to/eval_config_gym_hil.json
``` ```
</hfoption> </hfoption>

View File

@@ -2,7 +2,7 @@
This tutorial will explain how to integrate your own robot design into the LeRobot ecosystem and have it access all of our tools (data collection, control pipelines, policy training and inference). This tutorial will explain how to integrate your own robot design into the LeRobot ecosystem and have it access all of our tools (data collection, control pipelines, policy training and inference).
To that end, we provide the [`Robot`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/robots/robot.py) base class in the LeRobot which specifies a standard interface for physical robot integration. Let's see how to implement it. To that end, we provide the [`Robot`](https://github.com/huggingface/lerobot/blob/main/lerobot/robots/robot.py) base class in the LeRobot which specifies a standard interface for physical robot integration. Let's see how to implement it.
## Prerequisites ## Prerequisites
@@ -14,11 +14,11 @@ To that end, we provide the [`Robot`](https://github.com/huggingface/lerobot/blo
If you're using Feetech or Dynamixel motors, LeRobot provides built-in bus interfaces: If you're using Feetech or Dynamixel motors, LeRobot provides built-in bus interfaces:
- [`FeetechMotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/motors/feetech/feetech.py) for controlling Feetech servos - [`FeetechMotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/motors/feetech/feetech.py) for controlling Feetech servos
- [`DynamixelMotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/motors/dynamixel/dynamixel.py) for controlling Dynamixel servos - [`DynamixelMotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/motors/dynamixel/dynamixel.py) for controlling Dynamixel servos
Please refer to the [`MotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/motors/motors_bus.py) abstract class to learn about its API. Please refer to the [`MotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/motors/motors_bus.py) abstract class to learn about its API.
For a good example of how it can be used, you can have a look at our own [SO101 follower implementation](https://github.com/huggingface/lerobot/blob/main/lerobot/common/robots/so101_follower/so101_follower.py) For a good example of how it can be used, you can have a look at our own [SO101 follower implementation](https://github.com/huggingface/lerobot/blob/main/lerobot/robots/so101_follower/so101_follower.py)
Use these if compatible. Otherwise, you'll need to find or write a Python interface (not covered in this tutorial): Use these if compatible. Otherwise, you'll need to find or write a Python interface (not covered in this tutorial):
- Find an existing SDK in Python (or use bindings to C/C++) - Find an existing SDK in Python (or use bindings to C/C++)
@@ -32,7 +32,7 @@ For Feetech and Dynamixel, we currently support these servos:
- SCS series (protocol 1): `scs0009` - SCS series (protocol 1): `scs0009`
- Dynamixel (protocol 2.0 only): `xl330-m077`, `xl330-m288`, `xl430-w250`, `xm430-w350`, `xm540-w270`, `xc430-w150` - Dynamixel (protocol 2.0 only): `xl330-m077`, `xl330-m288`, `xl430-w250`, `xm430-w350`, `xm540-w270`, `xc430-w150`
If you are using Feetech or Dynamixel servos that are not in this list, you can add those in the [Feetech table](https://github.com/huggingface/lerobot/blob/main/lerobot/common/motors/feetech/tables.py) or [Dynamixel table](https://github.com/huggingface/lerobot/blob/main/lerobot/common/motors/dynamixel/tables.py). Depending on the model, this will require you to add model-specific information. In most cases though, there shouldn't be a lot of additions to do. If you are using Feetech or Dynamixel servos that are not in this list, you can add those in the [Feetech table](https://github.com/huggingface/lerobot/blob/main/lerobot/motors/feetech/tables.py) or [Dynamixel table](https://github.com/huggingface/lerobot/blob/main/lerobot/motors/dynamixel/tables.py). Depending on the model, this will require you to add model-specific information. In most cases though, there shouldn't be a lot of additions to do.
In the next sections, we'll use a `FeetechMotorsBus` as the motors interface for the examples. Replace it and adapt to your motors if necessary. In the next sections, we'll use a `FeetechMotorsBus` as the motors interface for the examples. Replace it and adapt to your motors if necessary.
@@ -44,9 +44,9 @@ Here, we'll add the port name and one camera by default for our robot:
```python ```python
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.common.cameras import CameraConfig from lerobot.cameras import CameraConfig
from lerobot.common.cameras.opencv import OpenCVCameraConfig from lerobot.cameras.opencv import OpenCVCameraConfig
from lerobot.common.robots import RobotConfig from lerobot.robots import RobotConfig
@RobotConfig.register_subclass("my_cool_robot") @RobotConfig.register_subclass("my_cool_robot")
@@ -72,10 +72,10 @@ Next, we'll create our actual robot class which inherits from `Robot`. This abst
Here we'll create a simple 5-DoF robot with one camera. It could be a simple arm but notice that the `Robot` abstract class does not assume anything on your robot's form factor. You can let you imagination run wild when designing new robots! Here we'll create a simple 5-DoF robot with one camera. It could be a simple arm but notice that the `Robot` abstract class does not assume anything on your robot's form factor. You can let you imagination run wild when designing new robots!
```python ```python
from lerobot.common.cameras import make_cameras_from_configs from lerobot.cameras import make_cameras_from_configs
from lerobot.common.motors import Motor, MotorNormMode from lerobot.motors import Motor, MotorNormMode
from lerobot.common.motors.feetech import FeetechMotorsBus from lerobot.motors.feetech import FeetechMotorsBus
from lerobot.common.robots import Robot from lerobot.robots import Robot
class MyCoolRobot(Robot): class MyCoolRobot(Robot):
config_class = MyCoolRobotConfig config_class = MyCoolRobotConfig
@@ -303,7 +303,7 @@ def send_action(self, action: dict[str, Any]) -> dict[str, Any]:
## Adding a Teleoperator ## Adding a Teleoperator
For implementing teleoperation devices, we also provide a [`Teleoperator`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/teleoperators/teleoperator.py) base class. This class is very similar to the `Robot` base class and also doesn't assume anything on form factor. For implementing teleoperation devices, we also provide a [`Teleoperator`](https://github.com/huggingface/lerobot/blob/main/lerobot/teleoperators/teleoperator.py) base class. This class is very similar to the `Robot` base class and also doesn't assume anything on form factor.
The main differences are in the I/O functions: a teleoperator allows you to produce action via `get_action` and can receive feedback actions via `send_feedback`. Feedback could be anything controllable on the teleoperation device that could help the person controlling it understand the consequences of the actions sent. Think motion/force feedback on a leader arm, vibrations on a gamepad controller for example. To implement a teleoperator, you can follow this same tutorial and adapt it for these two methods. The main differences are in the I/O functions: a teleoperator allows you to produce action via `get_action` and can receive feedback actions via `send_feedback`. Feedback could be anything controllable on the teleoperation device that could help the person controlling it understand the consequences of the actions sent. Think motion/force feedback on a leader arm, vibrations on a gamepad controller for example. To implement a teleoperator, you can follow this same tutorial and adapt it for these two methods.

View File

@@ -1 +1 @@
../../lerobot/common/robots/koch_follower/koch.mdx ../../src/lerobot/robots/koch_follower/koch.mdx

View File

@@ -1 +1 @@
../../lerobot/common/robots/lekiwi/lekiwi.mdx ../../src/lerobot/robots/lekiwi/lekiwi.mdx

View File

@@ -44,7 +44,7 @@ If you don't have a gpu device, you can train using our notebook on [![Google Co
Pass your dataset to the training script using `--dataset.repo_id`. If you want to test your installation, run the following command where we use one of the datasets we collected for the [SmolVLA Paper](https://huggingface.co/papers/2506.01844). Pass your dataset to the training script using `--dataset.repo_id`. If you want to test your installation, run the following command where we use one of the datasets we collected for the [SmolVLA Paper](https://huggingface.co/papers/2506.01844).
```bash ```bash
cd lerobot && python lerobot/scripts/train.py \ cd lerobot && python -m lerobot.scripts.train \
--policy.path=lerobot/smolvla_base \ --policy.path=lerobot/smolvla_base \
--dataset.repo_id=${HF_USER}/mydataset \ --dataset.repo_id=${HF_USER}/mydataset \
--batch_size=64 \ --batch_size=64 \
@@ -62,7 +62,7 @@ You can start with a small batch size and increase it incrementally, if the GPU
Fine-tuning is an art. For a complete overview of the options for finetuning, run Fine-tuning is an art. For a complete overview of the options for finetuning, run
```bash ```bash
python lerobot/scripts/train.py --help python -m lerobot.scripts.train --help
``` ```
<p align="center"> <p align="center">

View File

@@ -1 +1 @@
../../lerobot/common/robots/so100_follower/so100.mdx ../../src/lerobot/robots/so100_follower/so100.mdx

View File

@@ -1 +1 @@
../../lerobot/common/robots/so101_follower/so101.mdx ../../src/lerobot/robots/so101_follower/so101.mdx

View File

@@ -32,7 +32,7 @@ import torch
from huggingface_hub import HfApi from huggingface_hub import HfApi
import lerobot import lerobot
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
# We ported a number of existing datasets ourselves, use this to see the list: # We ported a number of existing datasets ourselves, use this to see the list:
print("List of available datasets:") print("List of available datasets:")

View File

@@ -30,7 +30,7 @@ import imageio
import numpy import numpy
import torch import torch
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy
# Create a directory to store the video of the evaluation # Create a directory to store the video of the evaluation
output_directory = Path("outputs/eval/example_pusht_diffusion") output_directory = Path("outputs/eval/example_pusht_diffusion")

View File

@@ -22,11 +22,11 @@ from pathlib import Path
import torch import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
from lerobot.common.datasets.utils import dataset_to_policy_features
from lerobot.common.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy
from lerobot.configs.types import FeatureType from lerobot.configs.types import FeatureType
from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
from lerobot.datasets.utils import dataset_to_policy_features
from lerobot.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy
def main(): def main():

View File

@@ -4,7 +4,7 @@ This tutorial will explain the training script, how to use it, and particularly
## The training script ## The training script
LeRobot offers a training script at [`lerobot/scripts/train.py`](../lerobot/scripts/train.py). At a high level it does the following: LeRobot offers a training script at [`lerobot/scripts/train.py`](../src/lerobot/scripts/train.py). At a high level it does the following:
- Initialize/load a configuration for the following steps using. - Initialize/load a configuration for the following steps using.
- Instantiates a dataset. - Instantiates a dataset.
@@ -21,7 +21,7 @@ In the training script, the main function `train` expects a `TrainPipelineConfig
def train(cfg: TrainPipelineConfig): def train(cfg: TrainPipelineConfig):
``` ```
You can inspect the `TrainPipelineConfig` defined in [`lerobot/configs/train.py`](../lerobot/configs/train.py) (which is heavily commented and meant to be a reference to understand any option) You can inspect the `TrainPipelineConfig` defined in [`lerobot/configs/train.py`](../src/lerobot/configs/train.py) (which is heavily commented and meant to be a reference to understand any option)
When running the script, inputs for the command line are parsed thanks to the `@parser.wrap()` decorator and an instance of this class is automatically generated. Under the hood, this is done with [Draccus](https://github.com/dlwh/draccus) which is a tool dedicated to this purpose. If you're familiar with Hydra, Draccus can similarly load configurations from config files (.json, .yaml) and also override their values through command line inputs. Unlike Hydra, these configurations are pre-defined in the code through dataclasses rather than being defined entirely in config files. This allows for more rigorous serialization/deserialization, typing, and to manipulate configuration as objects directly in the code and not as dictionaries or namespaces (which enables nice features in an IDE such as autocomplete, jump-to-def, etc.) When running the script, inputs for the command line are parsed thanks to the `@parser.wrap()` decorator and an instance of this class is automatically generated. Under the hood, this is done with [Draccus](https://github.com/dlwh/draccus) which is a tool dedicated to this purpose. If you're familiar with Hydra, Draccus can similarly load configurations from config files (.json, .yaml) and also override their values through command line inputs. Unlike Hydra, these configurations are pre-defined in the code through dataclasses rather than being defined entirely in config files. This allows for more rigorous serialization/deserialization, typing, and to manipulate configuration as objects directly in the code and not as dictionaries or namespaces (which enables nice features in an IDE such as autocomplete, jump-to-def, etc.)
@@ -50,9 +50,9 @@ By default, every field takes its default value specified in the dataclass. If a
## Specifying values from the CLI ## Specifying values from the CLI
Let's say that we want to train [Diffusion Policy](../lerobot/common/policies/diffusion) on the [pusht](https://huggingface.co/datasets/lerobot/pusht) dataset, using the [gym_pusht](https://github.com/huggingface/gym-pusht) environment for evaluation. The command to do so would look like this: Let's say that we want to train [Diffusion Policy](../src/lerobot/policies/diffusion) on the [pusht](https://huggingface.co/datasets/lerobot/pusht) dataset, using the [gym_pusht](https://github.com/huggingface/gym-pusht) environment for evaluation. The command to do so would look like this:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--dataset.repo_id=lerobot/pusht \ --dataset.repo_id=lerobot/pusht \
--policy.type=diffusion \ --policy.type=diffusion \
--env.type=pusht --env.type=pusht
@@ -60,12 +60,12 @@ python lerobot/scripts/train.py \
Let's break this down: Let's break this down:
- To specify the dataset, we just need to specify its `repo_id` on the hub which is the only required argument in the `DatasetConfig`. The rest of the fields have default values and in this case we are fine with those so we can just add the option `--dataset.repo_id=lerobot/pusht`. - To specify the dataset, we just need to specify its `repo_id` on the hub which is the only required argument in the `DatasetConfig`. The rest of the fields have default values and in this case we are fine with those so we can just add the option `--dataset.repo_id=lerobot/pusht`.
- To specify the policy, we can just select diffusion policy using `--policy` appended with `.type`. Here, `.type` is a special argument which allows us to select config classes inheriting from `draccus.ChoiceRegistry` and that have been decorated with the `register_subclass()` method. To have a better explanation of this feature, have a look at this [Draccus demo](https://github.com/dlwh/draccus?tab=readme-ov-file#more-flexible-configuration-with-choice-types). In our code, we use this mechanism mainly to select policies, environments, robots, and some other components like optimizers. The policies available to select are located in [lerobot/common/policies](../lerobot/common/policies) - To specify the policy, we can just select diffusion policy using `--policy` appended with `.type`. Here, `.type` is a special argument which allows us to select config classes inheriting from `draccus.ChoiceRegistry` and that have been decorated with the `register_subclass()` method. To have a better explanation of this feature, have a look at this [Draccus demo](https://github.com/dlwh/draccus?tab=readme-ov-file#more-flexible-configuration-with-choice-types). In our code, we use this mechanism mainly to select policies, environments, robots, and some other components like optimizers. The policies available to select are located in [lerobot/policies](../src/lerobot/policies)
- Similarly, we select the environment with `--env.type=pusht`. The different environment configs are available in [`lerobot/common/envs/configs.py`](../lerobot/common/envs/configs.py) - Similarly, we select the environment with `--env.type=pusht`. The different environment configs are available in [`lerobot/envs/configs.py`](../src/lerobot/envs/configs.py)
Let's see another example. Let's say you've been training [ACT](../lerobot/common/policies/act) on [lerobot/aloha_sim_insertion_human](https://huggingface.co/datasets/lerobot/aloha_sim_insertion_human) using the [gym-aloha](https://github.com/huggingface/gym-aloha) environment for evaluation with: Let's see another example. Let's say you've been training [ACT](../src/lerobot/policies/act) on [lerobot/aloha_sim_insertion_human](https://huggingface.co/datasets/lerobot/aloha_sim_insertion_human) using the [gym-aloha](https://github.com/huggingface/gym-aloha) environment for evaluation with:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=act \ --policy.type=act \
--dataset.repo_id=lerobot/aloha_sim_insertion_human \ --dataset.repo_id=lerobot/aloha_sim_insertion_human \
--env.type=aloha \ --env.type=aloha \
@@ -74,9 +74,9 @@ python lerobot/scripts/train.py \
> Notice we added `--output_dir` to explicitly tell where to write outputs from this run (checkpoints, training state, configs etc.). This is not mandatory and if you don't specify it, a default directory will be created from the current date and time, env.type and policy.type. This will typically look like `outputs/train/2025-01-24/16-10-05_aloha_act`. > Notice we added `--output_dir` to explicitly tell where to write outputs from this run (checkpoints, training state, configs etc.). This is not mandatory and if you don't specify it, a default directory will be created from the current date and time, env.type and policy.type. This will typically look like `outputs/train/2025-01-24/16-10-05_aloha_act`.
We now want to train a different policy for aloha on another task. We'll change the dataset and use [lerobot/aloha_sim_transfer_cube_human](https://huggingface.co/datasets/lerobot/aloha_sim_transfer_cube_human) instead. Of course, we also need to change the task of the environment as well to match this other task. We now want to train a different policy for aloha on another task. We'll change the dataset and use [lerobot/aloha_sim_transfer_cube_human](https://huggingface.co/datasets/lerobot/aloha_sim_transfer_cube_human) instead. Of course, we also need to change the task of the environment as well to match this other task.
Looking at the [`AlohaEnv`](../lerobot/common/envs/configs.py) config, the task is `"AlohaInsertion-v0"` by default, which corresponds to the task we trained on in the command above. The [gym-aloha](https://github.com/huggingface/gym-aloha?tab=readme-ov-file#description) environment also has the `AlohaTransferCube-v0` task which corresponds to this other task we want to train on. Putting this together, we can train this new policy on this different task using: Looking at the [`AlohaEnv`](../src/lerobot/envs/configs.py) config, the task is `"AlohaInsertion-v0"` by default, which corresponds to the task we trained on in the command above. The [gym-aloha](https://github.com/huggingface/gym-aloha?tab=readme-ov-file#description) environment also has the `AlohaTransferCube-v0` task which corresponds to this other task we want to train on. Putting this together, we can train this new policy on this different task using:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=act \ --policy.type=act \
--dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \ --dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \
--env.type=aloha \ --env.type=aloha \
@@ -111,7 +111,7 @@ Now, let's assume that we want to reproduce the run just above. That run has pro
We can then simply load the config values from this file using: We can then simply load the config values from this file using:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \ --config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \
--output_dir=outputs/train/act_aloha_transfer_2 --output_dir=outputs/train/act_aloha_transfer_2
``` ```
@@ -119,7 +119,7 @@ python lerobot/scripts/train.py \
Similarly to Hydra, we can still override some parameters in the CLI if we want to, e.g.: Similarly to Hydra, we can still override some parameters in the CLI if we want to, e.g.:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \ --config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \
--output_dir=outputs/train/act_aloha_transfer_2 --output_dir=outputs/train/act_aloha_transfer_2
--policy.n_action_steps=80 --policy.n_action_steps=80
@@ -128,7 +128,7 @@ python lerobot/scripts/train.py \
`--config_path` can also accept the repo_id of a repo on the hub that contains a `train_config.json` file, e.g. running: `--config_path` can also accept the repo_id of a repo on the hub that contains a `train_config.json` file, e.g. running:
```bash ```bash
python lerobot/scripts/train.py --config_path=lerobot/diffusion_pusht python -m lerobot.scripts.train --config_path=lerobot/diffusion_pusht
``` ```
will start a training run with the same configuration used for training [lerobot/diffusion_pusht](https://huggingface.co/lerobot/diffusion_pusht) will start a training run with the same configuration used for training [lerobot/diffusion_pusht](https://huggingface.co/lerobot/diffusion_pusht)
@@ -139,7 +139,7 @@ Being able to resume a training run is important in case it crashed or aborted f
Let's reuse the command from the previous run and add a few more options: Let's reuse the command from the previous run and add a few more options:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=act \ --policy.type=act \
--dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \ --dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \
--env.type=aloha \ --env.type=aloha \
@@ -155,7 +155,7 @@ INFO 2025-01-24 16:10:56 ts/train.py:263 Checkpoint policy after step 100
``` ```
Now let's simulate a crash by killing the process (hit `ctrl`+`c`). We can then simply resume this run from the last checkpoint available with: Now let's simulate a crash by killing the process (hit `ctrl`+`c`). We can then simply resume this run from the last checkpoint available with:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \ --config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \
--resume=true --resume=true
``` ```
@@ -164,7 +164,7 @@ You should see from the logging that your training picks up from where it left o
Another reason for which you might want to resume a run is simply to extend training and add more training steps. The number of training steps is set by the option `--steps`, which is 100 000 by default. Another reason for which you might want to resume a run is simply to extend training and add more training steps. The number of training steps is set by the option `--steps`, which is 100 000 by default.
You could double the number of steps of the previous run with: You could double the number of steps of the previous run with:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \ --config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \
--resume=true \ --resume=true \
--steps=200000 --steps=200000
@@ -195,7 +195,7 @@ In addition to the features currently in Draccus, we've added a special `.path`
For example, we could fine-tune a [policy pre-trained on the aloha transfer task](https://huggingface.co/lerobot/act_aloha_sim_transfer_cube_human) on the aloha insertion task. We can achieve this with: For example, we could fine-tune a [policy pre-trained on the aloha transfer task](https://huggingface.co/lerobot/act_aloha_sim_transfer_cube_human) on the aloha insertion task. We can achieve this with:
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.path=lerobot/act_aloha_sim_transfer_cube_human \ --policy.path=lerobot/act_aloha_sim_transfer_cube_human \
--dataset.repo_id=lerobot/aloha_sim_insertion_human \ --dataset.repo_id=lerobot/aloha_sim_insertion_human \
--env.type=aloha \ --env.type=aloha \
@@ -236,7 +236,7 @@ We'll summarize here the main use cases to remember from this tutorial.
#### Train a policy from scratch CLI #### Train a policy from scratch CLI
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.type=act \ # <- select 'act' policy --policy.type=act \ # <- select 'act' policy
--env.type=pusht \ # <- select 'pusht' environment --env.type=pusht \ # <- select 'pusht' environment
--dataset.repo_id=lerobot/pusht # <- train on this dataset --dataset.repo_id=lerobot/pusht # <- train on this dataset
@@ -244,14 +244,14 @@ python lerobot/scripts/train.py \
#### Train a policy from scratch - config file + CLI #### Train a policy from scratch - config file + CLI
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=path/to/pretrained_model \ # <- can also be a repo_id --config_path=path/to/pretrained_model \ # <- can also be a repo_id
--policy.n_action_steps=80 # <- you may still override values --policy.n_action_steps=80 # <- you may still override values
``` ```
#### Resume/continue a training run #### Resume/continue a training run
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--config_path=checkpoint/pretrained_model/ \ --config_path=checkpoint/pretrained_model/ \
--resume=true \ --resume=true \
--steps=200000 # <- you can change some training parameters --steps=200000 # <- you can change some training parameters
@@ -259,7 +259,7 @@ python lerobot/scripts/train.py \
#### Fine-tuning #### Fine-tuning
```bash ```bash
python lerobot/scripts/train.py \ python -m lerobot.scripts.train \
--policy.path=lerobot/act_aloha_sim_transfer_cube_human \ # <- can also be a local path to a checkpoint --policy.path=lerobot/act_aloha_sim_transfer_cube_human \ # <- can also be a local path to a checkpoint
--dataset.repo_id=lerobot/aloha_sim_insertion_human \ --dataset.repo_id=lerobot/aloha_sim_insertion_human \
--env.type=aloha \ --env.type=aloha \

View File

@@ -22,7 +22,7 @@ from pathlib import Path
from torchvision.transforms import ToPILImage, v2 from torchvision.transforms import ToPILImage, v2
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
dataset_repo_id = "lerobot/aloha_static_screw_driver" dataset_repo_id = "lerobot/aloha_static_screw_driver"

View File

@@ -26,8 +26,8 @@ import math
import torch import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy
def main(): def main():

View File

@@ -35,8 +35,8 @@ from pprint import pformat
import draccus import draccus
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.robots import ( # noqa: F401 from lerobot.robots import ( # noqa: F401
Robot, Robot,
RobotConfig, RobotConfig,
koch_follower, koch_follower,
@@ -44,8 +44,8 @@ from lerobot.common.robots import ( # noqa: F401
so100_follower, so100_follower,
so101_follower, so101_follower,
) )
from lerobot.common.utils.robot_utils import busy_wait from lerobot.utils.robot_utils import busy_wait
from lerobot.common.utils.utils import ( from lerobot.utils.utils import (
init_logging, init_logging,
log_say, log_say,
) )

View File

@@ -1,8 +1,8 @@
from lerobot.common.datasets.utils import build_dataset_frame, hw_to_dataset_features from lerobot.datasets.utils import build_dataset_frame, hw_to_dataset_features
from lerobot.common.policies.act.modeling_act import ACTPolicy from lerobot.policies.act.modeling_act import ACTPolicy
from lerobot.common.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig from lerobot.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig
from lerobot.common.utils.control_utils import predict_action from lerobot.utils.control_utils import predict_action
from lerobot.common.utils.utils import get_safe_torch_device from lerobot.utils.utils import get_safe_torch_device
NB_CYCLES_CLIENT_CONNECTION = 1000 NB_CYCLES_CLIENT_CONNECTION = 1000

View File

@@ -1,11 +1,11 @@
import time import time
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.datasets.utils import hw_to_dataset_features from lerobot.datasets.utils import hw_to_dataset_features
from lerobot.common.robots.lekiwi.config_lekiwi import LeKiwiClientConfig from lerobot.robots.lekiwi.config_lekiwi import LeKiwiClientConfig
from lerobot.common.robots.lekiwi.lekiwi_client import LeKiwiClient from lerobot.robots.lekiwi.lekiwi_client import LeKiwiClient
from lerobot.common.teleoperators.keyboard import KeyboardTeleop, KeyboardTeleopConfig from lerobot.teleoperators.keyboard import KeyboardTeleop, KeyboardTeleopConfig
from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig from lerobot.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig
NB_CYCLES_CLIENT_CONNECTION = 250 NB_CYCLES_CLIENT_CONNECTION = 250

View File

@@ -1,9 +1,9 @@
import time import time
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.robots.lekiwi.config_lekiwi import LeKiwiClientConfig from lerobot.robots.lekiwi.config_lekiwi import LeKiwiClientConfig
from lerobot.common.robots.lekiwi.lekiwi_client import LeKiwiClient from lerobot.robots.lekiwi.lekiwi_client import LeKiwiClient
from lerobot.common.utils.robot_utils import busy_wait from lerobot.utils.robot_utils import busy_wait
robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="lekiwi") robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="lekiwi")
robot = LeKiwiClient(robot_config) robot = LeKiwiClient(robot_config)

View File

@@ -1,6 +1,6 @@
from lerobot.common.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig from lerobot.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig
from lerobot.common.teleoperators.keyboard.teleop_keyboard import KeyboardTeleop, KeyboardTeleopConfig from lerobot.teleoperators.keyboard.teleop_keyboard import KeyboardTeleop, KeyboardTeleopConfig
from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig from lerobot.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig
robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="my_lekiwi") robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="my_lekiwi")

View File

@@ -1,45 +0,0 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: lerobot/common/transport/services.proto
# Protobuf Python Version: 5.29.0
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
5,
29,
0,
'',
'lerobot/common/transport/services.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'lerobot/common/transport/services.proto\x12\ttransport\"L\n\nTransition\x12\x30\n\x0etransfer_state\x18\x01 \x01(\x0e\x32\x18.transport.TransferState\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"L\n\nParameters\x12\x30\n\x0etransfer_state\x18\x01 \x01(\x0e\x32\x18.transport.TransferState\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"T\n\x12InteractionMessage\x12\x30\n\x0etransfer_state\x18\x01 \x01(\x0e\x32\x18.transport.TransferState\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x07\n\x05\x45mpty*`\n\rTransferState\x12\x14\n\x10TRANSFER_UNKNOWN\x10\x00\x12\x12\n\x0eTRANSFER_BEGIN\x10\x01\x12\x13\n\x0fTRANSFER_MIDDLE\x10\x02\x12\x10\n\x0cTRANSFER_END\x10\x03\x32\x81\x02\n\x0eLearnerService\x12=\n\x10StreamParameters\x12\x10.transport.Empty\x1a\x15.transport.Parameters0\x01\x12<\n\x0fSendTransitions\x12\x15.transport.Transition\x1a\x10.transport.Empty(\x01\x12\x45\n\x10SendInteractions\x12\x1d.transport.InteractionMessage\x1a\x10.transport.Empty(\x01\x12+\n\x05Ready\x12\x10.transport.Empty\x1a\x10.transport.Emptyb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'lerobot.common.transport.services_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
DESCRIPTOR._loaded_options = None
_globals['_TRANSFERSTATE']._serialized_start=305
_globals['_TRANSFERSTATE']._serialized_end=401
_globals['_TRANSITION']._serialized_start=54
_globals['_TRANSITION']._serialized_end=130
_globals['_PARAMETERS']._serialized_start=132
_globals['_PARAMETERS']._serialized_end=208
_globals['_INTERACTIONMESSAGE']._serialized_start=210
_globals['_INTERACTIONMESSAGE']._serialized_end=294
_globals['_EMPTY']._serialized_start=296
_globals['_EMPTY']._serialized_end=303
_globals['_LEARNERSERVICE']._serialized_start=404
_globals['_LEARNERSERVICE']._serialized_end=661
# @@protoc_insertion_point(module_scope)

View File

@@ -123,10 +123,10 @@ select = ["E4", "E7", "E9", "F", "I", "N", "B", "C4", "SIM"]
exclude_dirs = [ exclude_dirs = [
"tests", "tests",
"benchmarks", "benchmarks",
"lerobot/common/datasets/push_dataset_to_hub", "src/lerobot/datasets/push_dataset_to_hub",
"lerobot/common/datasets/v2/convert_dataset_v1_to_v2", "src/lerobot/datasets/v2/convert_dataset_v1_to_v2",
"lerobot/common/policies/pi0/conversion_scripts", "src/lerobot/policies/pi0/conversion_scripts",
"lerobot/scripts/push_dataset_to_hub.py", "src/lerobot/scripts/push_dataset_to_hub.py",
] ]
skips = ["B101", "B311", "B404", "B603"] skips = ["B101", "B311", "B404", "B603"]

View File

@@ -167,10 +167,10 @@ available_datasets = sorted(
set(itertools.chain(*available_datasets_per_env.values(), available_real_world_datasets)) set(itertools.chain(*available_datasets_per_env.values(), available_real_world_datasets))
) )
# lists all available policies from `lerobot/common/policies` # lists all available policies from `lerobot/policies`
available_policies = ["act", "diffusion", "tdmpc", "vqbet"] available_policies = ["act", "diffusion", "tdmpc", "vqbet"]
# lists all available robots from `lerobot/common/robot_devices/robots` # lists all available robots from `lerobot/robot_devices/robots`
available_robots = [ available_robots = [
"koch", "koch",
"koch_bimanual", "koch_bimanual",
@@ -179,13 +179,13 @@ available_robots = [
"so101", "so101",
] ]
# lists all available cameras from `lerobot/common/robot_devices/cameras` # lists all available cameras from `lerobot/robot_devices/cameras`
available_cameras = [ available_cameras = [
"opencv", "opencv",
"intelrealsense", "intelrealsense",
] ]
# lists all available motors from `lerobot/common/robot_devices/motors` # lists all available motors from `lerobot/robot_devices/motors`
available_motors = [ available_motors = [
"dynamixel", "dynamixel",
"feetech", "feetech",

View File

@@ -31,9 +31,9 @@ from pprint import pformat
import draccus import draccus
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401
from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401
from lerobot.common.robots import ( # noqa: F401 from lerobot.robots import ( # noqa: F401
Robot, Robot,
RobotConfig, RobotConfig,
koch_follower, koch_follower,
@@ -42,7 +42,7 @@ from lerobot.common.robots import ( # noqa: F401
so100_follower, so100_follower,
so101_follower, so101_follower,
) )
from lerobot.common.teleoperators import ( # noqa: F401 from lerobot.teleoperators import ( # noqa: F401
Teleoperator, Teleoperator,
TeleoperatorConfig, TeleoperatorConfig,
koch_leader, koch_leader,
@@ -50,7 +50,7 @@ from lerobot.common.teleoperators import ( # noqa: F401
so100_leader, so100_leader,
so101_leader, so101_leader,
) )
from lerobot.common.utils.utils import init_logging from lerobot.utils.utils import init_logging
@dataclass @dataclass

View File

@@ -27,7 +27,7 @@ from typing import Any, Dict, List
import cv2 import cv2
import numpy as np import numpy as np
from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError
from ..camera import Camera from ..camera import Camera
from ..utils import get_cv2_backend, get_cv2_rotation from ..utils import get_cv2_backend, get_cv2_rotation
@@ -64,8 +64,8 @@ class OpenCVCamera(Camera):
Example: Example:
```python ```python
from lerobot.common.cameras.opencv import OpenCVCamera from lerobot.cameras.opencv import OpenCVCamera
from lerobot.common.cameras.configuration_opencv import OpenCVCameraConfig, ColorMode, Cv2Rotation from lerobot.cameras.configuration_opencv import OpenCVCameraConfig, ColorMode, Cv2Rotation
# Basic usage with camera index 0 # Basic usage with camera index 0
config = OpenCVCameraConfig(index_or_path=0) config = OpenCVCameraConfig(index_or_path=0)

View File

@@ -29,7 +29,7 @@ try:
except Exception as e: except Exception as e:
logging.info(f"Could not import realsense: {e}") logging.info(f"Could not import realsense: {e}")
from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError
from ..camera import Camera from ..camera import Camera
from ..configs import ColorMode from ..configs import ColorMode
@@ -63,8 +63,8 @@ class RealSenseCamera(Camera):
Example: Example:
```python ```python
from lerobot.common.cameras.realsense import RealSenseCamera, RealSenseCameraConfig from lerobot.cameras.realsense import RealSenseCamera, RealSenseCameraConfig
from lerobot.common.cameras import ColorMode, Cv2Rotation from lerobot.cameras import ColorMode, Cv2Rotation
# Basic usage with serial number # Basic usage with serial number
config = RealSenseCameraConfig(serial_number_or_name="0123456789") # Replace with actual SN config = RealSenseCameraConfig(serial_number_or_name="0123456789") # Replace with actual SN

View File

@@ -16,11 +16,11 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.common import ( from lerobot import (
policies, # noqa: F401 policies, # noqa: F401
) )
from lerobot.common.datasets.transforms import ImageTransformsConfig from lerobot.datasets.transforms import ImageTransformsConfig
from lerobot.common.datasets.video_utils import get_safe_default_codec from lerobot.datasets.video_utils import get_safe_default_codec
@dataclass @dataclass

View File

@@ -17,7 +17,7 @@ import logging
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from lerobot.common import envs, policies # noqa: F401 from lerobot import envs, policies # noqa: F401
from lerobot.configs import parser from lerobot.configs import parser
from lerobot.configs.default import EvalConfig from lerobot.configs.default import EvalConfig
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig

View File

@@ -22,7 +22,7 @@ from typing import Sequence
import draccus import draccus
from lerobot.common.utils.utils import has_method from lerobot.utils.utils import has_method
PATH_KEY = "path" PATH_KEY = "path"
PLUGIN_DISCOVERY_SUFFIX = "discover_packages_path" PLUGIN_DISCOVERY_SUFFIX = "discover_packages_path"

View File

@@ -23,11 +23,11 @@ from huggingface_hub import hf_hub_download
from huggingface_hub.constants import CONFIG_NAME from huggingface_hub.constants import CONFIG_NAME
from huggingface_hub.errors import HfHubHTTPError from huggingface_hub.errors import HfHubHTTPError
from lerobot.common.optim.optimizers import OptimizerConfig
from lerobot.common.optim.schedulers import LRSchedulerConfig
from lerobot.common.utils.hub import HubMixin
from lerobot.common.utils.utils import auto_select_torch_device, is_amp_available, is_torch_device_available
from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature
from lerobot.optim.optimizers import OptimizerConfig
from lerobot.optim.schedulers import LRSchedulerConfig
from lerobot.utils.hub import HubMixin
from lerobot.utils.utils import auto_select_torch_device, is_amp_available, is_torch_device_available
# Generic variable that is either PreTrainedConfig or a subclass thereof # Generic variable that is either PreTrainedConfig or a subclass thereof
T = TypeVar("T", bound="PreTrainedConfig") T = TypeVar("T", bound="PreTrainedConfig")

View File

@@ -21,13 +21,13 @@ import draccus
from huggingface_hub import hf_hub_download from huggingface_hub import hf_hub_download
from huggingface_hub.errors import HfHubHTTPError from huggingface_hub.errors import HfHubHTTPError
from lerobot.common import envs from lerobot import envs
from lerobot.common.optim import OptimizerConfig
from lerobot.common.optim.schedulers import LRSchedulerConfig
from lerobot.common.utils.hub import HubMixin
from lerobot.configs import parser from lerobot.configs import parser
from lerobot.configs.default import DatasetConfig, EvalConfig, WandBConfig from lerobot.configs.default import DatasetConfig, EvalConfig, WandBConfig
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.optim import OptimizerConfig
from lerobot.optim.schedulers import LRSchedulerConfig
from lerobot.utils.hub import HubMixin
TRAIN_CONFIG_NAME = "train_config.json" TRAIN_CONFIG_NAME = "train_config.json"

View File

@@ -20,7 +20,7 @@ The dataset you requested ({repo_id}) is in {version} format.
We introduced a new format since v2.0 which is not backward compatible with v1.x. We introduced a new format since v2.0 which is not backward compatible with v1.x.
Please, use our conversion script. Modify the following command with your own task description: Please, use our conversion script. Modify the following command with your own task description:
``` ```
python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \\ python -m lerobot.datasets.v2.convert_dataset_v1_to_v2 \\
--repo-id {repo_id} \\ --repo-id {repo_id} \\
--single-task "TASK DESCRIPTION." # <---- /!\\ Replace TASK DESCRIPTION /!\\ --single-task "TASK DESCRIPTION." # <---- /!\\ Replace TASK DESCRIPTION /!\\
``` ```
@@ -40,7 +40,7 @@ The dataset you requested ({repo_id}) is in {version} format.
While current version of LeRobot is backward-compatible with it, the version of your dataset still uses global While current version of LeRobot is backward-compatible with it, the version of your dataset still uses global
stats instead of per-episode stats. Update your dataset stats to the new format using this command: stats instead of per-episode stats. Update your dataset stats to the new format using this command:
``` ```
python lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py --repo-id={repo_id} python -m lerobot.datasets.v21.convert_dataset_v20_to_v21 --repo-id={repo_id}
``` ```
If you encounter a problem, contact LeRobot maintainers on [Discord](https://discord.com/invite/s3KuuzsPFb) If you encounter a problem, contact LeRobot maintainers on [Discord](https://discord.com/invite/s3KuuzsPFb)

View File

@@ -15,7 +15,7 @@
# limitations under the License. # limitations under the License.
import numpy as np import numpy as np
from lerobot.common.datasets.utils import load_image_as_numpy from lerobot.datasets.utils import load_image_as_numpy
def estimate_num_samples( def estimate_num_samples(

View File

@@ -18,14 +18,14 @@ from pprint import pformat
import torch import torch
from lerobot.common.datasets.lerobot_dataset import ( from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.train import TrainPipelineConfig
from lerobot.datasets.lerobot_dataset import (
LeRobotDataset, LeRobotDataset,
LeRobotDatasetMetadata, LeRobotDatasetMetadata,
MultiLeRobotDataset, MultiLeRobotDataset,
) )
from lerobot.common.datasets.transforms import ImageTransforms from lerobot.datasets.transforms import ImageTransforms
from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.train import TrainPipelineConfig
IMAGENET_STATS = { IMAGENET_STATS = {
"mean": [[[0.485]], [[0.456]], [[0.406]]], # (c,1,1) "mean": [[[0.485]], [[0.456]], [[0.406]]], # (c,1,1)

View File

@@ -30,10 +30,10 @@ from huggingface_hub import HfApi, snapshot_download
from huggingface_hub.constants import REPOCARD_NAME from huggingface_hub.constants import REPOCARD_NAME
from huggingface_hub.errors import RevisionNotFoundError from huggingface_hub.errors import RevisionNotFoundError
from lerobot.common.constants import HF_LEROBOT_HOME from lerobot.constants import HF_LEROBOT_HOME
from lerobot.common.datasets.compute_stats import aggregate_stats, compute_episode_stats from lerobot.datasets.compute_stats import aggregate_stats, compute_episode_stats
from lerobot.common.datasets.image_writer import AsyncImageWriter, write_image from lerobot.datasets.image_writer import AsyncImageWriter, write_image
from lerobot.common.datasets.utils import ( from lerobot.datasets.utils import (
DEFAULT_FEATURES, DEFAULT_FEATURES,
DEFAULT_IMAGE_PATH, DEFAULT_IMAGE_PATH,
INFO_PATH, INFO_PATH,
@@ -65,7 +65,7 @@ from lerobot.common.datasets.utils import (
write_info, write_info,
write_json, write_json,
) )
from lerobot.common.datasets.video_utils import ( from lerobot.datasets.video_utils import (
VideoFrame, VideoFrame,
decode_video_frames, decode_video_frames,
encode_video_frames, encode_video_frames,
@@ -357,7 +357,7 @@ class LeRobotDataset(torch.utils.data.Dataset):
the dataset from that address and load it, pending your dataset is compliant with the dataset from that address and load it, pending your dataset is compliant with
codebase_version v2.0. If your dataset has been created before this new format, you will be codebase_version v2.0. If your dataset has been created before this new format, you will be
prompted to convert it using our conversion script from v1.6 to v2.0, which you can find at prompted to convert it using our conversion script from v1.6 to v2.0, which you can find at
lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py. lerobot/datasets/v2/convert_dataset_v1_to_v2.py.
2. Your dataset doesn't already exists (either on local disk or on the Hub): you can create an empty 2. Your dataset doesn't already exists (either on local disk or on the Hub): you can create an empty

View File

@@ -28,7 +28,7 @@ from typing import Any
import numpy as np import numpy as np
import torch import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
def _make_memmap_safe(**kwargs) -> np.memmap: def _make_memmap_safe(**kwargs) -> np.memmap:

View File

@@ -23,7 +23,7 @@ import numpy
import PIL import PIL
import torch import torch
from lerobot.common.datasets.video_utils import encode_video_frames from lerobot.datasets.video_utils import encode_video_frames
def concatenate_episodes(ep_dicts): def concatenate_episodes(ep_dicts):

View File

@@ -35,14 +35,14 @@ from huggingface_hub.errors import RevisionNotFoundError
from PIL import Image as PILImage from PIL import Image as PILImage
from torchvision import transforms from torchvision import transforms
from lerobot.common.datasets.backward_compatibility import ( from lerobot.configs.types import DictLike, FeatureType, PolicyFeature
from lerobot.datasets.backward_compatibility import (
V21_MESSAGE, V21_MESSAGE,
BackwardCompatibilityError, BackwardCompatibilityError,
ForwardCompatibilityError, ForwardCompatibilityError,
) )
from lerobot.common.robots import Robot from lerobot.robots import Robot
from lerobot.common.utils.utils import is_valid_numpy_dtype_string from lerobot.utils.utils import is_valid_numpy_dtype_string
from lerobot.configs.types import DictLike, FeatureType, PolicyFeature
DEFAULT_CHUNK_SIZE = 1000 # Max number of episodes per chunk DEFAULT_CHUNK_SIZE = 1000 # Max number of episodes per chunk
@@ -664,7 +664,7 @@ def create_lerobot_dataset_card(
**kwargs, **kwargs,
) -> DatasetCard: ) -> DatasetCard:
""" """
Keyword arguments will be used to replace values in ./lerobot/common/datasets/card_template.md. Keyword arguments will be used to replace values in src/lerobot/datasets/card_template.md.
Note: If specified, license must be one of https://huggingface.co/docs/hub/repositories-licenses. Note: If specified, license must be one of https://huggingface.co/docs/hub/repositories-licenses.
""" """
card_tags = ["LeRobot"] card_tags = ["LeRobot"]
@@ -687,7 +687,7 @@ def create_lerobot_dataset_card(
], ],
) )
card_template = (importlib.resources.files("lerobot.common.datasets") / "card_template.md").read_text() card_template = (importlib.resources.files("lerobot.datasets") / "card_template.md").read_text()
return DatasetCard.from_template( return DatasetCard.from_template(
card_data=card_data, card_data=card_data,

View File

@@ -26,8 +26,8 @@ from pathlib import Path
from textwrap import dedent from textwrap import dedent
from lerobot import available_datasets from lerobot import available_datasets
from lerobot.common.datasets.v2.convert_dataset_v1_to_v2 import convert_dataset from lerobot.datasets.v2.convert_dataset_v1_to_v2 import convert_dataset
from lerobot.common.robots.aloha.configuration_aloha import AlohaRobotConfig from lerobot.robots.aloha.configuration_aloha import AlohaRobotConfig
LOCAL_DIR = Path("data/") LOCAL_DIR = Path("data/")

View File

@@ -38,7 +38,7 @@ If your dataset contains a single task, you can simply provide it directly via t
Examples: Examples:
```bash ```bash
python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \ python -m lerobot.datasets.v2.convert_dataset_v1_to_v2 \
--repo-id lerobot/aloha_sim_insertion_human_image \ --repo-id lerobot/aloha_sim_insertion_human_image \
--single-task "Insert the peg into the socket." \ --single-task "Insert the peg into the socket." \
--robot-config lerobot/configs/robot/aloha.yaml \ --robot-config lerobot/configs/robot/aloha.yaml \
@@ -46,7 +46,7 @@ python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \
``` ```
```bash ```bash
python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \ python -m lerobot.datasets.v2.convert_dataset_v1_to_v2 \
--repo-id aliberts/koch_tutorial \ --repo-id aliberts/koch_tutorial \
--single-task "Pick the Lego block and drop it in the box on the right." \ --single-task "Pick the Lego block and drop it in the box on the right." \
--robot-config lerobot/configs/robot/koch.yaml \ --robot-config lerobot/configs/robot/koch.yaml \
@@ -63,7 +63,7 @@ If your dataset is a multi-task dataset, you have two options to provide the tas
Example: Example:
```bash ```bash
python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \ python -m lerobot.datasets.v2.convert_dataset_v1_to_v2 \
--repo-id lerobot/stanford_kuka_multimodal_dataset \ --repo-id lerobot/stanford_kuka_multimodal_dataset \
--tasks-col "language_instruction" \ --tasks-col "language_instruction" \
--local-dir data --local-dir data
@@ -92,7 +92,7 @@ parquet file, and you must provide this column's name with the '--tasks-col' arg
Example: Example:
```bash ```bash
python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \ python -m lerobot.datasets.v2.convert_dataset_v1_to_v2 \
--repo-id lerobot/stanford_kuka_multimodal_dataset \ --repo-id lerobot/stanford_kuka_multimodal_dataset \
--tasks-col "language_instruction" \ --tasks-col "language_instruction" \
--local-dir data --local-dir data
@@ -119,7 +119,7 @@ from huggingface_hub import HfApi
from huggingface_hub.errors import EntryNotFoundError, HfHubHTTPError from huggingface_hub.errors import EntryNotFoundError, HfHubHTTPError
from safetensors.torch import load_file from safetensors.torch import load_file
from lerobot.common.datasets.utils import ( from lerobot.datasets.utils import (
DEFAULT_CHUNK_SIZE, DEFAULT_CHUNK_SIZE,
DEFAULT_PARQUET_PATH, DEFAULT_PARQUET_PATH,
DEFAULT_VIDEO_PATH, DEFAULT_VIDEO_PATH,
@@ -136,12 +136,12 @@ from lerobot.common.datasets.utils import (
write_json, write_json,
write_jsonlines, write_jsonlines,
) )
from lerobot.common.datasets.video_utils import ( from lerobot.datasets.video_utils import (
VideoFrame, # noqa: F401 VideoFrame, # noqa: F401
get_image_pixel_channels, get_image_pixel_channels,
get_video_info, get_video_info,
) )
from lerobot.common.robots import RobotConfig from lerobot.robots import RobotConfig
V16 = "v1.6" V16 = "v1.6"
V20 = "v2.0" V20 = "v2.0"
@@ -602,19 +602,19 @@ def make_robot_config(robot_type: str, **kwargs) -> RobotConfig:
raise NotImplementedError # TODO raise NotImplementedError # TODO
elif robot_type == "koch_follower": elif robot_type == "koch_follower":
from lerobot.common.robots.koch_follower import KochFollowerConfig from lerobot.robots.koch_follower import KochFollowerConfig
return KochFollowerConfig(**kwargs) return KochFollowerConfig(**kwargs)
elif robot_type == "so100_follower": elif robot_type == "so100_follower":
from lerobot.common.robots.so100_follower import SO100FollowerConfig from lerobot.robots.so100_follower import SO100FollowerConfig
return SO100FollowerConfig(**kwargs) return SO100FollowerConfig(**kwargs)
elif robot_type == "stretch": elif robot_type == "stretch":
from lerobot.common.robots.stretch3 import Stretch3RobotConfig from lerobot.robots.stretch3 import Stretch3RobotConfig
return Stretch3RobotConfig(**kwargs) return Stretch3RobotConfig(**kwargs)
elif robot_type == "lekiwi": elif robot_type == "lekiwi":
from lerobot.common.robots.lekiwi import LeKiwiConfig from lerobot.robots.lekiwi import LeKiwiConfig
return LeKiwiConfig(**kwargs) return LeKiwiConfig(**kwargs)
else: else:

View File

@@ -20,9 +20,9 @@ from datasets import get_dataset_config_info
from huggingface_hub import HfApi from huggingface_hub import HfApi
from lerobot import available_datasets from lerobot import available_datasets
from lerobot.common.datasets.lerobot_dataset import LeRobotDatasetMetadata from lerobot.datasets.lerobot_dataset import LeRobotDatasetMetadata
from lerobot.common.datasets.utils import INFO_PATH, write_info from lerobot.datasets.utils import INFO_PATH, write_info
from lerobot.common.datasets.v21.convert_dataset_v20_to_v21 import V20, SuppressWarnings from lerobot.datasets.v21.convert_dataset_v20_to_v21 import V20, SuppressWarnings
LOCAL_DIR = Path("data/") LOCAL_DIR = Path("data/")

View File

@@ -24,7 +24,7 @@ from pathlib import Path
from huggingface_hub import HfApi from huggingface_hub import HfApi
from lerobot import available_datasets from lerobot import available_datasets
from lerobot.common.datasets.v21.convert_dataset_v20_to_v21 import V21, convert_dataset from lerobot.datasets.v21.convert_dataset_v20_to_v21 import V21, convert_dataset
LOCAL_DIR = Path("data/") LOCAL_DIR = Path("data/")

View File

@@ -25,7 +25,7 @@ This script will help you convert any LeRobot dataset already pushed to the hub
Usage: Usage:
```bash ```bash
python lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py \ python -m lerobot.datasets.v21.convert_dataset_v20_to_v21 \
--repo-id=aliberts/koch_tutorial --repo-id=aliberts/koch_tutorial
``` ```
@@ -36,9 +36,9 @@ import logging
from huggingface_hub import HfApi from huggingface_hub import HfApi
from lerobot.common.datasets.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset from lerobot.datasets.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset
from lerobot.common.datasets.utils import EPISODES_STATS_PATH, STATS_PATH, load_stats, write_info from lerobot.datasets.utils import EPISODES_STATS_PATH, STATS_PATH, load_stats, write_info
from lerobot.common.datasets.v21.convert_stats import check_aggregate_stats, convert_stats from lerobot.datasets.v21.convert_stats import check_aggregate_stats, convert_stats
V20 = "v2.0" V20 = "v2.0"
V21 = "v2.1" V21 = "v2.1"

View File

@@ -17,9 +17,9 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
import numpy as np import numpy as np
from tqdm import tqdm from tqdm import tqdm
from lerobot.common.datasets.compute_stats import aggregate_stats, get_feature_stats, sample_indices from lerobot.datasets.compute_stats import aggregate_stats, get_feature_stats, sample_indices
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.datasets.utils import write_episode_stats from lerobot.datasets.utils import write_episode_stats
def sample_episode_video_frames(dataset: LeRobotDataset, episode_index: int, ft_key: str) -> np.ndarray: def sample_episode_video_frames(dataset: LeRobotDataset, episode_index: int, ft_key: str) -> np.ndarray:

View File

@@ -18,10 +18,10 @@ from typing import Any, Optional
import draccus import draccus
from lerobot.common.constants import ACTION, OBS_ENV_STATE, OBS_IMAGE, OBS_IMAGES, OBS_STATE
from lerobot.common.robots import RobotConfig
from lerobot.common.teleoperators.config import TeleoperatorConfig
from lerobot.configs.types import FeatureType, PolicyFeature from lerobot.configs.types import FeatureType, PolicyFeature
from lerobot.constants import ACTION, OBS_ENV_STATE, OBS_IMAGE, OBS_IMAGES, OBS_STATE
from lerobot.robots import RobotConfig
from lerobot.teleoperators.config import TeleoperatorConfig
@dataclass @dataclass

View File

@@ -17,7 +17,7 @@ import importlib
import gymnasium as gym import gymnasium as gym
from lerobot.common.envs.configs import AlohaEnv, EnvConfig, HILEnvConfig, PushtEnv, XarmEnv from lerobot.envs.configs import AlohaEnv, EnvConfig, HILEnvConfig, PushtEnv, XarmEnv
def make_env_config(env_type: str, **kwargs) -> EnvConfig: def make_env_config(env_type: str, **kwargs) -> EnvConfig:

View File

@@ -22,9 +22,9 @@ import numpy as np
import torch import torch
from torch import Tensor from torch import Tensor
from lerobot.common.envs.configs import EnvConfig
from lerobot.common.utils.utils import get_channel_first_image_shape
from lerobot.configs.types import FeatureType, PolicyFeature from lerobot.configs.types import FeatureType, PolicyFeature
from lerobot.envs.configs import EnvConfig
from lerobot.utils.utils import get_channel_first_image_shape
def preprocess_observation(observations: dict[str, np.ndarray]) -> dict[str, Tensor]: def preprocess_observation(observations: dict[str, np.ndarray]) -> dict[str, Tensor]:

View File

@@ -37,11 +37,11 @@ from typing import Any, Dict, List
import numpy as np import numpy as np
from PIL import Image from PIL import Image
from lerobot.common.cameras.configs import ColorMode from lerobot.cameras.configs import ColorMode
from lerobot.common.cameras.opencv.camera_opencv import OpenCVCamera from lerobot.cameras.opencv.camera_opencv import OpenCVCamera
from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.common.cameras.realsense.camera_realsense import RealSenseCamera from lerobot.cameras.realsense.camera_realsense import RealSenseCamera
from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -22,7 +22,7 @@ import logging
from copy import deepcopy from copy import deepcopy
from enum import Enum from enum import Enum
from lerobot.common.utils.encoding_utils import decode_twos_complement, encode_twos_complement from lerobot.utils.encoding_utils import decode_twos_complement, encode_twos_complement
from ..motors_bus import Motor, MotorCalibration, MotorsBus, NameOrID, Value, get_address from ..motors_bus import Motor, MotorCalibration, MotorsBus, NameOrID, Value, get_address
from .tables import ( from .tables import (

View File

@@ -17,7 +17,7 @@ from copy import deepcopy
from enum import Enum from enum import Enum
from pprint import pformat from pprint import pformat
from lerobot.common.utils.encoding_utils import decode_sign_magnitude, encode_sign_magnitude from lerobot.utils.encoding_utils import decode_sign_magnitude, encode_sign_magnitude
from ..motors_bus import Motor, MotorCalibration, MotorsBus, NameOrID, Value, get_address from ..motors_bus import Motor, MotorCalibration, MotorsBus, NameOrID, Value, get_address
from .tables import ( from .tables import (

View File

@@ -32,8 +32,8 @@ import serial
from deepdiff import DeepDiff from deepdiff import DeepDiff
from tqdm import tqdm from tqdm import tqdm
from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError
from lerobot.common.utils.utils import enter_pressed, move_cursor_up from lerobot.utils.utils import enter_pressed, move_cursor_up
NameOrID: TypeAlias = str | int NameOrID: TypeAlias = str | int
Value: TypeAlias = int | float Value: TypeAlias = int | float
@@ -446,7 +446,7 @@ class MotorsBus(abc.ABC):
except (FileNotFoundError, OSError, serial.SerialException) as e: except (FileNotFoundError, OSError, serial.SerialException) as e:
raise ConnectionError( raise ConnectionError(
f"\nCould not connect on port '{self.port}'. Make sure you are using the correct port." f"\nCould not connect on port '{self.port}'. Make sure you are using the correct port."
"\nTry running `python lerobot/find_port.py`\n" "\nTry running `python -m lerobot.find_port`\n"
) from e ) from e
@abc.abstractmethod @abc.abstractmethod

View File

@@ -18,8 +18,8 @@
from torch.optim import Optimizer from torch.optim import Optimizer
from torch.optim.lr_scheduler import LRScheduler from torch.optim.lr_scheduler import LRScheduler
from lerobot.common.policies.pretrained import PreTrainedPolicy
from lerobot.configs.train import TrainPipelineConfig from lerobot.configs.train import TrainPipelineConfig
from lerobot.policies.pretrained import PreTrainedPolicy
def make_optimizer_and_scheduler( def make_optimizer_and_scheduler(

View File

@@ -22,12 +22,12 @@ import draccus
import torch import torch
from safetensors.torch import load_file, save_file from safetensors.torch import load_file, save_file
from lerobot.common.constants import ( from lerobot.constants import (
OPTIMIZER_PARAM_GROUPS, OPTIMIZER_PARAM_GROUPS,
OPTIMIZER_STATE, OPTIMIZER_STATE,
) )
from lerobot.common.datasets.utils import flatten_dict, unflatten_dict, write_json from lerobot.datasets.utils import flatten_dict, unflatten_dict, write_json
from lerobot.common.utils.io_utils import deserialize_json_into_object from lerobot.utils.io_utils import deserialize_json_into_object
@dataclass @dataclass

View File

@@ -22,9 +22,9 @@ import draccus
from torch.optim import Optimizer from torch.optim import Optimizer
from torch.optim.lr_scheduler import LambdaLR, LRScheduler from torch.optim.lr_scheduler import LambdaLR, LRScheduler
from lerobot.common.constants import SCHEDULER_STATE from lerobot.constants import SCHEDULER_STATE
from lerobot.common.datasets.utils import write_json from lerobot.datasets.utils import write_json
from lerobot.common.utils.io_utils import deserialize_json_into_object from lerobot.utils.io_utils import deserialize_json_into_object
@dataclass @dataclass

View File

@@ -15,9 +15,9 @@
# limitations under the License. # limitations under the License.
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.common.optim.optimizers import AdamWConfig
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.types import NormalizationMode from lerobot.configs.types import NormalizationMode
from lerobot.optim.optimizers import AdamWConfig
@PreTrainedConfig.register_subclass("act") @PreTrainedConfig.register_subclass("act")

View File

@@ -33,10 +33,10 @@ from torch import Tensor, nn
from torchvision.models._utils import IntermediateLayerGetter from torchvision.models._utils import IntermediateLayerGetter
from torchvision.ops.misc import FrozenBatchNorm2d from torchvision.ops.misc import FrozenBatchNorm2d
from lerobot.common.constants import ACTION, OBS_IMAGES from lerobot.constants import ACTION, OBS_IMAGES
from lerobot.common.policies.act.configuration_act import ACTConfig from lerobot.policies.act.configuration_act import ACTConfig
from lerobot.common.policies.normalize import Normalize, Unnormalize from lerobot.policies.normalize import Normalize, Unnormalize
from lerobot.common.policies.pretrained import PreTrainedPolicy from lerobot.policies.pretrained import PreTrainedPolicy
class ACTPolicy(PreTrainedPolicy): class ACTPolicy(PreTrainedPolicy):

View File

@@ -16,10 +16,10 @@
# limitations under the License. # limitations under the License.
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.common.optim.optimizers import AdamConfig
from lerobot.common.optim.schedulers import DiffuserSchedulerConfig
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.types import NormalizationMode from lerobot.configs.types import NormalizationMode
from lerobot.optim.optimizers import AdamConfig
from lerobot.optim.schedulers import DiffuserSchedulerConfig
@PreTrainedConfig.register_subclass("diffusion") @PreTrainedConfig.register_subclass("diffusion")

View File

@@ -33,11 +33,11 @@ from diffusers.schedulers.scheduling_ddim import DDIMScheduler
from diffusers.schedulers.scheduling_ddpm import DDPMScheduler from diffusers.schedulers.scheduling_ddpm import DDPMScheduler
from torch import Tensor, nn from torch import Tensor, nn
from lerobot.common.constants import ACTION, OBS_ENV_STATE, OBS_IMAGES, OBS_STATE from lerobot.constants import ACTION, OBS_ENV_STATE, OBS_IMAGES, OBS_STATE
from lerobot.common.policies.diffusion.configuration_diffusion import DiffusionConfig from lerobot.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.common.policies.normalize import Normalize, Unnormalize from lerobot.policies.normalize import Normalize, Unnormalize
from lerobot.common.policies.pretrained import PreTrainedPolicy from lerobot.policies.pretrained import PreTrainedPolicy
from lerobot.common.policies.utils import ( from lerobot.policies.utils import (
get_device_from_parameters, get_device_from_parameters,
get_dtype_from_parameters, get_dtype_from_parameters,
get_output_shape, get_output_shape,

View File

@@ -18,60 +18,60 @@ import logging
from torch import nn from torch import nn
from lerobot.common.datasets.lerobot_dataset import LeRobotDatasetMetadata
from lerobot.common.datasets.utils import dataset_to_policy_features
from lerobot.common.envs.configs import EnvConfig
from lerobot.common.envs.utils import env_to_policy_features
from lerobot.common.policies.act.configuration_act import ACTConfig
from lerobot.common.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.common.policies.pi0.configuration_pi0 import PI0Config
from lerobot.common.policies.pi0fast.configuration_pi0fast import PI0FASTConfig
from lerobot.common.policies.pretrained import PreTrainedPolicy
from lerobot.common.policies.sac.configuration_sac import SACConfig
from lerobot.common.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig
from lerobot.common.policies.smolvla.configuration_smolvla import SmolVLAConfig
from lerobot.common.policies.tdmpc.configuration_tdmpc import TDMPCConfig
from lerobot.common.policies.vqbet.configuration_vqbet import VQBeTConfig
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.types import FeatureType from lerobot.configs.types import FeatureType
from lerobot.datasets.lerobot_dataset import LeRobotDatasetMetadata
from lerobot.datasets.utils import dataset_to_policy_features
from lerobot.envs.configs import EnvConfig
from lerobot.envs.utils import env_to_policy_features
from lerobot.policies.act.configuration_act import ACTConfig
from lerobot.policies.diffusion.configuration_diffusion import DiffusionConfig
from lerobot.policies.pi0.configuration_pi0 import PI0Config
from lerobot.policies.pi0fast.configuration_pi0fast import PI0FASTConfig
from lerobot.policies.pretrained import PreTrainedPolicy
from lerobot.policies.sac.configuration_sac import SACConfig
from lerobot.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig
from lerobot.policies.smolvla.configuration_smolvla import SmolVLAConfig
from lerobot.policies.tdmpc.configuration_tdmpc import TDMPCConfig
from lerobot.policies.vqbet.configuration_vqbet import VQBeTConfig
def get_policy_class(name: str) -> PreTrainedPolicy: def get_policy_class(name: str) -> PreTrainedPolicy:
"""Get the policy's class and config class given a name (matching the policy class' `name` attribute).""" """Get the policy's class and config class given a name (matching the policy class' `name` attribute)."""
if name == "tdmpc": if name == "tdmpc":
from lerobot.common.policies.tdmpc.modeling_tdmpc import TDMPCPolicy from lerobot.policies.tdmpc.modeling_tdmpc import TDMPCPolicy
return TDMPCPolicy return TDMPCPolicy
elif name == "diffusion": elif name == "diffusion":
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy
return DiffusionPolicy return DiffusionPolicy
elif name == "act": elif name == "act":
from lerobot.common.policies.act.modeling_act import ACTPolicy from lerobot.policies.act.modeling_act import ACTPolicy
return ACTPolicy return ACTPolicy
elif name == "vqbet": elif name == "vqbet":
from lerobot.common.policies.vqbet.modeling_vqbet import VQBeTPolicy from lerobot.policies.vqbet.modeling_vqbet import VQBeTPolicy
return VQBeTPolicy return VQBeTPolicy
elif name == "pi0": elif name == "pi0":
from lerobot.common.policies.pi0.modeling_pi0 import PI0Policy from lerobot.policies.pi0.modeling_pi0 import PI0Policy
return PI0Policy return PI0Policy
elif name == "pi0fast": elif name == "pi0fast":
from lerobot.common.policies.pi0fast.modeling_pi0fast import PI0FASTPolicy from lerobot.policies.pi0fast.modeling_pi0fast import PI0FASTPolicy
return PI0FASTPolicy return PI0FASTPolicy
elif name == "sac": elif name == "sac":
from lerobot.common.policies.sac.modeling_sac import SACPolicy from lerobot.policies.sac.modeling_sac import SACPolicy
return SACPolicy return SACPolicy
elif name == "reward_classifier": elif name == "reward_classifier":
from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier from lerobot.policies.sac.reward_model.modeling_classifier import Classifier
return Classifier return Classifier
elif name == "smolvla": elif name == "smolvla":
from lerobot.common.policies.smolvla.modeling_smolvla import SmolVLAPolicy from lerobot.policies.smolvla.modeling_smolvla import SmolVLAPolicy
return SmolVLAPolicy return SmolVLAPolicy
else: else:

View File

@@ -14,12 +14,12 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from lerobot.common.optim.optimizers import AdamWConfig
from lerobot.common.optim.schedulers import (
CosineDecayWithWarmupSchedulerConfig,
)
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature
from lerobot.optim.optimizers import AdamWConfig
from lerobot.optim.schedulers import (
CosineDecayWithWarmupSchedulerConfig,
)
@PreTrainedConfig.register_subclass("pi0") @PreTrainedConfig.register_subclass("pi0")

View File

@@ -14,9 +14,9 @@
import torch import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDataset
from lerobot.common.policies.factory import make_policy
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.datasets.lerobot_dataset import LeRobotDataset
from lerobot.policies.factory import make_policy
torch.backends.cudnn.benchmark = True torch.backends.cudnn.benchmark = True

View File

@@ -18,9 +18,9 @@ from pathlib import Path
import torch import torch
from lerobot.common.datasets.lerobot_dataset import LeRobotDatasetMetadata
from lerobot.common.policies.factory import make_policy
from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.policies import PreTrainedConfig
from lerobot.datasets.lerobot_dataset import LeRobotDatasetMetadata
from lerobot.policies.factory import make_policy
def display(tensor: torch.Tensor): def display(tensor: torch.Tensor):
@@ -97,7 +97,7 @@ def main():
noise = torch.from_numpy(noise).to(device=device, dtype=torch.float32) noise = torch.from_numpy(noise).to(device=device, dtype=torch.float32)
from lerobot.common import policies # noqa from lerobot import policies # noqa
cfg = PreTrainedConfig.from_pretrained(ckpt_torch_dir) cfg = PreTrainedConfig.from_pretrained(ckpt_torch_dir)
cfg.pretrained_path = ckpt_torch_dir cfg.pretrained_path = ckpt_torch_dir

Some files were not shown because too many files have changed in this diff Show More