diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2e6fd44..df2e2db 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -24,7 +24,7 @@ Examples: pytest -sx tests/test_stuff.py::test_something ``` ```bash -python lerobot/scripts/train.py --some.option=true +python -m lerobot.scripts.train --some.option=true ``` ## SECTION TO REMOVE BEFORE SUBMITTING YOUR PR diff --git a/.github/workflows/nightly-tests.yml b/.github/workflows/nightly-tests.yml index be248b3..7280169 100644 --- a/.github/workflows/nightly-tests.yml +++ b/.github/workflows/nightly-tests.yml @@ -44,7 +44,7 @@ jobs: working-directory: /lerobot steps: - name: Tests - run: pytest -v --cov=./lerobot --disable-warnings tests + run: pytest -v --cov=./src/lerobot --disable-warnings tests - name: Tests end-to-end run: make test-end-to-end @@ -74,7 +74,7 @@ jobs: run: nvidia-smi - 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 # - name: Upload coverage reports to Codecov with GitHub Action # uses: codecov/codecov-action@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8822956..d6ea1d4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ name: Tests on: pull_request: paths: - - "lerobot/**" + - "src/**" - "tests/**" - "examples/**" - ".github/**" @@ -29,7 +29,7 @@ on: branches: - main paths: - - "lerobot/**" + - "src/**" - "tests/**" - "examples/**" - ".github/**" @@ -73,7 +73,7 @@ jobs: - name: Test with pytest 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::UserWarning:torch.utils.data.dataloader:558 \ -W ignore::UserWarning:gymnasium.utils.env_checker:247 \ @@ -105,7 +105,7 @@ jobs: - name: Test with pytest 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::UserWarning:torch.utils.data.dataloader:558 \ -W ignore::UserWarning:gymnasium.utils.env_checker:247 \ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23a1800..a354e13 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,7 +67,7 @@ post it. ## 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), [xarm](https://github.com/huggingface/gym-xarm), [pusht](https://github.com/huggingface/gym-pusht)) diff --git a/MANIFEST.in b/MANIFEST.in index d2608ca..c1fb2ea 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ -include lerobot/templates/lerobot_modelcard_template.md -include lerobot/common/datasets/card_template.md +include src/lerobot/templates/lerobot_modelcard_template.md +include src/lerobot/datasets/card_template.md diff --git a/Makefile b/Makefile index 9457dbe..ca1495f 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ test-end-to-end: ${MAKE} DEVICE=$(DEVICE) test-smolvla-ete-eval test-act-ete-train: - python lerobot/scripts/train.py \ + python -m lerobot.scripts.train \ --policy.type=act \ --policy.dim_model=64 \ --policy.n_action_steps=20 \ @@ -68,12 +68,12 @@ test-act-ete-train: --output_dir=tests/outputs/act/ 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 \ --resume=true test-act-ete-eval: - python lerobot/scripts/eval.py \ + python -m lerobot.scripts.eval \ --policy.path=tests/outputs/act/checkpoints/000004/pretrained_model \ --policy.device=$(DEVICE) \ --env.type=aloha \ @@ -82,7 +82,7 @@ test-act-ete-eval: --eval.batch_size=1 test-diffusion-ete-train: - python lerobot/scripts/train.py \ + python -m lerobot.scripts.train \ --policy.type=diffusion \ --policy.down_dims='[64,128,256]' \ --policy.diffusion_step_embed_dim=32 \ @@ -106,7 +106,7 @@ test-diffusion-ete-train: --output_dir=tests/outputs/diffusion/ test-diffusion-ete-eval: - python lerobot/scripts/eval.py \ + python -m lerobot.scripts.eval \ --policy.path=tests/outputs/diffusion/checkpoints/000002/pretrained_model \ --policy.device=$(DEVICE) \ --env.type=pusht \ @@ -115,7 +115,7 @@ test-diffusion-ete-eval: --eval.batch_size=1 test-tdmpc-ete-train: - python lerobot/scripts/train.py \ + python -m lerobot.scripts.train \ --policy.type=tdmpc \ --policy.device=$(DEVICE) \ --policy.push_to_hub=false \ @@ -137,7 +137,7 @@ test-tdmpc-ete-train: --output_dir=tests/outputs/tdmpc/ test-tdmpc-ete-eval: - python lerobot/scripts/eval.py \ + python -m lerobot.scripts.eval \ --policy.path=tests/outputs/tdmpc/checkpoints/000002/pretrained_model \ --policy.device=$(DEVICE) \ --env.type=xarm \ @@ -148,7 +148,7 @@ test-tdmpc-ete-eval: test-smolvla-ete-train: - python lerobot/scripts/train.py \ + python -m lerobot.scripts.train \ --policy.type=smolvla \ --policy.n_action_steps=20 \ --policy.chunk_size=20 \ @@ -171,7 +171,7 @@ test-smolvla-ete-train: --output_dir=tests/outputs/smolvla/ test-smolvla-ete-eval: - python lerobot/scripts/eval.py \ + python -m lerobot.scripts.eval \ --policy.path=tests/outputs/smolvla/checkpoints/000004/pretrained_model \ --policy.device=$(DEVICE) \ --env.type=aloha \ diff --git a/README.md b/README.md index 0939802..153a3a2 100644 --- a/README.md +++ b/README.md @@ -149,44 +149,20 @@ wandb login (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 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: ```bash -python lerobot/scripts/visualize_dataset.py \ +python -m lerobot.scripts.visualize_dataset \ --repo-id lerobot/pusht \ --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`) ```bash -python lerobot/scripts/visualize_dataset.py \ +python -m lerobot.scripts.visualize_dataset \ --repo-id lerobot/pusht \ --root ./my_local_data_dir \ --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 -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 @@ -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): ```bash -python lerobot/scripts/eval.py \ +python -m lerobot.scripts.eval \ --policy.path=lerobot/diffusion_pusht \ --env.type=pusht \ --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: ```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 @@ -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) -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) 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: ```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. @@ -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. -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 diff --git a/benchmarks/video/run_video_benchmark.py b/benchmarks/video/run_video_benchmark.py index 9d587ee..bababf6 100644 --- a/benchmarks/video/run_video_benchmark.py +++ b/benchmarks/video/run_video_benchmark.py @@ -35,12 +35,12 @@ import torch from skimage.metrics import mean_squared_error, peak_signal_noise_ratio, structural_similarity from tqdm import tqdm -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.video_utils import ( +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.video_utils import ( decode_video_frames_torchvision, encode_video_frames, ) -from lerobot.common.utils.benchmark import TimeBenchmark +from lerobot.utils.benchmark import TimeBenchmark BASE_ENCODING = OrderedDict( [ diff --git a/docs/source/cameras.mdx b/docs/source/cameras.mdx index d8a49c1..313d5a7 100644 --- a/docs/source/cameras.mdx +++ b/docs/source/cameras.mdx @@ -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: ```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: @@ -44,9 +44,9 @@ Below are two examples, demonstrating how to work with the API. ```python -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.common.cameras.opencv.camera_opencv import OpenCVCamera -from lerobot.common.cameras.configs import ColorMode, Cv2Rotation +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.cameras.opencv.camera_opencv import OpenCVCamera +from lerobot.cameras.configs import ColorMode, Cv2Rotation # Construct an `OpenCVCameraConfig` with your desired FPS, resolution, color mode, and rotation. config = OpenCVCameraConfig( @@ -75,9 +75,9 @@ finally: ```python -from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig -from lerobot.common.cameras.realsense.camera_realsense import RealSenseCamera -from lerobot.common.cameras.configs import ColorMode, Cv2Rotation +from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig +from lerobot.cameras.realsense.camera_realsense import RealSenseCamera +from lerobot.cameras.configs import ColorMode, Cv2Rotation # Create a `RealSenseCameraConfig` specifying your camera’s serial number and enabling depth. config = RealSenseCameraConfig( diff --git a/docs/source/hilserl.mdx b/docs/source/hilserl.mdx index 149b25c..79b49c9 100644 --- a/docs/source/hilserl.mdx +++ b/docs/source/hilserl.mdx @@ -50,12 +50,12 @@ pip install -e ".[hilserl]" ### 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 class HILSerlRobotEnvConfig(EnvConfig): - robot: RobotConfig | None = None # Main robot agent (defined in `lerobot/common/robots`) - teleop: TeleoperatorConfig | None = None # Teleoperator agent, e.g., gamepad or leader arm, (defined in `lerobot/common/teleoperators`) + 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/teleoperators`) wrapper: EnvTransformConfig | None = None # Environment wrapper settings; check `lerobot/scripts/server/gym_manipulator.py` fps: int = 10 # Control frequency 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** @@ -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): ```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: @@ -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: ```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 @@ -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. ```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** @@ -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: ```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** @@ -410,7 +410,7 @@ or set the argument in the json config file. Run `gym_manipulator.py` to test the model. ```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. @@ -422,17 +422,17 @@ The reward classifier will automatically provide rewards based on the visual inp 2. **Collect a dataset**: ```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**: ```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**: ```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 @@ -446,7 +446,7 @@ Create a training configuration file (example available [here](https://huggingfa 1. Configure the policy settings (`type="sac"`, `device`, etc.) 2. Set `dataset` to your cropped dataset 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. **Starting the Learner** @@ -454,7 +454,7 @@ Create a training configuration file (example available [here](https://huggingfa First, start the learner server process: ```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: @@ -468,7 +468,7 @@ The learner: In a separate terminal, start the actor process with the same configuration: ```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: diff --git a/docs/source/hilserl_sim.mdx b/docs/source/hilserl_sim.mdx index 3239ba9..ad7a958 100644 --- a/docs/source/hilserl_sim.mdx +++ b/docs/source/hilserl_sim.mdx @@ -77,7 +77,7 @@ Important parameters: To run the environment, set mode to null: ```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 @@ -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: ```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 @@ -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: ```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: ```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. diff --git a/docs/source/il_robots.mdx b/docs/source/il_robots.mdx index 3dd9d80..cfa0a28 100644 --- a/docs/source/il_robots.mdx +++ b/docs/source/il_robots.mdx @@ -52,8 +52,8 @@ python -m lerobot.teleoperate \ ```python -from lerobot.common.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader -from lerobot.common.robots.so101_follower import SO101FollowerConfig, SO101Follower +from lerobot.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader +from lerobot.robots.so101_follower import SO101FollowerConfig, SO101Follower robot_config = SO101FollowerConfig( port="/dev/tty.usbmodem58760431541", @@ -105,9 +105,9 @@ python -m lerobot.teleoperate \ ```python -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.common.teleoperators.koch_leader import KochLeaderConfig, KochLeader -from lerobot.common.robots.koch_follower import KochFollowerConfig, KochFollower +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.teleoperators.koch_leader import KochLeaderConfig, KochLeader +from lerobot.robots.koch_follower import KochFollowerConfig, KochFollower camera_config = { "front": OpenCVCameraConfig(index_or_path=0, width=1920, height=1080, fps=30) @@ -175,15 +175,15 @@ python -m lerobot.record \ ```python -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import hw_to_dataset_features -from lerobot.common.robots.so100_follower import SO100Follower, SO100FollowerConfig -from lerobot.common.teleoperators.so100_leader.config_so100_leader import SO100LeaderConfig -from lerobot.common.teleoperators.so100_leader.so100_leader import SO100Leader -from lerobot.common.utils.control_utils import init_keyboard_listener -from lerobot.common.utils.utils import log_say -from lerobot.common.utils.visualization_utils import _init_rerun +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import hw_to_dataset_features +from lerobot.robots.so100_follower import SO100Follower, SO100FollowerConfig +from lerobot.teleoperators.so100_leader.config_so100_leader import SO100LeaderConfig +from lerobot.teleoperators.so100_leader.so100_leader import SO100Leader +from lerobot.utils.control_utils import init_keyboard_listener +from lerobot.utils.utils import log_say +from lerobot.utils.visualization_utils import _init_rerun from lerobot.record import record_loop NUM_EPISODES = 5 @@ -353,11 +353,11 @@ python -m lerobot.replay \ ```python import time -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.robots.so100_follower.config_so100_follower import SO100FollowerConfig -from lerobot.common.robots.so100_follower.so100_follower import SO100Follower -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import log_say +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.robots.so100_follower.config_so100_follower import SO100FollowerConfig +from lerobot.robots.so100_follower.so100_follower import SO100Follower +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import log_say episode_idx = 0 @@ -389,9 +389,9 @@ Your robot should replicate movements similar to those you recorded. For example ## 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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --dataset.repo_id=${HF_USER}/so101_test \ --policy.type=act \ --output_dir=outputs/train/act_so101_test \ @@ -403,7 +403,7 @@ python lerobot/scripts/train.py \ Let's explain the command: 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. 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: ```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 \ --resume=true ``` @@ -462,15 +462,15 @@ python -m lerobot.record \ ```python -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import hw_to_dataset_features -from lerobot.common.policies.act.modeling_act import ACTPolicy -from lerobot.common.robots.so100_follower.config_so100_follower import SO100FollowerConfig -from lerobot.common.robots.so100_follower.so100_follower import SO100Follower -from lerobot.common.utils.control_utils import init_keyboard_listener -from lerobot.common.utils.utils import log_say -from lerobot.common.utils.visualization_utils import _init_rerun +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import hw_to_dataset_features +from lerobot.policies.act.modeling_act import ACTPolicy +from lerobot.robots.so100_follower.config_so100_follower import SO100FollowerConfig +from lerobot.robots.so100_follower.so100_follower import SO100Follower +from lerobot.utils.control_utils import init_keyboard_listener +from lerobot.utils.utils import log_say +from lerobot.utils.visualization_utils import _init_rerun from lerobot.record import record_loop NUM_EPISODES = 5 diff --git a/docs/source/il_sim.mdx b/docs/source/il_sim.mdx index 625b2fc..048d314 100644 --- a/docs/source/il_sim.mdx +++ b/docs/source/il_sim.mdx @@ -35,14 +35,14 @@ Then we can run this command to start: ```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 ``` ```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 ``` @@ -81,9 +81,9 @@ If you uploaded your dataset to the hub you can [visualize your dataset online]( ## 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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --dataset.repo_id=${HF_USER}/il_gym \ --policy.type=act \ --output_dir=outputs/train/il_sim_test \ @@ -94,7 +94,7 @@ python lerobot/scripts/train.py \ Let's explain the command: 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. 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 ```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 ``` ```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 ``` diff --git a/docs/source/integrate_hardware.mdx b/docs/source/integrate_hardware.mdx index f7de1ce..18d73d3 100644 --- a/docs/source/integrate_hardware.mdx +++ b/docs/source/integrate_hardware.mdx @@ -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). -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 @@ -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: -- [`FeetechMotorsBus`](https://github.com/huggingface/lerobot/blob/main/lerobot/common/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 +- [`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/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. -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) +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/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): - 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` - 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. @@ -44,9 +44,9 @@ Here, we'll add the port name and one camera by default for our robot: ```python from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig -from lerobot.common.cameras.opencv import OpenCVCameraConfig -from lerobot.common.robots import RobotConfig +from lerobot.cameras import CameraConfig +from lerobot.cameras.opencv import OpenCVCameraConfig +from lerobot.robots import RobotConfig @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! ```python -from lerobot.common.cameras import make_cameras_from_configs -from lerobot.common.motors import Motor, MotorNormMode -from lerobot.common.motors.feetech import FeetechMotorsBus -from lerobot.common.robots import Robot +from lerobot.cameras import make_cameras_from_configs +from lerobot.motors import Motor, MotorNormMode +from lerobot.motors.feetech import FeetechMotorsBus +from lerobot.robots import Robot class MyCoolRobot(Robot): config_class = MyCoolRobotConfig @@ -303,7 +303,7 @@ def send_action(self, action: dict[str, Any]) -> dict[str, Any]: ## 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. diff --git a/docs/source/koch.mdx b/docs/source/koch.mdx index b2399ae..5383518 120000 --- a/docs/source/koch.mdx +++ b/docs/source/koch.mdx @@ -1 +1 @@ -../../lerobot/common/robots/koch_follower/koch.mdx \ No newline at end of file +../../src/lerobot/robots/koch_follower/koch.mdx \ No newline at end of file diff --git a/docs/source/lekiwi.mdx b/docs/source/lekiwi.mdx index e2b4ff5..afc4307 120000 --- a/docs/source/lekiwi.mdx +++ b/docs/source/lekiwi.mdx @@ -1 +1 @@ -../../lerobot/common/robots/lekiwi/lekiwi.mdx \ No newline at end of file +../../src/lerobot/robots/lekiwi/lekiwi.mdx \ No newline at end of file diff --git a/docs/source/smolvla.mdx b/docs/source/smolvla.mdx index 1d6596f..17a2bdf 100644 --- a/docs/source/smolvla.mdx +++ b/docs/source/smolvla.mdx @@ -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). ```bash -cd lerobot && python lerobot/scripts/train.py \ +cd lerobot && python -m lerobot.scripts.train \ --policy.path=lerobot/smolvla_base \ --dataset.repo_id=${HF_USER}/mydataset \ --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 ```bash -python lerobot/scripts/train.py --help +python -m lerobot.scripts.train --help ```

diff --git a/docs/source/so100.mdx b/docs/source/so100.mdx index 65849e9..0a71dc3 120000 --- a/docs/source/so100.mdx +++ b/docs/source/so100.mdx @@ -1 +1 @@ -../../lerobot/common/robots/so100_follower/so100.mdx \ No newline at end of file +../../src/lerobot/robots/so100_follower/so100.mdx \ No newline at end of file diff --git a/docs/source/so101.mdx b/docs/source/so101.mdx index dc4720c..ab6d0ac 120000 --- a/docs/source/so101.mdx +++ b/docs/source/so101.mdx @@ -1 +1 @@ -../../lerobot/common/robots/so101_follower/so101.mdx \ No newline at end of file +../../src/lerobot/robots/so101_follower/so101.mdx \ No newline at end of file diff --git a/examples/1_load_lerobot_dataset.py b/examples/1_load_lerobot_dataset.py index 07db38a..3d357dd 100644 --- a/examples/1_load_lerobot_dataset.py +++ b/examples/1_load_lerobot_dataset.py @@ -32,7 +32,7 @@ import torch from huggingface_hub import HfApi 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: print("List of available datasets:") diff --git a/examples/2_evaluate_pretrained_policy.py b/examples/2_evaluate_pretrained_policy.py index 4e6154c..c0c7845 100644 --- a/examples/2_evaluate_pretrained_policy.py +++ b/examples/2_evaluate_pretrained_policy.py @@ -30,7 +30,7 @@ import imageio import numpy 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 output_directory = Path("outputs/eval/example_pusht_diffusion") diff --git a/examples/3_train_policy.py b/examples/3_train_policy.py index f9c251a..f2de79d 100644 --- a/examples/3_train_policy.py +++ b/examples/3_train_policy.py @@ -22,11 +22,11 @@ from pathlib import Path 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.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(): diff --git a/examples/4_train_policy_with_script.md b/examples/4_train_policy_with_script.md index cb4cc62..f17411b 100644 --- a/examples/4_train_policy_with_script.md +++ b/examples/4_train_policy_with_script.md @@ -4,7 +4,7 @@ This tutorial will explain the training script, how to use it, and particularly ## 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. - Instantiates a dataset. @@ -21,7 +21,7 @@ In the training script, the main function `train` expects a `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.) @@ -50,9 +50,9 @@ By default, every field takes its default value specified in the dataclass. If a ## 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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --dataset.repo_id=lerobot/pusht \ --policy.type=diffusion \ --env.type=pusht @@ -60,12 +60,12 @@ python lerobot/scripts/train.py \ 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 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) -- 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) +- 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/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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=act \ --dataset.repo_id=lerobot/aloha_sim_insertion_human \ --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`. 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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=act \ --dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \ --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: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \ --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.: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=outputs/train/act_aloha_transfer/checkpoints/last/pretrained_model/ \ --output_dir=outputs/train/act_aloha_transfer_2 --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: ```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) @@ -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: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=act \ --dataset.repo_id=lerobot/aloha_sim_transfer_cube_human \ --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: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \ --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. You could double the number of steps of the previous run with: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=outputs/train/run_resumption/checkpoints/last/pretrained_model/ \ --resume=true \ --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: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.path=lerobot/act_aloha_sim_transfer_cube_human \ --dataset.repo_id=lerobot/aloha_sim_insertion_human \ --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 ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=act \ # <- select 'act' policy --env.type=pusht \ # <- select 'pusht' environment --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 ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=path/to/pretrained_model \ # <- can also be a repo_id --policy.n_action_steps=80 # <- you may still override values ``` #### Resume/continue a training run ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --config_path=checkpoint/pretrained_model/ \ --resume=true \ --steps=200000 # <- you can change some training parameters @@ -259,7 +259,7 @@ python lerobot/scripts/train.py \ #### Fine-tuning ```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 --dataset.repo_id=lerobot/aloha_sim_insertion_human \ --env.type=aloha \ diff --git a/examples/advanced/1_add_image_transforms.py b/examples/advanced/1_add_image_transforms.py index f146092..3760fea 100644 --- a/examples/advanced/1_add_image_transforms.py +++ b/examples/advanced/1_add_image_transforms.py @@ -22,7 +22,7 @@ from pathlib import Path 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" diff --git a/examples/advanced/2_calculate_validation_loss.py b/examples/advanced/2_calculate_validation_loss.py index aac8e2e..9eeb1a2 100644 --- a/examples/advanced/2_calculate_validation_loss.py +++ b/examples/advanced/2_calculate_validation_loss.py @@ -26,8 +26,8 @@ import math import torch -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata -from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy +from lerobot.datasets.lerobot_dataset import LeRobotDataset, LeRobotDatasetMetadata +from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy def main(): diff --git a/examples/backward_compatibility/replay.py b/examples/backward_compatibility/replay.py index 11684d0..cc33975 100644 --- a/examples/backward_compatibility/replay.py +++ b/examples/backward_compatibility/replay.py @@ -35,8 +35,8 @@ from pprint import pformat import draccus -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.robots import ( # noqa: F401 +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.robots import ( # noqa: F401 Robot, RobotConfig, koch_follower, @@ -44,8 +44,8 @@ from lerobot.common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import ( +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import ( init_logging, log_say, ) diff --git a/examples/lekiwi/evaluate.py b/examples/lekiwi/evaluate.py index 2a41440..60526e6 100644 --- a/examples/lekiwi/evaluate.py +++ b/examples/lekiwi/evaluate.py @@ -1,8 +1,8 @@ -from lerobot.common.datasets.utils import build_dataset_frame, hw_to_dataset_features -from lerobot.common.policies.act.modeling_act import ACTPolicy -from lerobot.common.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig -from lerobot.common.utils.control_utils import predict_action -from lerobot.common.utils.utils import get_safe_torch_device +from lerobot.datasets.utils import build_dataset_frame, hw_to_dataset_features +from lerobot.policies.act.modeling_act import ACTPolicy +from lerobot.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig +from lerobot.utils.control_utils import predict_action +from lerobot.utils.utils import get_safe_torch_device NB_CYCLES_CLIENT_CONNECTION = 1000 diff --git a/examples/lekiwi/record.py b/examples/lekiwi/record.py index 405a41b..2ad3267 100644 --- a/examples/lekiwi/record.py +++ b/examples/lekiwi/record.py @@ -1,11 +1,11 @@ import time -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import hw_to_dataset_features -from lerobot.common.robots.lekiwi.config_lekiwi import LeKiwiClientConfig -from lerobot.common.robots.lekiwi.lekiwi_client import LeKiwiClient -from lerobot.common.teleoperators.keyboard import KeyboardTeleop, KeyboardTeleopConfig -from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import hw_to_dataset_features +from lerobot.robots.lekiwi.config_lekiwi import LeKiwiClientConfig +from lerobot.robots.lekiwi.lekiwi_client import LeKiwiClient +from lerobot.teleoperators.keyboard import KeyboardTeleop, KeyboardTeleopConfig +from lerobot.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig NB_CYCLES_CLIENT_CONNECTION = 250 diff --git a/examples/lekiwi/replay.py b/examples/lekiwi/replay.py index f69092d..2c49fc5 100644 --- a/examples/lekiwi/replay.py +++ b/examples/lekiwi/replay.py @@ -1,9 +1,9 @@ import time -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.robots.lekiwi.config_lekiwi import LeKiwiClientConfig -from lerobot.common.robots.lekiwi.lekiwi_client import LeKiwiClient -from lerobot.common.utils.robot_utils import busy_wait +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.robots.lekiwi.config_lekiwi import LeKiwiClientConfig +from lerobot.robots.lekiwi.lekiwi_client import LeKiwiClient +from lerobot.utils.robot_utils import busy_wait robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="lekiwi") robot = LeKiwiClient(robot_config) diff --git a/examples/lekiwi/teleoperate.py b/examples/lekiwi/teleoperate.py index 2fe85d9..d7218df 100644 --- a/examples/lekiwi/teleoperate.py +++ b/examples/lekiwi/teleoperate.py @@ -1,6 +1,6 @@ -from lerobot.common.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig -from lerobot.common.teleoperators.keyboard.teleop_keyboard import KeyboardTeleop, KeyboardTeleopConfig -from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig +from lerobot.robots.lekiwi import LeKiwiClient, LeKiwiClientConfig +from lerobot.teleoperators.keyboard.teleop_keyboard import KeyboardTeleop, KeyboardTeleopConfig +from lerobot.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig robot_config = LeKiwiClientConfig(remote_ip="172.18.134.136", id="my_lekiwi") diff --git a/lerobot/common/transport/services_pb2.py b/lerobot/common/transport/services_pb2.py deleted file mode 100644 index 727beb6..0000000 --- a/lerobot/common/transport/services_pb2.py +++ /dev/null @@ -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) diff --git a/pyproject.toml b/pyproject.toml index 5bff0fc..3686532 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -123,10 +123,10 @@ select = ["E4", "E7", "E9", "F", "I", "N", "B", "C4", "SIM"] exclude_dirs = [ "tests", "benchmarks", - "lerobot/common/datasets/push_dataset_to_hub", - "lerobot/common/datasets/v2/convert_dataset_v1_to_v2", - "lerobot/common/policies/pi0/conversion_scripts", - "lerobot/scripts/push_dataset_to_hub.py", + "src/lerobot/datasets/push_dataset_to_hub", + "src/lerobot/datasets/v2/convert_dataset_v1_to_v2", + "src/lerobot/policies/pi0/conversion_scripts", + "src/lerobot/scripts/push_dataset_to_hub.py", ] skips = ["B101", "B311", "B404", "B603"] diff --git a/lerobot/__init__.py b/src/lerobot/__init__.py similarity index 96% rename from lerobot/__init__.py rename to src/lerobot/__init__.py index 11114da..38d4e86 100644 --- a/lerobot/__init__.py +++ b/src/lerobot/__init__.py @@ -167,10 +167,10 @@ available_datasets = sorted( 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"] -# lists all available robots from `lerobot/common/robot_devices/robots` +# lists all available robots from `lerobot/robot_devices/robots` available_robots = [ "koch", "koch_bimanual", @@ -179,13 +179,13 @@ available_robots = [ "so101", ] -# lists all available cameras from `lerobot/common/robot_devices/cameras` +# lists all available cameras from `lerobot/robot_devices/cameras` available_cameras = [ "opencv", "intelrealsense", ] -# lists all available motors from `lerobot/common/robot_devices/motors` +# lists all available motors from `lerobot/robot_devices/motors` available_motors = [ "dynamixel", "feetech", diff --git a/lerobot/__version__.py b/src/lerobot/__version__.py similarity index 100% rename from lerobot/__version__.py rename to src/lerobot/__version__.py diff --git a/lerobot/calibrate.py b/src/lerobot/calibrate.py similarity index 84% rename from lerobot/calibrate.py rename to src/lerobot/calibrate.py index 6780577..37a9d5b 100644 --- a/lerobot/calibrate.py +++ b/src/lerobot/calibrate.py @@ -31,9 +31,9 @@ from pprint import pformat import draccus -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 -from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 -from lerobot.common.robots import ( # noqa: F401 +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 +from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 +from lerobot.robots import ( # noqa: F401 Robot, RobotConfig, koch_follower, @@ -42,7 +42,7 @@ from lerobot.common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from lerobot.common.teleoperators import ( # noqa: F401 +from lerobot.teleoperators import ( # noqa: F401 Teleoperator, TeleoperatorConfig, koch_leader, @@ -50,7 +50,7 @@ from lerobot.common.teleoperators import ( # noqa: F401 so100_leader, so101_leader, ) -from lerobot.common.utils.utils import init_logging +from lerobot.utils.utils import init_logging @dataclass diff --git a/lerobot/common/cameras/__init__.py b/src/lerobot/cameras/__init__.py similarity index 100% rename from lerobot/common/cameras/__init__.py rename to src/lerobot/cameras/__init__.py diff --git a/lerobot/common/cameras/camera.py b/src/lerobot/cameras/camera.py similarity index 100% rename from lerobot/common/cameras/camera.py rename to src/lerobot/cameras/camera.py diff --git a/lerobot/common/cameras/configs.py b/src/lerobot/cameras/configs.py similarity index 100% rename from lerobot/common/cameras/configs.py rename to src/lerobot/cameras/configs.py diff --git a/lerobot/common/cameras/opencv/__init__.py b/src/lerobot/cameras/opencv/__init__.py similarity index 100% rename from lerobot/common/cameras/opencv/__init__.py rename to src/lerobot/cameras/opencv/__init__.py diff --git a/lerobot/common/cameras/opencv/camera_opencv.py b/src/lerobot/cameras/opencv/camera_opencv.py similarity index 98% rename from lerobot/common/cameras/opencv/camera_opencv.py rename to src/lerobot/cameras/opencv/camera_opencv.py index 3e9370f..fd99922 100644 --- a/lerobot/common/cameras/opencv/camera_opencv.py +++ b/src/lerobot/cameras/opencv/camera_opencv.py @@ -27,7 +27,7 @@ from typing import Any, Dict, List import cv2 import numpy as np -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from ..camera import Camera from ..utils import get_cv2_backend, get_cv2_rotation @@ -64,8 +64,8 @@ class OpenCVCamera(Camera): Example: ```python - from lerobot.common.cameras.opencv import OpenCVCamera - from lerobot.common.cameras.configuration_opencv import OpenCVCameraConfig, ColorMode, Cv2Rotation + from lerobot.cameras.opencv import OpenCVCamera + from lerobot.cameras.configuration_opencv import OpenCVCameraConfig, ColorMode, Cv2Rotation # Basic usage with camera index 0 config = OpenCVCameraConfig(index_or_path=0) diff --git a/lerobot/common/cameras/opencv/configuration_opencv.py b/src/lerobot/cameras/opencv/configuration_opencv.py similarity index 100% rename from lerobot/common/cameras/opencv/configuration_opencv.py rename to src/lerobot/cameras/opencv/configuration_opencv.py diff --git a/lerobot/common/cameras/realsense/__init__.py b/src/lerobot/cameras/realsense/__init__.py similarity index 100% rename from lerobot/common/cameras/realsense/__init__.py rename to src/lerobot/cameras/realsense/__init__.py diff --git a/lerobot/common/cameras/realsense/camera_realsense.py b/src/lerobot/cameras/realsense/camera_realsense.py similarity index 98% rename from lerobot/common/cameras/realsense/camera_realsense.py rename to src/lerobot/cameras/realsense/camera_realsense.py index 2bcbee7..96531b6 100644 --- a/lerobot/common/cameras/realsense/camera_realsense.py +++ b/src/lerobot/cameras/realsense/camera_realsense.py @@ -29,7 +29,7 @@ try: except Exception as 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 ..configs import ColorMode @@ -63,8 +63,8 @@ class RealSenseCamera(Camera): Example: ```python - from lerobot.common.cameras.realsense import RealSenseCamera, RealSenseCameraConfig - from lerobot.common.cameras import ColorMode, Cv2Rotation + from lerobot.cameras.realsense import RealSenseCamera, RealSenseCameraConfig + from lerobot.cameras import ColorMode, Cv2Rotation # Basic usage with serial number config = RealSenseCameraConfig(serial_number_or_name="0123456789") # Replace with actual SN diff --git a/lerobot/common/cameras/realsense/configuration_realsense.py b/src/lerobot/cameras/realsense/configuration_realsense.py similarity index 100% rename from lerobot/common/cameras/realsense/configuration_realsense.py rename to src/lerobot/cameras/realsense/configuration_realsense.py diff --git a/lerobot/common/cameras/utils.py b/src/lerobot/cameras/utils.py similarity index 100% rename from lerobot/common/cameras/utils.py rename to src/lerobot/cameras/utils.py diff --git a/lerobot/configs/default.py b/src/lerobot/configs/default.py similarity index 94% rename from lerobot/configs/default.py rename to src/lerobot/configs/default.py index ce72466..53cfe58 100644 --- a/lerobot/configs/default.py +++ b/src/lerobot/configs/default.py @@ -16,11 +16,11 @@ from dataclasses import dataclass, field -from lerobot.common import ( +from lerobot import ( policies, # noqa: F401 ) -from lerobot.common.datasets.transforms import ImageTransformsConfig -from lerobot.common.datasets.video_utils import get_safe_default_codec +from lerobot.datasets.transforms import ImageTransformsConfig +from lerobot.datasets.video_utils import get_safe_default_codec @dataclass diff --git a/lerobot/configs/eval.py b/src/lerobot/configs/eval.py similarity index 97% rename from lerobot/configs/eval.py rename to src/lerobot/configs/eval.py index 16b3529..cfe48cf 100644 --- a/lerobot/configs/eval.py +++ b/src/lerobot/configs/eval.py @@ -17,7 +17,7 @@ import logging from dataclasses import dataclass, field 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.default import EvalConfig from lerobot.configs.policies import PreTrainedConfig diff --git a/lerobot/configs/parser.py b/src/lerobot/configs/parser.py similarity index 99% rename from lerobot/configs/parser.py rename to src/lerobot/configs/parser.py index f69b5a7..1da7ad8 100644 --- a/lerobot/configs/parser.py +++ b/src/lerobot/configs/parser.py @@ -22,7 +22,7 @@ from typing import Sequence import draccus -from lerobot.common.utils.utils import has_method +from lerobot.utils.utils import has_method PATH_KEY = "path" PLUGIN_DISCOVERY_SUFFIX = "discover_packages_path" diff --git a/lerobot/configs/policies.py b/src/lerobot/configs/policies.py similarity index 96% rename from lerobot/configs/policies.py rename to src/lerobot/configs/policies.py index 9e7f3dd..36e6ea2 100644 --- a/lerobot/configs/policies.py +++ b/src/lerobot/configs/policies.py @@ -23,11 +23,11 @@ from huggingface_hub import hf_hub_download from huggingface_hub.constants import CONFIG_NAME 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.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 T = TypeVar("T", bound="PreTrainedConfig") diff --git a/lerobot/configs/train.py b/src/lerobot/configs/train.py similarity index 97% rename from lerobot/configs/train.py rename to src/lerobot/configs/train.py index 377fb8a..c088a5f 100644 --- a/lerobot/configs/train.py +++ b/src/lerobot/configs/train.py @@ -21,13 +21,13 @@ import draccus from huggingface_hub import hf_hub_download from huggingface_hub.errors import HfHubHTTPError -from lerobot.common import envs -from lerobot.common.optim import OptimizerConfig -from lerobot.common.optim.schedulers import LRSchedulerConfig -from lerobot.common.utils.hub import HubMixin +from lerobot import envs from lerobot.configs import parser from lerobot.configs.default import DatasetConfig, EvalConfig, WandBConfig 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" diff --git a/lerobot/configs/types.py b/src/lerobot/configs/types.py similarity index 100% rename from lerobot/configs/types.py rename to src/lerobot/configs/types.py diff --git a/lerobot/common/constants.py b/src/lerobot/constants.py similarity index 100% rename from lerobot/common/constants.py rename to src/lerobot/constants.py diff --git a/lerobot/common/datasets/backward_compatibility.py b/src/lerobot/datasets/backward_compatibility.py similarity index 95% rename from lerobot/common/datasets/backward_compatibility.py rename to src/lerobot/datasets/backward_compatibility.py index cf8e31c..fae4850 100644 --- a/lerobot/common/datasets/backward_compatibility.py +++ b/src/lerobot/datasets/backward_compatibility.py @@ -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. 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} \\ --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 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) diff --git a/lerobot/common/datasets/card_template.md b/src/lerobot/datasets/card_template.md similarity index 100% rename from lerobot/common/datasets/card_template.md rename to src/lerobot/datasets/card_template.md diff --git a/lerobot/common/datasets/compute_stats.py b/src/lerobot/datasets/compute_stats.py similarity index 99% rename from lerobot/common/datasets/compute_stats.py rename to src/lerobot/datasets/compute_stats.py index 1149ec8..bfe7b18 100644 --- a/lerobot/common/datasets/compute_stats.py +++ b/src/lerobot/datasets/compute_stats.py @@ -15,7 +15,7 @@ # limitations under the License. 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( diff --git a/lerobot/common/datasets/factory.py b/src/lerobot/datasets/factory.py similarity index 97% rename from lerobot/common/datasets/factory.py rename to src/lerobot/datasets/factory.py index 88d3f76..e06650b 100644 --- a/lerobot/common/datasets/factory.py +++ b/src/lerobot/datasets/factory.py @@ -18,14 +18,14 @@ from pprint import pformat 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, LeRobotDatasetMetadata, MultiLeRobotDataset, ) -from lerobot.common.datasets.transforms import ImageTransforms -from lerobot.configs.policies import PreTrainedConfig -from lerobot.configs.train import TrainPipelineConfig +from lerobot.datasets.transforms import ImageTransforms IMAGENET_STATS = { "mean": [[[0.485]], [[0.456]], [[0.406]]], # (c,1,1) diff --git a/lerobot/common/datasets/image_writer.py b/src/lerobot/datasets/image_writer.py similarity index 100% rename from lerobot/common/datasets/image_writer.py rename to src/lerobot/datasets/image_writer.py diff --git a/lerobot/common/datasets/lerobot_dataset.py b/src/lerobot/datasets/lerobot_dataset.py similarity index 99% rename from lerobot/common/datasets/lerobot_dataset.py rename to src/lerobot/datasets/lerobot_dataset.py index 425e9f7..1a3dd1e 100644 --- a/lerobot/common/datasets/lerobot_dataset.py +++ b/src/lerobot/datasets/lerobot_dataset.py @@ -30,10 +30,10 @@ from huggingface_hub import HfApi, snapshot_download from huggingface_hub.constants import REPOCARD_NAME from huggingface_hub.errors import RevisionNotFoundError -from lerobot.common.constants import HF_LEROBOT_HOME -from lerobot.common.datasets.compute_stats import aggregate_stats, compute_episode_stats -from lerobot.common.datasets.image_writer import AsyncImageWriter, write_image -from lerobot.common.datasets.utils import ( +from lerobot.constants import HF_LEROBOT_HOME +from lerobot.datasets.compute_stats import aggregate_stats, compute_episode_stats +from lerobot.datasets.image_writer import AsyncImageWriter, write_image +from lerobot.datasets.utils import ( DEFAULT_FEATURES, DEFAULT_IMAGE_PATH, INFO_PATH, @@ -65,7 +65,7 @@ from lerobot.common.datasets.utils import ( write_info, write_json, ) -from lerobot.common.datasets.video_utils import ( +from lerobot.datasets.video_utils import ( VideoFrame, decode_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 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 - 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 diff --git a/lerobot/common/datasets/online_buffer.py b/src/lerobot/datasets/online_buffer.py similarity index 99% rename from lerobot/common/datasets/online_buffer.py rename to src/lerobot/datasets/online_buffer.py index d907e46..79f48f4 100644 --- a/lerobot/common/datasets/online_buffer.py +++ b/src/lerobot/datasets/online_buffer.py @@ -28,7 +28,7 @@ from typing import Any import numpy as np import torch -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.lerobot_dataset import LeRobotDataset def _make_memmap_safe(**kwargs) -> np.memmap: diff --git a/lerobot/common/datasets/push_dataset_to_hub/utils.py b/src/lerobot/datasets/push_dataset_to_hub/utils.py similarity index 98% rename from lerobot/common/datasets/push_dataset_to_hub/utils.py rename to src/lerobot/datasets/push_dataset_to_hub/utils.py index ebcf87f..6aca7b0 100644 --- a/lerobot/common/datasets/push_dataset_to_hub/utils.py +++ b/src/lerobot/datasets/push_dataset_to_hub/utils.py @@ -23,7 +23,7 @@ import numpy import PIL 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): diff --git a/lerobot/common/datasets/sampler.py b/src/lerobot/datasets/sampler.py similarity index 100% rename from lerobot/common/datasets/sampler.py rename to src/lerobot/datasets/sampler.py diff --git a/lerobot/common/datasets/transforms.py b/src/lerobot/datasets/transforms.py similarity index 100% rename from lerobot/common/datasets/transforms.py rename to src/lerobot/datasets/transforms.py diff --git a/lerobot/common/datasets/utils.py b/src/lerobot/datasets/utils.py similarity index 98% rename from lerobot/common/datasets/utils.py rename to src/lerobot/datasets/utils.py index 542daf2..ac0ab97 100644 --- a/lerobot/common/datasets/utils.py +++ b/src/lerobot/datasets/utils.py @@ -35,14 +35,14 @@ from huggingface_hub.errors import RevisionNotFoundError from PIL import Image as PILImage 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, BackwardCompatibilityError, ForwardCompatibilityError, ) -from lerobot.common.robots import Robot -from lerobot.common.utils.utils import is_valid_numpy_dtype_string -from lerobot.configs.types import DictLike, FeatureType, PolicyFeature +from lerobot.robots import Robot +from lerobot.utils.utils import is_valid_numpy_dtype_string DEFAULT_CHUNK_SIZE = 1000 # Max number of episodes per chunk @@ -664,7 +664,7 @@ def create_lerobot_dataset_card( **kwargs, ) -> 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. """ 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( card_data=card_data, diff --git a/lerobot/common/datasets/v2/batch_convert_dataset_v1_to_v2.py b/src/lerobot/datasets/v2/batch_convert_dataset_v1_to_v2.py similarity index 99% rename from lerobot/common/datasets/v2/batch_convert_dataset_v1_to_v2.py rename to src/lerobot/datasets/v2/batch_convert_dataset_v1_to_v2.py index 9b21cf7..fa99c72 100644 --- a/lerobot/common/datasets/v2/batch_convert_dataset_v1_to_v2.py +++ b/src/lerobot/datasets/v2/batch_convert_dataset_v1_to_v2.py @@ -26,8 +26,8 @@ from pathlib import Path from textwrap import dedent from lerobot import available_datasets -from lerobot.common.datasets.v2.convert_dataset_v1_to_v2 import convert_dataset -from lerobot.common.robots.aloha.configuration_aloha import AlohaRobotConfig +from lerobot.datasets.v2.convert_dataset_v1_to_v2 import convert_dataset +from lerobot.robots.aloha.configuration_aloha import AlohaRobotConfig LOCAL_DIR = Path("data/") diff --git a/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py b/src/lerobot/datasets/v2/convert_dataset_v1_to_v2.py similarity index 97% rename from lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py rename to src/lerobot/datasets/v2/convert_dataset_v1_to_v2.py index 136a7a6..cddfc4c 100644 --- a/lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py +++ b/src/lerobot/datasets/v2/convert_dataset_v1_to_v2.py @@ -38,7 +38,7 @@ If your dataset contains a single task, you can simply provide it directly via t Examples: ```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 \ --single-task "Insert the peg into the socket." \ --robot-config lerobot/configs/robot/aloha.yaml \ @@ -46,7 +46,7 @@ python lerobot/common/datasets/v2/convert_dataset_v1_to_v2.py \ ``` ```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 \ --single-task "Pick the Lego block and drop it in the box on the right." \ --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: ```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 \ --tasks-col "language_instruction" \ --local-dir data @@ -92,7 +92,7 @@ parquet file, and you must provide this column's name with the '--tasks-col' arg Example: ```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 \ --tasks-col "language_instruction" \ --local-dir data @@ -119,7 +119,7 @@ from huggingface_hub import HfApi from huggingface_hub.errors import EntryNotFoundError, HfHubHTTPError from safetensors.torch import load_file -from lerobot.common.datasets.utils import ( +from lerobot.datasets.utils import ( DEFAULT_CHUNK_SIZE, DEFAULT_PARQUET_PATH, DEFAULT_VIDEO_PATH, @@ -136,12 +136,12 @@ from lerobot.common.datasets.utils import ( write_json, write_jsonlines, ) -from lerobot.common.datasets.video_utils import ( +from lerobot.datasets.video_utils import ( VideoFrame, # noqa: F401 get_image_pixel_channels, get_video_info, ) -from lerobot.common.robots import RobotConfig +from lerobot.robots import RobotConfig V16 = "v1.6" V20 = "v2.0" @@ -602,19 +602,19 @@ def make_robot_config(robot_type: str, **kwargs) -> RobotConfig: raise NotImplementedError # TODO elif robot_type == "koch_follower": - from lerobot.common.robots.koch_follower import KochFollowerConfig + from lerobot.robots.koch_follower import KochFollowerConfig return KochFollowerConfig(**kwargs) elif robot_type == "so100_follower": - from lerobot.common.robots.so100_follower import SO100FollowerConfig + from lerobot.robots.so100_follower import SO100FollowerConfig return SO100FollowerConfig(**kwargs) elif robot_type == "stretch": - from lerobot.common.robots.stretch3 import Stretch3RobotConfig + from lerobot.robots.stretch3 import Stretch3RobotConfig return Stretch3RobotConfig(**kwargs) elif robot_type == "lekiwi": - from lerobot.common.robots.lekiwi import LeKiwiConfig + from lerobot.robots.lekiwi import LeKiwiConfig return LeKiwiConfig(**kwargs) else: diff --git a/lerobot/common/datasets/v21/_remove_language_instruction.py b/src/lerobot/datasets/v21/_remove_language_instruction.py similarity index 92% rename from lerobot/common/datasets/v21/_remove_language_instruction.py rename to src/lerobot/datasets/v21/_remove_language_instruction.py index 643ddd3..1f1cb18 100644 --- a/lerobot/common/datasets/v21/_remove_language_instruction.py +++ b/src/lerobot/datasets/v21/_remove_language_instruction.py @@ -20,9 +20,9 @@ from datasets import get_dataset_config_info from huggingface_hub import HfApi from lerobot import available_datasets -from lerobot.common.datasets.lerobot_dataset import LeRobotDatasetMetadata -from lerobot.common.datasets.utils import INFO_PATH, write_info -from lerobot.common.datasets.v21.convert_dataset_v20_to_v21 import V20, SuppressWarnings +from lerobot.datasets.lerobot_dataset import LeRobotDatasetMetadata +from lerobot.datasets.utils import INFO_PATH, write_info +from lerobot.datasets.v21.convert_dataset_v20_to_v21 import V20, SuppressWarnings LOCAL_DIR = Path("data/") diff --git a/lerobot/common/datasets/v21/batch_convert_dataset_v20_to_v21.py b/src/lerobot/datasets/v21/batch_convert_dataset_v20_to_v21.py similarity index 95% rename from lerobot/common/datasets/v21/batch_convert_dataset_v20_to_v21.py rename to src/lerobot/datasets/v21/batch_convert_dataset_v20_to_v21.py index cc9272a..b4f1c36 100644 --- a/lerobot/common/datasets/v21/batch_convert_dataset_v20_to_v21.py +++ b/src/lerobot/datasets/v21/batch_convert_dataset_v20_to_v21.py @@ -24,7 +24,7 @@ from pathlib import Path from huggingface_hub import HfApi 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/") diff --git a/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py b/src/lerobot/datasets/v21/convert_dataset_v20_to_v21.py similarity index 90% rename from lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py rename to src/lerobot/datasets/v21/convert_dataset_v20_to_v21.py index 176d16d..4ebc108 100644 --- a/lerobot/common/datasets/v21/convert_dataset_v20_to_v21.py +++ b/src/lerobot/datasets/v21/convert_dataset_v20_to_v21.py @@ -25,7 +25,7 @@ This script will help you convert any LeRobot dataset already pushed to the hub Usage: ```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 ``` @@ -36,9 +36,9 @@ import logging from huggingface_hub import HfApi -from lerobot.common.datasets.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset -from lerobot.common.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.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset +from lerobot.datasets.utils import EPISODES_STATS_PATH, STATS_PATH, load_stats, write_info +from lerobot.datasets.v21.convert_stats import check_aggregate_stats, convert_stats V20 = "v2.0" V21 = "v2.1" diff --git a/lerobot/common/datasets/v21/convert_stats.py b/src/lerobot/datasets/v21/convert_stats.py similarity index 94% rename from lerobot/common/datasets/v21/convert_stats.py rename to src/lerobot/datasets/v21/convert_stats.py index 4a20b42..462781c 100644 --- a/lerobot/common/datasets/v21/convert_stats.py +++ b/src/lerobot/datasets/v21/convert_stats.py @@ -17,9 +17,9 @@ from concurrent.futures import ThreadPoolExecutor, as_completed import numpy as np from tqdm import tqdm -from lerobot.common.datasets.compute_stats import aggregate_stats, get_feature_stats, sample_indices -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import write_episode_stats +from lerobot.datasets.compute_stats import aggregate_stats, get_feature_stats, sample_indices +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import write_episode_stats def sample_episode_video_frames(dataset: LeRobotDataset, episode_index: int, ft_key: str) -> np.ndarray: diff --git a/lerobot/common/datasets/video_utils.py b/src/lerobot/datasets/video_utils.py similarity index 100% rename from lerobot/common/datasets/video_utils.py rename to src/lerobot/datasets/video_utils.py diff --git a/lerobot/common/envs/__init__.py b/src/lerobot/envs/__init__.py similarity index 100% rename from lerobot/common/envs/__init__.py rename to src/lerobot/envs/__init__.py diff --git a/lerobot/common/envs/configs.py b/src/lerobot/envs/configs.py similarity index 97% rename from lerobot/common/envs/configs.py rename to src/lerobot/envs/configs.py index ea081e9..de969d6 100644 --- a/lerobot/common/envs/configs.py +++ b/src/lerobot/envs/configs.py @@ -18,10 +18,10 @@ from typing import Any, Optional 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.constants import ACTION, OBS_ENV_STATE, OBS_IMAGE, OBS_IMAGES, OBS_STATE +from lerobot.robots import RobotConfig +from lerobot.teleoperators.config import TeleoperatorConfig @dataclass diff --git a/lerobot/common/envs/factory.py b/src/lerobot/envs/factory.py similarity index 96% rename from lerobot/common/envs/factory.py rename to src/lerobot/envs/factory.py index 4f5d59c..dc6d96d 100644 --- a/lerobot/common/envs/factory.py +++ b/src/lerobot/envs/factory.py @@ -17,7 +17,7 @@ import importlib 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: diff --git a/lerobot/common/envs/utils.py b/src/lerobot/envs/utils.py similarity index 97% rename from lerobot/common/envs/utils.py rename to src/lerobot/envs/utils.py index 66d6e5f..00676a0 100644 --- a/lerobot/common/envs/utils.py +++ b/src/lerobot/envs/utils.py @@ -22,9 +22,9 @@ import numpy as np import torch 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.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]: diff --git a/lerobot/common/errors.py b/src/lerobot/errors.py similarity index 100% rename from lerobot/common/errors.py rename to src/lerobot/errors.py diff --git a/lerobot/find_cameras.py b/src/lerobot/find_cameras.py similarity index 96% rename from lerobot/find_cameras.py rename to src/lerobot/find_cameras.py index 34f4865..aff2f8c 100644 --- a/lerobot/find_cameras.py +++ b/src/lerobot/find_cameras.py @@ -37,11 +37,11 @@ from typing import Any, Dict, List import numpy as np from PIL import Image -from lerobot.common.cameras.configs import ColorMode -from lerobot.common.cameras.opencv.camera_opencv import OpenCVCamera -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig -from lerobot.common.cameras.realsense.camera_realsense import RealSenseCamera -from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig +from lerobot.cameras.configs import ColorMode +from lerobot.cameras.opencv.camera_opencv import OpenCVCamera +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.cameras.realsense.camera_realsense import RealSenseCamera +from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig logger = logging.getLogger(__name__) diff --git a/lerobot/find_port.py b/src/lerobot/find_port.py similarity index 100% rename from lerobot/find_port.py rename to src/lerobot/find_port.py diff --git a/lerobot/common/model/kinematics.py b/src/lerobot/model/kinematics.py similarity index 100% rename from lerobot/common/model/kinematics.py rename to src/lerobot/model/kinematics.py diff --git a/lerobot/common/motors/__init__.py b/src/lerobot/motors/__init__.py similarity index 100% rename from lerobot/common/motors/__init__.py rename to src/lerobot/motors/__init__.py diff --git a/lerobot/common/motors/dynamixel/__init__.py b/src/lerobot/motors/dynamixel/__init__.py similarity index 100% rename from lerobot/common/motors/dynamixel/__init__.py rename to src/lerobot/motors/dynamixel/__init__.py diff --git a/lerobot/common/motors/dynamixel/dynamixel.py b/src/lerobot/motors/dynamixel/dynamixel.py similarity index 99% rename from lerobot/common/motors/dynamixel/dynamixel.py rename to src/lerobot/motors/dynamixel/dynamixel.py index 9f0db90..d4f4164 100644 --- a/lerobot/common/motors/dynamixel/dynamixel.py +++ b/src/lerobot/motors/dynamixel/dynamixel.py @@ -22,7 +22,7 @@ import logging from copy import deepcopy 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 .tables import ( diff --git a/lerobot/common/motors/dynamixel/tables.py b/src/lerobot/motors/dynamixel/tables.py similarity index 100% rename from lerobot/common/motors/dynamixel/tables.py rename to src/lerobot/motors/dynamixel/tables.py diff --git a/lerobot/common/motors/feetech/__init__.py b/src/lerobot/motors/feetech/__init__.py similarity index 100% rename from lerobot/common/motors/feetech/__init__.py rename to src/lerobot/motors/feetech/__init__.py diff --git a/lerobot/common/motors/feetech/feetech.py b/src/lerobot/motors/feetech/feetech.py similarity index 99% rename from lerobot/common/motors/feetech/feetech.py rename to src/lerobot/motors/feetech/feetech.py index 4937fde..7edf869 100644 --- a/lerobot/common/motors/feetech/feetech.py +++ b/src/lerobot/motors/feetech/feetech.py @@ -17,7 +17,7 @@ from copy import deepcopy from enum import Enum 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 .tables import ( diff --git a/lerobot/common/motors/feetech/tables.py b/src/lerobot/motors/feetech/tables.py similarity index 100% rename from lerobot/common/motors/feetech/tables.py rename to src/lerobot/motors/feetech/tables.py diff --git a/lerobot/common/motors/motors_bus.py b/src/lerobot/motors/motors_bus.py similarity index 99% rename from lerobot/common/motors/motors_bus.py rename to src/lerobot/motors/motors_bus.py index 7ac9e68..7386bfb 100644 --- a/lerobot/common/motors/motors_bus.py +++ b/src/lerobot/motors/motors_bus.py @@ -32,8 +32,8 @@ import serial from deepdiff import DeepDiff from tqdm import tqdm -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.utils.utils import enter_pressed, move_cursor_up +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.utils.utils import enter_pressed, move_cursor_up NameOrID: TypeAlias = str | int Value: TypeAlias = int | float @@ -446,7 +446,7 @@ class MotorsBus(abc.ABC): except (FileNotFoundError, OSError, serial.SerialException) as e: raise ConnectionError( 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 @abc.abstractmethod diff --git a/lerobot/common/optim/__init__.py b/src/lerobot/optim/__init__.py similarity index 100% rename from lerobot/common/optim/__init__.py rename to src/lerobot/optim/__init__.py diff --git a/lerobot/common/optim/factory.py b/src/lerobot/optim/factory.py similarity index 96% rename from lerobot/common/optim/factory.py rename to src/lerobot/optim/factory.py index 10ff3df..bab95d0 100644 --- a/lerobot/common/optim/factory.py +++ b/src/lerobot/optim/factory.py @@ -18,8 +18,8 @@ from torch.optim import Optimizer from torch.optim.lr_scheduler import LRScheduler -from lerobot.common.policies.pretrained import PreTrainedPolicy from lerobot.configs.train import TrainPipelineConfig +from lerobot.policies.pretrained import PreTrainedPolicy def make_optimizer_and_scheduler( diff --git a/lerobot/common/optim/optimizers.py b/src/lerobot/optim/optimizers.py similarity index 97% rename from lerobot/common/optim/optimizers.py rename to src/lerobot/optim/optimizers.py index 903434f..ece4dc1 100644 --- a/lerobot/common/optim/optimizers.py +++ b/src/lerobot/optim/optimizers.py @@ -22,12 +22,12 @@ import draccus import torch from safetensors.torch import load_file, save_file -from lerobot.common.constants import ( +from lerobot.constants import ( OPTIMIZER_PARAM_GROUPS, OPTIMIZER_STATE, ) -from lerobot.common.datasets.utils import flatten_dict, unflatten_dict, write_json -from lerobot.common.utils.io_utils import deserialize_json_into_object +from lerobot.datasets.utils import flatten_dict, unflatten_dict, write_json +from lerobot.utils.io_utils import deserialize_json_into_object @dataclass diff --git a/lerobot/common/optim/schedulers.py b/src/lerobot/optim/schedulers.py similarity index 96% rename from lerobot/common/optim/schedulers.py rename to src/lerobot/optim/schedulers.py index 7e15839..d080181 100644 --- a/lerobot/common/optim/schedulers.py +++ b/src/lerobot/optim/schedulers.py @@ -22,9 +22,9 @@ import draccus from torch.optim import Optimizer from torch.optim.lr_scheduler import LambdaLR, LRScheduler -from lerobot.common.constants import SCHEDULER_STATE -from lerobot.common.datasets.utils import write_json -from lerobot.common.utils.io_utils import deserialize_json_into_object +from lerobot.constants import SCHEDULER_STATE +from lerobot.datasets.utils import write_json +from lerobot.utils.io_utils import deserialize_json_into_object @dataclass diff --git a/lerobot/common/policies/__init__.py b/src/lerobot/policies/__init__.py similarity index 100% rename from lerobot/common/policies/__init__.py rename to src/lerobot/policies/__init__.py diff --git a/lerobot/common/policies/act/configuration_act.py b/src/lerobot/policies/act/configuration_act.py similarity index 99% rename from lerobot/common/policies/act/configuration_act.py rename to src/lerobot/policies/act/configuration_act.py index 7a5819b..6f6c1c4 100644 --- a/lerobot/common/policies/act/configuration_act.py +++ b/src/lerobot/policies/act/configuration_act.py @@ -15,9 +15,9 @@ # limitations under the License. from dataclasses import dataclass, field -from lerobot.common.optim.optimizers import AdamWConfig from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.types import NormalizationMode +from lerobot.optim.optimizers import AdamWConfig @PreTrainedConfig.register_subclass("act") diff --git a/lerobot/common/policies/act/modeling_act.py b/src/lerobot/policies/act/modeling_act.py similarity index 99% rename from lerobot/common/policies/act/modeling_act.py rename to src/lerobot/policies/act/modeling_act.py index 1220665..ed911e9 100644 --- a/lerobot/common/policies/act/modeling_act.py +++ b/src/lerobot/policies/act/modeling_act.py @@ -33,10 +33,10 @@ from torch import Tensor, nn from torchvision.models._utils import IntermediateLayerGetter from torchvision.ops.misc import FrozenBatchNorm2d -from lerobot.common.constants import ACTION, OBS_IMAGES -from lerobot.common.policies.act.configuration_act import ACTConfig -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy +from lerobot.constants import ACTION, OBS_IMAGES +from lerobot.policies.act.configuration_act import ACTConfig +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy class ACTPolicy(PreTrainedPolicy): diff --git a/lerobot/common/policies/diffusion/configuration_diffusion.py b/src/lerobot/policies/diffusion/configuration_diffusion.py similarity index 99% rename from lerobot/common/policies/diffusion/configuration_diffusion.py rename to src/lerobot/policies/diffusion/configuration_diffusion.py index c8841f0..ce2de70 100644 --- a/lerobot/common/policies/diffusion/configuration_diffusion.py +++ b/src/lerobot/policies/diffusion/configuration_diffusion.py @@ -16,10 +16,10 @@ # limitations under the License. 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.types import NormalizationMode +from lerobot.optim.optimizers import AdamConfig +from lerobot.optim.schedulers import DiffuserSchedulerConfig @PreTrainedConfig.register_subclass("diffusion") diff --git a/lerobot/common/policies/diffusion/modeling_diffusion.py b/src/lerobot/policies/diffusion/modeling_diffusion.py similarity index 98% rename from lerobot/common/policies/diffusion/modeling_diffusion.py rename to src/lerobot/policies/diffusion/modeling_diffusion.py index 038136d..af40f7a 100644 --- a/lerobot/common/policies/diffusion/modeling_diffusion.py +++ b/src/lerobot/policies/diffusion/modeling_diffusion.py @@ -33,11 +33,11 @@ from diffusers.schedulers.scheduling_ddim import DDIMScheduler from diffusers.schedulers.scheduling_ddpm import DDPMScheduler from torch import Tensor, nn -from lerobot.common.constants import ACTION, OBS_ENV_STATE, OBS_IMAGES, OBS_STATE -from lerobot.common.policies.diffusion.configuration_diffusion import DiffusionConfig -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.utils import ( +from lerobot.constants import ACTION, OBS_ENV_STATE, OBS_IMAGES, OBS_STATE +from lerobot.policies.diffusion.configuration_diffusion import DiffusionConfig +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.utils import ( get_device_from_parameters, get_dtype_from_parameters, get_output_shape, diff --git a/lerobot/common/policies/factory.py b/src/lerobot/policies/factory.py similarity index 77% rename from lerobot/common/policies/factory.py rename to src/lerobot/policies/factory.py index 682bb8c..ef56bdb 100644 --- a/lerobot/common/policies/factory.py +++ b/src/lerobot/policies/factory.py @@ -18,60 +18,60 @@ import logging 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.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: """Get the policy's class and config class given a name (matching the policy class' `name` attribute).""" if name == "tdmpc": - from lerobot.common.policies.tdmpc.modeling_tdmpc import TDMPCPolicy + from lerobot.policies.tdmpc.modeling_tdmpc import TDMPCPolicy return TDMPCPolicy elif name == "diffusion": - from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy + from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy return DiffusionPolicy elif name == "act": - from lerobot.common.policies.act.modeling_act import ACTPolicy + from lerobot.policies.act.modeling_act import ACTPolicy return ACTPolicy elif name == "vqbet": - from lerobot.common.policies.vqbet.modeling_vqbet import VQBeTPolicy + from lerobot.policies.vqbet.modeling_vqbet import VQBeTPolicy return VQBeTPolicy elif name == "pi0": - from lerobot.common.policies.pi0.modeling_pi0 import PI0Policy + from lerobot.policies.pi0.modeling_pi0 import PI0Policy return PI0Policy elif name == "pi0fast": - from lerobot.common.policies.pi0fast.modeling_pi0fast import PI0FASTPolicy + from lerobot.policies.pi0fast.modeling_pi0fast import PI0FASTPolicy return PI0FASTPolicy elif name == "sac": - from lerobot.common.policies.sac.modeling_sac import SACPolicy + from lerobot.policies.sac.modeling_sac import SACPolicy return SACPolicy 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 elif name == "smolvla": - from lerobot.common.policies.smolvla.modeling_smolvla import SmolVLAPolicy + from lerobot.policies.smolvla.modeling_smolvla import SmolVLAPolicy return SmolVLAPolicy else: diff --git a/lerobot/common/policies/normalize.py b/src/lerobot/policies/normalize.py similarity index 100% rename from lerobot/common/policies/normalize.py rename to src/lerobot/policies/normalize.py diff --git a/lerobot/common/policies/pi0/configuration_pi0.py b/src/lerobot/policies/pi0/configuration_pi0.py similarity index 98% rename from lerobot/common/policies/pi0/configuration_pi0.py rename to src/lerobot/policies/pi0/configuration_pi0.py index 8c7cc13..c9728e4 100644 --- a/lerobot/common/policies/pi0/configuration_pi0.py +++ b/src/lerobot/policies/pi0/configuration_pi0.py @@ -14,12 +14,12 @@ 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.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.optim.optimizers import AdamWConfig +from lerobot.optim.schedulers import ( + CosineDecayWithWarmupSchedulerConfig, +) @PreTrainedConfig.register_subclass("pi0") diff --git a/lerobot/common/policies/pi0/conversion_scripts/benchmark.py b/src/lerobot/policies/pi0/conversion_scripts/benchmark.py similarity index 95% rename from lerobot/common/policies/pi0/conversion_scripts/benchmark.py rename to src/lerobot/policies/pi0/conversion_scripts/benchmark.py index cb3c0e9..c1a4882 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/benchmark.py +++ b/src/lerobot/policies/pi0/conversion_scripts/benchmark.py @@ -14,9 +14,9 @@ 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.datasets.lerobot_dataset import LeRobotDataset +from lerobot.policies.factory import make_policy torch.backends.cudnn.benchmark = True diff --git a/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py b/src/lerobot/policies/pi0/conversion_scripts/compare_with_jax.py similarity index 96% rename from lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py rename to src/lerobot/policies/pi0/conversion_scripts/compare_with_jax.py index 6bd7c91..c0c2e48 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/compare_with_jax.py +++ b/src/lerobot/policies/pi0/conversion_scripts/compare_with_jax.py @@ -18,9 +18,9 @@ from pathlib import Path 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.datasets.lerobot_dataset import LeRobotDatasetMetadata +from lerobot.policies.factory import make_policy def display(tensor: torch.Tensor): @@ -97,7 +97,7 @@ def main(): 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.pretrained_path = ckpt_torch_dir diff --git a/lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py b/src/lerobot/policies/pi0/conversion_scripts/conversion_utils.py similarity index 100% rename from lerobot/common/policies/pi0/conversion_scripts/conversion_utils.py rename to src/lerobot/policies/pi0/conversion_scripts/conversion_utils.py diff --git a/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py b/src/lerobot/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py similarity index 98% rename from lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py rename to src/lerobot/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py index 73ff506..742c9ab 100644 --- a/lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py +++ b/src/lerobot/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py @@ -33,13 +33,13 @@ python Converting pi0_base: ```python -python lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py \ +python -m lerobot.policies.pi0.conversion_scripts.convert_pi0_to_hf_lerobot \ --checkpoint_dir /home/remi_cadene/.cache/openpi/openpi-assets/checkpoints/pi0_base/params \ --output_path /home/remi_cadene/.cache/openpi/openpi-assets/checkpoints/pi0_base_pytorch ``` ```python -python lerobot/common/policies/pi0/conversion_scripts/convert_pi0_to_hf_lerobot.py \ +python -m lerobot.policies.pi0.conversion_scripts.convert_pi0_to_hf_lerobot \ --checkpoint_dir /home/remi_cadene/.cache/openpi/openpi-assets/checkpoints/pi0_aloha_sim/params \ --output_path /home/remi_cadene/.cache/openpi/openpi-assets/checkpoints/pi0_aloha_sim_pytorch ``` @@ -54,12 +54,12 @@ import orbax.checkpoint as ocp import torch from jax.sharding import SingleDeviceSharding -from lerobot.common.policies.pi0.configuration_pi0 import PI0Config -from lerobot.common.policies.pi0.conversion_scripts.conversion_utils import ( +from lerobot.policies.pi0.configuration_pi0 import PI0Config +from lerobot.policies.pi0.conversion_scripts.conversion_utils import ( get_gemma_config, get_paligemma_config, ) -from lerobot.common.policies.pi0.modeling_pi0 import PI0Policy +from lerobot.policies.pi0.modeling_pi0 import PI0Policy PRECISIONS = {"bfloat16": torch.bfloat16, "float32": torch.float32, "float16": torch.float16} diff --git a/lerobot/common/policies/pi0/flex_attention.py b/src/lerobot/policies/pi0/flex_attention.py similarity index 100% rename from lerobot/common/policies/pi0/flex_attention.py rename to src/lerobot/policies/pi0/flex_attention.py diff --git a/lerobot/common/policies/pi0/modeling_pi0.py b/src/lerobot/policies/pi0/modeling_pi0.py similarity index 98% rename from lerobot/common/policies/pi0/modeling_pi0.py rename to src/lerobot/policies/pi0/modeling_pi0.py index 97e66a2..241509d 100644 --- a/lerobot/common/policies/pi0/modeling_pi0.py +++ b/src/lerobot/policies/pi0/modeling_pi0.py @@ -29,7 +29,7 @@ pip install -e ".[pi0]" Example of finetuning the pi0 pretrained model (`pi0_base` in `openpi`): ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.path=lerobot/pi0 \ --dataset.repo_id=danaaubakirova/koch_test ``` @@ -37,7 +37,7 @@ python lerobot/scripts/train.py \ Example of finetuning the pi0 neural network with PaliGemma and expert Gemma pretrained with VLM default parameters before pi0 finetuning: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=pi0 \ --dataset.repo_id=danaaubakirova/koch_test ``` @@ -57,15 +57,15 @@ import torch.nn.functional as F # noqa: N812 from torch import Tensor, nn from transformers import AutoTokenizer -from lerobot.common.constants import ACTION, OBS_STATE -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pi0.configuration_pi0 import PI0Config -from lerobot.common.policies.pi0.paligemma_with_expert import ( +from lerobot.constants import ACTION, OBS_STATE +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pi0.configuration_pi0 import PI0Config +from lerobot.policies.pi0.paligemma_with_expert import ( PaliGemmaWithExpertConfig, PaliGemmaWithExpertModel, ) -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.utils.utils import get_safe_dtype +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.utils.utils import get_safe_dtype def create_sinusoidal_pos_embedding( diff --git a/lerobot/common/policies/pi0/paligemma_with_expert.py b/src/lerobot/policies/pi0/paligemma_with_expert.py similarity index 99% rename from lerobot/common/policies/pi0/paligemma_with_expert.py rename to src/lerobot/policies/pi0/paligemma_with_expert.py index fb5077f..f0f5713 100644 --- a/lerobot/common/policies/pi0/paligemma_with_expert.py +++ b/src/lerobot/policies/pi0/paligemma_with_expert.py @@ -27,7 +27,7 @@ from transformers import ( ) from transformers.models.auto import CONFIG_MAPPING -from lerobot.common.policies.pi0.flex_attention import flex_attention_forward +from lerobot.policies.pi0.flex_attention import flex_attention_forward def apply_rope(x, positions, max_wavelength=10_000): diff --git a/lerobot/common/policies/pi0fast/configuration_pi0fast.py b/src/lerobot/policies/pi0fast/configuration_pi0fast.py similarity index 97% rename from lerobot/common/policies/pi0fast/configuration_pi0fast.py rename to src/lerobot/policies/pi0fast/configuration_pi0fast.py index 29c856e..b72bcd7 100644 --- a/lerobot/common/policies/pi0fast/configuration_pi0fast.py +++ b/src/lerobot/policies/pi0fast/configuration_pi0fast.py @@ -1,11 +1,11 @@ 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.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.optim.optimizers import AdamWConfig +from lerobot.optim.schedulers import ( + CosineDecayWithWarmupSchedulerConfig, +) @PreTrainedConfig.register_subclass("pi0fast") diff --git a/lerobot/common/policies/pi0fast/modeling_pi0fast.py b/src/lerobot/policies/pi0fast/modeling_pi0fast.py similarity index 99% rename from lerobot/common/policies/pi0fast/modeling_pi0fast.py rename to src/lerobot/policies/pi0fast/modeling_pi0fast.py index dbf5266..d3e576d 100644 --- a/lerobot/common/policies/pi0fast/modeling_pi0fast.py +++ b/src/lerobot/policies/pi0fast/modeling_pi0fast.py @@ -24,14 +24,14 @@ Designed by Physical Intelligence. Ported from Jax by Hugging Face. Example of finetuning the pi0+FAST pretrained model (`pi0_fast_base` in `openpi`): ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.path=lerobot/pi0fast_base \ --dataset.repo_id=danaaubakirova/koch_test ``` Example of training the pi0+FAST neural network with from scratch: ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=pi0fast \ --dataset.repo_id=danaaubakirova/koch_test ``` @@ -56,10 +56,10 @@ from transformers import AutoProcessor, AutoTokenizer, PaliGemmaForConditionalGe from transformers.cache_utils import HybridCache, StaticCache from transformers.models.auto import CONFIG_MAPPING -from lerobot.common.constants import ACTION, OBS_STATE -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pi0fast.configuration_pi0fast import PI0FASTConfig -from lerobot.common.policies.pretrained import PreTrainedPolicy +from lerobot.constants import ACTION, OBS_STATE +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pi0fast.configuration_pi0fast import PI0FASTConfig +from lerobot.policies.pretrained import PreTrainedPolicy PRECISION = { "float16": torch.float16, diff --git a/lerobot/common/policies/pretrained.py b/src/lerobot/policies/pretrained.py similarity index 99% rename from lerobot/common/policies/pretrained.py rename to src/lerobot/policies/pretrained.py index bc9276d..d18b798 100644 --- a/lerobot/common/policies/pretrained.py +++ b/src/lerobot/policies/pretrained.py @@ -28,9 +28,9 @@ from safetensors.torch import load_model as load_model_as_safetensor from safetensors.torch import save_model as save_model_as_safetensor from torch import Tensor, nn -from lerobot.common.utils.hub import HubMixin from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.train import TrainPipelineConfig +from lerobot.utils.hub import HubMixin T = TypeVar("T", bound="PreTrainedPolicy") diff --git a/lerobot/common/policies/sac/configuration_sac.py b/src/lerobot/policies/sac/configuration_sac.py similarity index 98% rename from lerobot/common/policies/sac/configuration_sac.py rename to src/lerobot/policies/sac/configuration_sac.py index db58beb..c57eeeb 100644 --- a/lerobot/common/policies/sac/configuration_sac.py +++ b/src/lerobot/policies/sac/configuration_sac.py @@ -17,10 +17,10 @@ from dataclasses import dataclass, field -from lerobot.common.constants import ACTION, OBS_IMAGE, OBS_STATE -from lerobot.common.optim.optimizers import MultiAdamConfig from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.types import NormalizationMode +from lerobot.constants import ACTION, OBS_IMAGE, OBS_STATE +from lerobot.optim.optimizers import MultiAdamConfig def is_image_feature(key: str) -> bool: diff --git a/lerobot/common/policies/sac/modeling_sac.py b/src/lerobot/policies/sac/modeling_sac.py similarity index 99% rename from lerobot/common/policies/sac/modeling_sac.py rename to src/lerobot/policies/sac/modeling_sac.py index 1ca4693..54ea122 100644 --- a/lerobot/common/policies/sac/modeling_sac.py +++ b/src/lerobot/policies/sac/modeling_sac.py @@ -27,10 +27,10 @@ import torch.nn.functional as F # noqa: N812 from torch import Tensor from torch.distributions import MultivariateNormal, TanhTransform, Transform, TransformedDistribution -from lerobot.common.policies.normalize import NormalizeBuffer -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.sac.configuration_sac import SACConfig, is_image_feature -from lerobot.common.policies.utils import get_device_from_parameters +from lerobot.policies.normalize import NormalizeBuffer +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.sac.configuration_sac import SACConfig, is_image_feature +from lerobot.policies.utils import get_device_from_parameters DISCRETE_DIMENSION_INDEX = -1 # Gripper is always the last dimension diff --git a/lerobot/common/policies/sac/reward_model/configuration_classifier.py b/src/lerobot/policies/sac/reward_model/configuration_classifier.py similarity index 94% rename from lerobot/common/policies/sac/reward_model/configuration_classifier.py rename to src/lerobot/policies/sac/reward_model/configuration_classifier.py index 6e2a551..fc53283 100644 --- a/lerobot/common/policies/sac/reward_model/configuration_classifier.py +++ b/src/lerobot/policies/sac/reward_model/configuration_classifier.py @@ -15,10 +15,10 @@ # limitations under the License. from dataclasses import dataclass, field -from lerobot.common.optim.optimizers import AdamWConfig, OptimizerConfig -from lerobot.common.optim.schedulers import LRSchedulerConfig from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.types import NormalizationMode +from lerobot.optim.optimizers import AdamWConfig, OptimizerConfig +from lerobot.optim.schedulers import LRSchedulerConfig @PreTrainedConfig.register_subclass(name="reward_classifier") diff --git a/lerobot/common/policies/sac/reward_model/modeling_classifier.py b/src/lerobot/policies/sac/reward_model/modeling_classifier.py similarity index 97% rename from lerobot/common/policies/sac/reward_model/modeling_classifier.py rename to src/lerobot/policies/sac/reward_model/modeling_classifier.py index 7fec67f..cadd1c9 100644 --- a/lerobot/common/policies/sac/reward_model/modeling_classifier.py +++ b/src/lerobot/policies/sac/reward_model/modeling_classifier.py @@ -19,10 +19,10 @@ import logging import torch from torch import Tensor, nn -from lerobot.common.constants import OBS_IMAGE, REWARD -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig +from lerobot.constants import OBS_IMAGE, REWARD +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig class ClassifierOutput: diff --git a/lerobot/common/policies/smolvla/configuration_smolvla.py b/src/lerobot/policies/smolvla/configuration_smolvla.py similarity index 98% rename from lerobot/common/policies/smolvla/configuration_smolvla.py rename to src/lerobot/policies/smolvla/configuration_smolvla.py index 5996cf2..571900c 100644 --- a/lerobot/common/policies/smolvla/configuration_smolvla.py +++ b/src/lerobot/policies/smolvla/configuration_smolvla.py @@ -14,12 +14,12 @@ 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.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.optim.optimizers import AdamWConfig +from lerobot.optim.schedulers import ( + CosineDecayWithWarmupSchedulerConfig, +) @PreTrainedConfig.register_subclass("smolvla") diff --git a/lerobot/common/policies/smolvla/modeling_smolvla.py b/src/lerobot/policies/smolvla/modeling_smolvla.py similarity index 98% rename from lerobot/common/policies/smolvla/modeling_smolvla.py rename to src/lerobot/policies/smolvla/modeling_smolvla.py index 3619998..11bb8bf 100644 --- a/lerobot/common/policies/smolvla/modeling_smolvla.py +++ b/src/lerobot/policies/smolvla/modeling_smolvla.py @@ -28,7 +28,7 @@ pip install -e ".[smolvla]" Example of finetuning the smolvla pretrained model (`smolvla_base`): ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.path=lerobot/smolvla_base \ --dataset.repo_id=danaaubakirova/svla_so100_task1_v3 \ --batch_size=64 \ @@ -38,7 +38,7 @@ python lerobot/scripts/train.py \ Example of finetuning a smolVLA. SmolVLA is composed of a pretrained VLM, and an action expert. ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --policy.type=smolvla \ --dataset.repo_id=danaaubakirova/svla_so100_task1_v3 \ --batch_size=64 \ @@ -63,18 +63,18 @@ import torch.nn.functional as F # noqa: N812 from torch import Tensor, nn from transformers import AutoProcessor -from lerobot.common.constants import ACTION, OBS_STATE -from lerobot.common.policies.normalize import ( +from lerobot.constants import ACTION, OBS_STATE +from lerobot.policies.normalize import ( Normalize, Unnormalize, ) -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.smolvla.configuration_smolvla import SmolVLAConfig -from lerobot.common.policies.smolvla.smolvlm_with_expert import SmolVLMWithExpertModel -from lerobot.common.policies.utils import ( +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.smolvla.configuration_smolvla import SmolVLAConfig +from lerobot.policies.smolvla.smolvlm_with_expert import SmolVLMWithExpertModel +from lerobot.policies.utils import ( populate_queues, ) -from lerobot.common.utils.utils import get_safe_dtype +from lerobot.utils.utils import get_safe_dtype # Matches ".soNNN", optionally followed by "-something", up to the "_buffer_" marker _VARIANT_RE = re.compile(r"\.so\d+(?:-[\w]+)?_buffer_") diff --git a/lerobot/common/policies/smolvla/smolvlm_with_expert.py b/src/lerobot/policies/smolvla/smolvlm_with_expert.py similarity index 100% rename from lerobot/common/policies/smolvla/smolvlm_with_expert.py rename to src/lerobot/policies/smolvla/smolvlm_with_expert.py diff --git a/lerobot/common/policies/tdmpc/configuration_tdmpc.py b/src/lerobot/policies/tdmpc/configuration_tdmpc.py similarity index 99% rename from lerobot/common/policies/tdmpc/configuration_tdmpc.py rename to src/lerobot/policies/tdmpc/configuration_tdmpc.py index 3fce01d..3c1a299 100644 --- a/lerobot/common/policies/tdmpc/configuration_tdmpc.py +++ b/src/lerobot/policies/tdmpc/configuration_tdmpc.py @@ -16,9 +16,9 @@ # limitations under the License. from dataclasses import dataclass, field -from lerobot.common.optim.optimizers import AdamConfig from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.types import NormalizationMode +from lerobot.optim.optimizers import AdamConfig @PreTrainedConfig.register_subclass("tdmpc") diff --git a/lerobot/common/policies/tdmpc/modeling_tdmpc.py b/src/lerobot/policies/tdmpc/modeling_tdmpc.py similarity index 98% rename from lerobot/common/policies/tdmpc/modeling_tdmpc.py rename to src/lerobot/policies/tdmpc/modeling_tdmpc.py index 4bb564f..8b70b26 100644 --- a/lerobot/common/policies/tdmpc/modeling_tdmpc.py +++ b/src/lerobot/policies/tdmpc/modeling_tdmpc.py @@ -35,11 +35,11 @@ import torch.nn as nn import torch.nn.functional as F # noqa: N812 from torch import Tensor -from lerobot.common.constants import ACTION, OBS_ENV_STATE, OBS_IMAGE, OBS_STATE, REWARD -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.tdmpc.configuration_tdmpc import TDMPCConfig -from lerobot.common.policies.utils import get_device_from_parameters, get_output_shape, populate_queues +from lerobot.constants import ACTION, OBS_ENV_STATE, OBS_IMAGE, OBS_STATE, REWARD +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.tdmpc.configuration_tdmpc import TDMPCConfig +from lerobot.policies.utils import get_device_from_parameters, get_output_shape, populate_queues class TDMPCPolicy(PreTrainedPolicy): diff --git a/lerobot/common/policies/utils.py b/src/lerobot/policies/utils.py similarity index 100% rename from lerobot/common/policies/utils.py rename to src/lerobot/policies/utils.py diff --git a/lerobot/common/policies/vqbet/configuration_vqbet.py b/src/lerobot/policies/vqbet/configuration_vqbet.py similarity index 98% rename from lerobot/common/policies/vqbet/configuration_vqbet.py rename to src/lerobot/policies/vqbet/configuration_vqbet.py index 28e9c43..d7a79f1 100644 --- a/lerobot/common/policies/vqbet/configuration_vqbet.py +++ b/src/lerobot/policies/vqbet/configuration_vqbet.py @@ -18,10 +18,10 @@ from dataclasses import dataclass, field -from lerobot.common.optim.optimizers import AdamConfig -from lerobot.common.optim.schedulers import VQBeTSchedulerConfig from lerobot.configs.policies import PreTrainedConfig from lerobot.configs.types import NormalizationMode +from lerobot.optim.optimizers import AdamConfig +from lerobot.optim.schedulers import VQBeTSchedulerConfig @PreTrainedConfig.register_subclass("vqbet") diff --git a/lerobot/common/policies/vqbet/modeling_vqbet.py b/src/lerobot/policies/vqbet/modeling_vqbet.py similarity index 99% rename from lerobot/common/policies/vqbet/modeling_vqbet.py rename to src/lerobot/policies/vqbet/modeling_vqbet.py index a76bea2..c045ccb 100644 --- a/lerobot/common/policies/vqbet/modeling_vqbet.py +++ b/src/lerobot/policies/vqbet/modeling_vqbet.py @@ -27,12 +27,12 @@ import torch.nn.functional as F # noqa: N812 import torchvision from torch import Tensor, nn -from lerobot.common.constants import ACTION, OBS_IMAGES, OBS_STATE -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.utils import get_device_from_parameters, get_output_shape, populate_queues -from lerobot.common.policies.vqbet.configuration_vqbet import VQBeTConfig -from lerobot.common.policies.vqbet.vqbet_utils import GPT, ResidualVQ +from lerobot.constants import ACTION, OBS_IMAGES, OBS_STATE +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.utils import get_device_from_parameters, get_output_shape, populate_queues +from lerobot.policies.vqbet.configuration_vqbet import VQBeTConfig +from lerobot.policies.vqbet.vqbet_utils import GPT, ResidualVQ # ruff: noqa: N806 diff --git a/lerobot/common/policies/vqbet/vqbet_utils.py b/src/lerobot/policies/vqbet/vqbet_utils.py similarity index 99% rename from lerobot/common/policies/vqbet/vqbet_utils.py rename to src/lerobot/policies/vqbet/vqbet_utils.py index 09a86c0..03b02a2 100644 --- a/lerobot/common/policies/vqbet/vqbet_utils.py +++ b/src/lerobot/policies/vqbet/vqbet_utils.py @@ -30,7 +30,7 @@ from torch import einsum, nn from torch.cuda.amp import autocast from torch.optim import Optimizer -from lerobot.common.policies.vqbet.configuration_vqbet import VQBeTConfig +from lerobot.policies.vqbet.configuration_vqbet import VQBeTConfig # ruff: noqa: N806 diff --git a/lerobot/record.py b/src/lerobot/record.py similarity index 93% rename from lerobot/record.py rename to src/lerobot/record.py index ce6f538..54d7f39 100644 --- a/lerobot/record.py +++ b/src/lerobot/record.py @@ -44,17 +44,19 @@ from pprint import pformat import numpy as np import rerun as rr -from lerobot.common.cameras import ( # noqa: F401 +from lerobot.cameras import ( # noqa: F401 CameraConfig, # noqa: F401 ) -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 -from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 -from lerobot.common.datasets.image_writer import safe_stop_image_writer -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import build_dataset_frame, hw_to_dataset_features -from lerobot.common.policies.factory import make_policy -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.robots import ( # noqa: F401 +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 +from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 +from lerobot.configs import parser +from lerobot.configs.policies import PreTrainedConfig +from lerobot.datasets.image_writer import safe_stop_image_writer +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import build_dataset_frame, hw_to_dataset_features +from lerobot.policies.factory import make_policy +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.robots import ( # noqa: F401 Robot, RobotConfig, koch_follower, @@ -62,7 +64,7 @@ from lerobot.common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from lerobot.common.teleoperators import ( # noqa: F401 +from lerobot.teleoperators import ( # noqa: F401 Teleoperator, TeleoperatorConfig, koch_leader, @@ -70,22 +72,20 @@ from lerobot.common.teleoperators import ( # noqa: F401 so100_leader, so101_leader, ) -from lerobot.common.utils.control_utils import ( +from lerobot.utils.control_utils import ( init_keyboard_listener, is_headless, predict_action, sanity_check_dataset_name, sanity_check_dataset_robot_compatibility, ) -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import ( +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import ( get_safe_torch_device, init_logging, log_say, ) -from lerobot.common.utils.visualization_utils import _init_rerun -from lerobot.configs import parser -from lerobot.configs.policies import PreTrainedConfig +from lerobot.utils.visualization_utils import _init_rerun @dataclass diff --git a/lerobot/replay.py b/src/lerobot/replay.py similarity index 92% rename from lerobot/replay.py rename to src/lerobot/replay.py index 36eb086..ef20c28 100644 --- a/lerobot/replay.py +++ b/src/lerobot/replay.py @@ -35,8 +35,8 @@ from pprint import pformat import draccus -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.robots import ( # noqa: F401 +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.robots import ( # noqa: F401 Robot, RobotConfig, koch_follower, @@ -44,8 +44,8 @@ from lerobot.common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import ( +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import ( init_logging, log_say, ) diff --git a/lerobot/common/robots/__init__.py b/src/lerobot/robots/__init__.py similarity index 100% rename from lerobot/common/robots/__init__.py rename to src/lerobot/robots/__init__.py diff --git a/lerobot/common/robots/config.py b/src/lerobot/robots/config.py similarity index 100% rename from lerobot/common/robots/config.py rename to src/lerobot/robots/config.py diff --git a/lerobot/common/robots/koch_follower/__init__.py b/src/lerobot/robots/koch_follower/__init__.py similarity index 100% rename from lerobot/common/robots/koch_follower/__init__.py rename to src/lerobot/robots/koch_follower/__init__.py diff --git a/lerobot/common/robots/koch_follower/config_koch_follower.py b/src/lerobot/robots/koch_follower/config_koch_follower.py similarity index 96% rename from lerobot/common/robots/koch_follower/config_koch_follower.py rename to src/lerobot/robots/koch_follower/config_koch_follower.py index 6ac1647..a7c9249 100644 --- a/lerobot/common/robots/koch_follower/config_koch_follower.py +++ b/src/lerobot/robots/koch_follower/config_koch_follower.py @@ -14,7 +14,7 @@ from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig +from lerobot.cameras import CameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/koch_follower/koch.mdx b/src/lerobot/robots/koch_follower/koch.mdx similarity index 96% rename from lerobot/common/robots/koch_follower/koch.mdx rename to src/lerobot/robots/koch_follower/koch.mdx index c398659..f70a180 100644 --- a/lerobot/common/robots/koch_follower/koch.mdx +++ b/src/lerobot/robots/koch_follower/koch.mdx @@ -29,7 +29,7 @@ pip install -e ".[dynamixel]" To find the port for each bus servo adapter, run this script: ```bash -python lerobot/find_port.py +python -m lerobot.find_port ``` @@ -103,7 +103,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.robots.koch_follower import KochFollower, KochFollowerConfig +from lerobot.robots.koch_follower import KochFollower, KochFollowerConfig config = KochFollowerConfig( port="/dev/tty.usbmodem575E0031751", @@ -169,7 +169,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.teleoperators.koch_leader import KochLeader, KochLeaderConfig +from lerobot.teleoperators.koch_leader import KochLeader, KochLeaderConfig config = KochLeaderConfig( port="/dev/tty.usbmodem575E0031751", @@ -203,7 +203,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.robots.koch_follower import KochFollowerConfig, KochFollower +from lerobot.robots.koch_follower import KochFollowerConfig, KochFollower config = KochFollowerConfig( port="/dev/tty.usbmodem585A0076891", @@ -237,7 +237,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.teleoperators.koch_leader import KochLeaderConfig, KochLeader +from lerobot.teleoperators.koch_leader import KochLeaderConfig, KochLeader config = KochLeaderConfig( port="/dev/tty.usbmodem575E0031751", diff --git a/lerobot/common/robots/koch_follower/koch_follower.py b/src/lerobot/robots/koch_follower/koch_follower.py similarity index 97% rename from lerobot/common/robots/koch_follower/koch_follower.py rename to src/lerobot/robots/koch_follower/koch_follower.py index 64ece25..1cfc6cf 100644 --- a/lerobot/common/robots/koch_follower/koch_follower.py +++ b/src/lerobot/robots/koch_follower/koch_follower.py @@ -19,10 +19,10 @@ import time from functools import cached_property from typing import Any -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.dynamixel import ( +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.dynamixel import ( DynamixelMotorsBus, OperatingMode, ) diff --git a/lerobot/common/robots/lekiwi/__init__.py b/src/lerobot/robots/lekiwi/__init__.py similarity index 100% rename from lerobot/common/robots/lekiwi/__init__.py rename to src/lerobot/robots/lekiwi/__init__.py diff --git a/lerobot/common/robots/lekiwi/config_lekiwi.py b/src/lerobot/robots/lekiwi/config_lekiwi.py similarity index 95% rename from lerobot/common/robots/lekiwi/config_lekiwi.py rename to src/lerobot/robots/lekiwi/config_lekiwi.py index 022d09c..f0f8c24 100644 --- a/lerobot/common/robots/lekiwi/config_lekiwi.py +++ b/src/lerobot/robots/lekiwi/config_lekiwi.py @@ -14,8 +14,8 @@ from dataclasses import dataclass, field -from lerobot.common.cameras.configs import CameraConfig, Cv2Rotation -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig +from lerobot.cameras.configs import CameraConfig, Cv2Rotation +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/lekiwi/lekiwi.mdx b/src/lerobot/robots/lekiwi/lekiwi.mdx similarity index 97% rename from lerobot/common/robots/lekiwi/lekiwi.mdx rename to src/lerobot/robots/lekiwi/lekiwi.mdx index 6eaebce..61b1c05 100644 --- a/lerobot/common/robots/lekiwi/lekiwi.mdx +++ b/src/lerobot/robots/lekiwi/lekiwi.mdx @@ -47,7 +47,7 @@ First, we will assemble the two SO100/SO101 arms. One to attach to the mobile ba To find the port for each bus servo adapter, run this script: ```bash -python lerobot/find_port.py +python -m lerobot.find_port ``` @@ -175,7 +175,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.teleoperators.so100_leader import SO100LeaderConfig, SO100Leader +from lerobot.teleoperators.so100_leader import SO100LeaderConfig, SO100Leader config = SO100LeaderConfig( port="/dev/tty.usbmodem58760431551", @@ -197,7 +197,7 @@ leader.disconnect() To teleoperate, SSH into your Raspberry Pi, and run `conda activate lerobot` and this command: ```bash -python -m lerobot.common.robots.lekiwi.lekiwi_host --robot.id=my_awesome_kiwi +python -m lerobot.robots.lekiwi.lekiwi_host --robot.id=my_awesome_kiwi ``` Then on your laptop, also run `conda activate lerobot` and run the API example, make sure you set the correct `remote_ip` and `port` in `examples/lekiwi/teleoperate.py`. @@ -227,7 +227,7 @@ You should see on your laptop something like this: ```[INFO] Connected to remote | F | Decrease speed | > [!TIP] -> If you use a different keyboard, you can change the keys for each command in the [`LeKiwiConfig`](../lerobot/common/robot_devices/robots/configs.py). +> If you use a different keyboard, you can change the keys for each command in the [`LeKiwiConfig`](../src/lerobot/robot_devices/robots/configs.py). ### Wired version If you have the **wired** LeKiwi version, please run all commands on your laptop. diff --git a/lerobot/common/robots/lekiwi/lekiwi.py b/src/lerobot/robots/lekiwi/lekiwi.py similarity index 98% rename from lerobot/common/robots/lekiwi/lekiwi.py rename to src/lerobot/robots/lekiwi/lekiwi.py index f6a9b8b..ff1465d 100644 --- a/lerobot/common/robots/lekiwi/lekiwi.py +++ b/src/lerobot/robots/lekiwi/lekiwi.py @@ -22,10 +22,10 @@ from typing import Any import numpy as np -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import ( +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import ( FeetechMotorsBus, OperatingMode, ) diff --git a/lerobot/common/robots/lekiwi/lekiwi_client.py b/src/lerobot/robots/lekiwi/lekiwi_client.py similarity index 99% rename from lerobot/common/robots/lekiwi/lekiwi_client.py rename to src/lerobot/robots/lekiwi/lekiwi_client.py index f79b7f8..ffde1c8 100644 --- a/lerobot/common/robots/lekiwi/lekiwi_client.py +++ b/src/lerobot/robots/lekiwi/lekiwi_client.py @@ -25,7 +25,7 @@ import numpy as np import torch import zmq -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from ..robot import Robot from .config_lekiwi import LeKiwiClientConfig diff --git a/lerobot/common/robots/lekiwi/lekiwi_host.py b/src/lerobot/robots/lekiwi/lekiwi_host.py similarity index 100% rename from lerobot/common/robots/lekiwi/lekiwi_host.py rename to src/lerobot/robots/lekiwi/lekiwi_host.py diff --git a/lerobot/common/robots/robot.py b/src/lerobot/robots/robot.py similarity index 98% rename from lerobot/common/robots/robot.py rename to src/lerobot/robots/robot.py index 76c57fa..6820645 100644 --- a/lerobot/common/robots/robot.py +++ b/src/lerobot/robots/robot.py @@ -18,8 +18,8 @@ from typing import Any, Type import draccus -from lerobot.common.constants import HF_LEROBOT_CALIBRATION, ROBOTS -from lerobot.common.motors import MotorCalibration +from lerobot.constants import HF_LEROBOT_CALIBRATION, ROBOTS +from lerobot.motors import MotorCalibration from .config import RobotConfig diff --git a/lerobot/common/robots/so100_follower/__init__.py b/src/lerobot/robots/so100_follower/__init__.py similarity index 100% rename from lerobot/common/robots/so100_follower/__init__.py rename to src/lerobot/robots/so100_follower/__init__.py diff --git a/lerobot/common/robots/so100_follower/config_so100_follower.py b/src/lerobot/robots/so100_follower/config_so100_follower.py similarity index 97% rename from lerobot/common/robots/so100_follower/config_so100_follower.py rename to src/lerobot/robots/so100_follower/config_so100_follower.py index b76675d..249b449 100644 --- a/lerobot/common/robots/so100_follower/config_so100_follower.py +++ b/src/lerobot/robots/so100_follower/config_so100_follower.py @@ -14,7 +14,7 @@ from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig +from lerobot.cameras import CameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/so100_follower/so100.mdx b/src/lerobot/robots/so100_follower/so100.mdx similarity index 98% rename from lerobot/common/robots/so100_follower/so100.mdx rename to src/lerobot/robots/so100_follower/so100.mdx index 5443a68..f5eea6a 100644 --- a/lerobot/common/robots/so100_follower/so100.mdx +++ b/src/lerobot/robots/so100_follower/so100.mdx @@ -24,7 +24,7 @@ Unlike the SO-101, the motor connectors are not easily accessible once the arm i To find the port for each bus servo adapter, run this script: ```bash -python lerobot/find_port.py +python -m lerobot.find_port ``` @@ -98,7 +98,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.robots.so100_follower import SO100Follower, SO100FollowerConfig +from lerobot.robots.so100_follower import SO100Follower, SO100FollowerConfig config = SO100FollowerConfig( port="/dev/tty.usbmodem585A0076841", @@ -163,7 +163,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig +from lerobot.teleoperators.so100_leader import SO100Leader, SO100LeaderConfig config = SO100LeaderConfig( port="/dev/tty.usbmodem585A0076841", @@ -434,7 +434,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.robots.so100_follower import SO100FollowerConfig, SO100Follower +from lerobot.robots.so100_follower import SO100FollowerConfig, SO100Follower config = SO100FollowerConfig( port="/dev/tty.usbmodem585A0076891", @@ -468,7 +468,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.teleoperators.so100_leader import SO100LeaderConfig, SO100Leader +from lerobot.teleoperators.so100_leader import SO100LeaderConfig, SO100Leader config = SO100LeaderConfig( port="/dev/tty.usbmodem58760431551", diff --git a/lerobot/common/robots/so100_follower/so100_follower.py b/src/lerobot/robots/so100_follower/so100_follower.py similarity index 96% rename from lerobot/common/robots/so100_follower/so100_follower.py rename to src/lerobot/robots/so100_follower/so100_follower.py index 9520499..e5da6bc 100644 --- a/lerobot/common/robots/so100_follower/so100_follower.py +++ b/src/lerobot/robots/so100_follower/so100_follower.py @@ -19,10 +19,10 @@ import time from functools import cached_property from typing import Any -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import ( +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import ( FeetechMotorsBus, OperatingMode, ) diff --git a/lerobot/common/robots/so100_follower/so100_follower_end_effector.py b/src/lerobot/robots/so100_follower/so100_follower_end_effector.py similarity index 96% rename from lerobot/common/robots/so100_follower/so100_follower_end_effector.py rename to src/lerobot/robots/so100_follower/so100_follower_end_effector.py index 82e8930..d01b60e 100644 --- a/lerobot/common/robots/so100_follower/so100_follower_end_effector.py +++ b/src/lerobot/robots/so100_follower/so100_follower_end_effector.py @@ -20,11 +20,11 @@ from typing import Any import numpy as np -from lerobot.common.cameras import make_cameras_from_configs -from lerobot.common.errors import DeviceNotConnectedError -from lerobot.common.model.kinematics import RobotKinematics -from lerobot.common.motors import Motor, MotorNormMode -from lerobot.common.motors.feetech import FeetechMotorsBus +from lerobot.cameras import make_cameras_from_configs +from lerobot.errors import DeviceNotConnectedError +from lerobot.model.kinematics import RobotKinematics +from lerobot.motors import Motor, MotorNormMode +from lerobot.motors.feetech import FeetechMotorsBus from . import SO100Follower from .config_so100_follower import SO100FollowerEndEffectorConfig diff --git a/lerobot/common/robots/so101_follower/__init__.py b/src/lerobot/robots/so101_follower/__init__.py similarity index 100% rename from lerobot/common/robots/so101_follower/__init__.py rename to src/lerobot/robots/so101_follower/__init__.py diff --git a/lerobot/common/robots/so101_follower/config_so101_follower.py b/src/lerobot/robots/so101_follower/config_so101_follower.py similarity index 96% rename from lerobot/common/robots/so101_follower/config_so101_follower.py rename to src/lerobot/robots/so101_follower/config_so101_follower.py index 6dbf21f..be630e6 100644 --- a/lerobot/common/robots/so101_follower/config_so101_follower.py +++ b/src/lerobot/robots/so101_follower/config_so101_follower.py @@ -16,7 +16,7 @@ from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig +from lerobot.cameras import CameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/so101_follower/so101.mdx b/src/lerobot/robots/so101_follower/so101.mdx similarity index 97% rename from lerobot/common/robots/so101_follower/so101.mdx rename to src/lerobot/robots/so101_follower/so101.mdx index 36bd4fc..c49807d 100644 --- a/lerobot/common/robots/so101_follower/so101.mdx +++ b/src/lerobot/robots/so101_follower/so101.mdx @@ -136,7 +136,7 @@ Remove all support material from the 3D-printed parts. The easiest way to do thi To find the port for each bus servo adapter, run this script: ```bash -python lerobot/find_port.py +python -m lerobot.find_port ``` @@ -218,7 +218,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.robots.so101_follower import SO101Follower, SO101FollowerConfig +from lerobot.robots.so101_follower import SO101Follower, SO101FollowerConfig config = SO101FollowerConfig( port="/dev/tty.usbmodem585A0076841", @@ -284,7 +284,7 @@ python -m lerobot.setup_motors \ ```python -from lerobot.common.teleoperators.so101_leader import SO101Leader, SO101LeaderConfig +from lerobot.teleoperators.so101_leader import SO101Leader, SO101LeaderConfig config = SO101LeaderConfig( port="/dev/tty.usbmodem585A0076841", @@ -318,7 +318,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.robots.so101_follower import SO101FollowerConfig, SO101Follower +from lerobot.robots.so101_follower import SO101FollowerConfig, SO101Follower config = SO101FollowerConfig( port="/dev/tty.usbmodem585A0076891", @@ -360,7 +360,7 @@ python -m lerobot.calibrate \ ```python -from lerobot.common.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader +from lerobot.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader config = SO101LeaderConfig( port="/dev/tty.usbmodem58760431551", diff --git a/lerobot/common/robots/so101_follower/so101_follower.py b/src/lerobot/robots/so101_follower/so101_follower.py similarity index 96% rename from lerobot/common/robots/so101_follower/so101_follower.py rename to src/lerobot/robots/so101_follower/so101_follower.py index a3c7aa0..3ae3c39 100644 --- a/lerobot/common/robots/so101_follower/so101_follower.py +++ b/src/lerobot/robots/so101_follower/so101_follower.py @@ -19,10 +19,10 @@ import time from functools import cached_property from typing import Any -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import ( +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import ( FeetechMotorsBus, OperatingMode, ) diff --git a/lerobot/common/robots/stretch3/README.md b/src/lerobot/robots/stretch3/README.md similarity index 100% rename from lerobot/common/robots/stretch3/README.md rename to src/lerobot/robots/stretch3/README.md diff --git a/lerobot/common/robots/stretch3/__init__.py b/src/lerobot/robots/stretch3/__init__.py similarity index 100% rename from lerobot/common/robots/stretch3/__init__.py rename to src/lerobot/robots/stretch3/__init__.py diff --git a/lerobot/common/robots/stretch3/configuration_stretch3.py b/src/lerobot/robots/stretch3/configuration_stretch3.py similarity index 91% rename from lerobot/common/robots/stretch3/configuration_stretch3.py rename to src/lerobot/robots/stretch3/configuration_stretch3.py index e62e4fa..9fcf8f7 100644 --- a/lerobot/common/robots/stretch3/configuration_stretch3.py +++ b/src/lerobot/robots/stretch3/configuration_stretch3.py @@ -14,9 +14,9 @@ from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig -from lerobot.common.cameras.opencv import OpenCVCameraConfig -from lerobot.common.cameras.realsense import RealSenseCameraConfig +from lerobot.cameras import CameraConfig +from lerobot.cameras.opencv import OpenCVCameraConfig +from lerobot.cameras.realsense import RealSenseCameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/stretch3/robot_stretch3.py b/src/lerobot/robots/stretch3/robot_stretch3.py similarity index 96% rename from lerobot/common/robots/stretch3/robot_stretch3.py rename to src/lerobot/robots/stretch3/robot_stretch3.py index 048db38..b907d6a 100644 --- a/lerobot/common/robots/stretch3/robot_stretch3.py +++ b/src/lerobot/robots/stretch3/robot_stretch3.py @@ -21,9 +21,9 @@ from stretch_body.gamepad_teleop import GamePadTeleop from stretch_body.robot import Robot as StretchAPI from stretch_body.robot_params import RobotParams -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.constants import OBS_IMAGES, OBS_STATE -from lerobot.common.datasets.utils import get_nested_item +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.constants import OBS_IMAGES, OBS_STATE +from lerobot.datasets.utils import get_nested_item from ..robot import Robot from .configuration_stretch3 import Stretch3RobotConfig diff --git a/lerobot/common/robots/utils.py b/src/lerobot/robots/utils.py similarity index 98% rename from lerobot/common/robots/utils.py rename to src/lerobot/robots/utils.py index ccc1c58..435303c 100644 --- a/lerobot/common/robots/utils.py +++ b/src/lerobot/robots/utils.py @@ -15,7 +15,7 @@ import logging from pprint import pformat -from lerobot.common.robots import RobotConfig +from lerobot.robots import RobotConfig from .robot import Robot diff --git a/lerobot/common/robots/viperx/README.md b/src/lerobot/robots/viperx/README.md similarity index 88% rename from lerobot/common/robots/viperx/README.md rename to src/lerobot/robots/viperx/README.md index be2a323..445368e 100644 --- a/lerobot/common/robots/viperx/README.md +++ b/src/lerobot/robots/viperx/README.md @@ -58,7 +58,7 @@ python lerobot/scripts/control_robot.py \ --control.type=teleoperate ``` -By adding `--robot.max_relative_target=5`, we override the default value for `max_relative_target` defined in [`AlohaRobotConfig`](lerobot/common/robot_devices/robots/configs.py). It is expected to be `5` to limit the magnitude of the movement for more safety, but the teleoperation won't be smooth. When you feel confident, you can disable this limit by adding `--robot.max_relative_target=null` to the command line: +By adding `--robot.max_relative_target=5`, we override the default value for `max_relative_target` defined in [`AlohaRobotConfig`](lerobot/robot_devices/robots/configs.py). It is expected to be `5` to limit the magnitude of the movement for more safety, but the teleoperation won't be smooth. When you feel confident, you can disable this limit by adding `--robot.max_relative_target=null` to the command line: ```bash python lerobot/scripts/control_robot.py \ --robot.type=aloha \ @@ -107,7 +107,7 @@ echo ${HF_USER}/aloha_test If you didn't upload with `--control.push_to_hub=false`, you can also visualize it locally with: ```bash -python lerobot/scripts/visualize_dataset_html.py \ +python -m lerobot.scripts.visualize_dataset_html \ --repo-id ${HF_USER}/aloha_test ``` @@ -129,9 +129,9 @@ python lerobot/scripts/control_robot.py \ ## 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 -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --dataset.repo_id=${HF_USER}/aloha_test \ --policy.type=act \ --output_dir=outputs/train/act_aloha_test \ @@ -142,7 +142,7 @@ python lerobot/scripts/train.py \ Let's explain it: 1. We provided the dataset as argument with `--dataset.repo_id=${HF_USER}/aloha_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. 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`. @@ -152,7 +152,7 @@ Training should take several hours. You will find checkpoints in `outputs/train/ ## Evaluate your policy -You can use the `record` function from [`lerobot/scripts/control_robot.py`](../lerobot/scripts/control_robot.py) but with a policy checkpoint as input. For instance, run this command to record 10 evaluation episodes: +You can use the `record` function from [`lerobot/scripts/control_robot.py`](../src/lerobot/scripts/control_robot.py) but with a policy checkpoint as input. For instance, run this command to record 10 evaluation episodes: ```bash python lerobot/scripts/control_robot.py \ --robot.type=aloha \ diff --git a/lerobot/common/robots/viperx/__init__.py b/src/lerobot/robots/viperx/__init__.py similarity index 100% rename from lerobot/common/robots/viperx/__init__.py rename to src/lerobot/robots/viperx/__init__.py diff --git a/lerobot/common/robots/viperx/config_viperx.py b/src/lerobot/robots/viperx/config_viperx.py similarity index 97% rename from lerobot/common/robots/viperx/config_viperx.py rename to src/lerobot/robots/viperx/config_viperx.py index 6c7e2cc..4922f1d 100644 --- a/lerobot/common/robots/viperx/config_viperx.py +++ b/src/lerobot/robots/viperx/config_viperx.py @@ -14,7 +14,7 @@ from dataclasses import dataclass, field -from lerobot.common.cameras import CameraConfig +from lerobot.cameras import CameraConfig from ..config import RobotConfig diff --git a/lerobot/common/robots/viperx/viperx.py b/src/lerobot/robots/viperx/viperx.py similarity index 96% rename from lerobot/common/robots/viperx/viperx.py rename to src/lerobot/robots/viperx/viperx.py index 8ed8ef7..881640c 100644 --- a/lerobot/common/robots/viperx/viperx.py +++ b/src/lerobot/robots/viperx/viperx.py @@ -17,11 +17,11 @@ import time from functools import cached_property from typing import Any -from lerobot.common.cameras.utils import make_cameras_from_configs -from lerobot.common.constants import OBS_STATE -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.dynamixel import ( +from lerobot.cameras.utils import make_cameras_from_configs +from lerobot.constants import OBS_STATE +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.dynamixel import ( DynamixelMotorsBus, OperatingMode, ) diff --git a/lerobot/scripts/display_sys_info.py b/src/lerobot/scripts/display_sys_info.py similarity index 100% rename from lerobot/scripts/display_sys_info.py rename to src/lerobot/scripts/display_sys_info.py diff --git a/lerobot/scripts/eval.py b/src/lerobot/scripts/eval.py similarity index 97% rename from lerobot/scripts/eval.py rename to src/lerobot/scripts/eval.py index 58275f6..d85ac27 100644 --- a/lerobot/scripts/eval.py +++ b/src/lerobot/scripts/eval.py @@ -21,7 +21,7 @@ You want to evaluate a model from the hub (eg: https://huggingface.co/lerobot/di for 10 episodes. ``` -python lerobot/scripts/eval.py \ +python -m lerobot.scripts.eval \ --policy.path=lerobot/diffusion_pusht \ --env.type=pusht \ --eval.batch_size=10 \ @@ -32,7 +32,7 @@ python lerobot/scripts/eval.py \ OR, you want to evaluate a model checkpoint from the LeRobot training script for 10 episodes. ``` -python lerobot/scripts/eval.py \ +python -m lerobot.scripts.eval \ --policy.path=outputs/train/diffusion_pusht/checkpoints/005000/pretrained_model \ --env.type=pusht \ --eval.batch_size=10 \ @@ -65,20 +65,20 @@ from termcolor import colored from torch import Tensor, nn from tqdm import trange -from lerobot.common.envs.factory import make_env -from lerobot.common.envs.utils import add_envs_task, check_env_attributes_and_types, preprocess_observation -from lerobot.common.policies.factory import make_policy -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.utils import get_device_from_parameters -from lerobot.common.utils.io_utils import write_video -from lerobot.common.utils.random_utils import set_seed -from lerobot.common.utils.utils import ( +from lerobot.configs import parser +from lerobot.configs.eval import EvalPipelineConfig +from lerobot.envs.factory import make_env +from lerobot.envs.utils import add_envs_task, check_env_attributes_and_types, preprocess_observation +from lerobot.policies.factory import make_policy +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.utils import get_device_from_parameters +from lerobot.utils.io_utils import write_video +from lerobot.utils.random_utils import set_seed +from lerobot.utils.utils import ( get_safe_torch_device, init_logging, inside_slurm, ) -from lerobot.configs import parser -from lerobot.configs.eval import EvalPipelineConfig def rollout( diff --git a/lerobot/scripts/find_joint_limits.py b/src/lerobot/scripts/find_joint_limits.py similarity index 95% rename from lerobot/scripts/find_joint_limits.py rename to src/lerobot/scripts/find_joint_limits.py index 95676dd..346edf8 100644 --- a/lerobot/scripts/find_joint_limits.py +++ b/src/lerobot/scripts/find_joint_limits.py @@ -36,14 +36,14 @@ from dataclasses import dataclass import draccus import numpy as np -from lerobot.common.model.kinematics import RobotKinematics -from lerobot.common.robots import ( # noqa: F401 +from lerobot.model.kinematics import RobotKinematics +from lerobot.robots import ( # noqa: F401 RobotConfig, koch_follower, make_robot_from_config, so100_follower, ) -from lerobot.common.teleoperators import ( # noqa: F401 +from lerobot.teleoperators import ( # noqa: F401 TeleoperatorConfig, gamepad, koch_leader, diff --git a/lerobot/scripts/rl/actor.py b/src/lerobot/scripts/rl/actor.py similarity index 96% rename from lerobot/scripts/rl/actor.py rename to src/lerobot/scripts/rl/actor.py index da24d0d..0e96d33 100644 --- a/lerobot/scripts/rl/actor.py +++ b/src/lerobot/scripts/rl/actor.py @@ -24,7 +24,7 @@ Examples of usage: - Start an actor server for real robot training with human-in-the-loop intervention: ```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 ``` **NOTE**: The actor server requires a running learner server to connect to. Ensure the learner @@ -57,37 +57,37 @@ import torch from torch import nn from torch.multiprocessing import Event, Queue -from lerobot.common.cameras import opencv # noqa: F401 -from lerobot.common.policies.factory import make_policy -from lerobot.common.policies.sac.modeling_sac import SACPolicy -from lerobot.common.robots import so100_follower # noqa: F401 -from lerobot.common.teleoperators import gamepad, so101_leader # noqa: F401 -from lerobot.common.transport import services_pb2, services_pb2_grpc -from lerobot.common.transport.utils import ( +from lerobot.cameras import opencv # noqa: F401 +from lerobot.configs import parser +from lerobot.configs.train import TrainRLServerPipelineConfig +from lerobot.policies.factory import make_policy +from lerobot.policies.sac.modeling_sac import SACPolicy +from lerobot.robots import so100_follower # noqa: F401 +from lerobot.scripts.rl import learner_service +from lerobot.scripts.rl.gym_manipulator import make_robot_env +from lerobot.teleoperators import gamepad, so101_leader # noqa: F401 +from lerobot.transport import services_pb2, services_pb2_grpc +from lerobot.transport.utils import ( bytes_to_state_dict, python_object_to_bytes, receive_bytes_in_chunks, send_bytes_in_chunks, transitions_to_bytes, ) -from lerobot.common.utils.process import ProcessSignalHandler -from lerobot.common.utils.queue import get_last_item_from_queue -from lerobot.common.utils.random_utils import set_seed -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.transition import ( +from lerobot.utils.process import ProcessSignalHandler +from lerobot.utils.queue import get_last_item_from_queue +from lerobot.utils.random_utils import set_seed +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.transition import ( Transition, move_state_dict_to_device, move_transition_to_device, ) -from lerobot.common.utils.utils import ( +from lerobot.utils.utils import ( TimerManager, get_safe_torch_device, init_logging, ) -from lerobot.configs import parser -from lerobot.configs.train import TrainRLServerPipelineConfig -from lerobot.scripts.rl import learner_service -from lerobot.scripts.rl.gym_manipulator import make_robot_env ACTOR_SHUTDOWN_TIMEOUT = 30 diff --git a/lerobot/scripts/rl/crop_dataset_roi.py b/src/lerobot/scripts/rl/crop_dataset_roi.py similarity index 99% rename from lerobot/scripts/rl/crop_dataset_roi.py rename to src/lerobot/scripts/rl/crop_dataset_roi.py index 5b7038d..4cb7a3e 100644 --- a/lerobot/scripts/rl/crop_dataset_roi.py +++ b/src/lerobot/scripts/rl/crop_dataset_roi.py @@ -26,7 +26,7 @@ import cv2 import torchvision.transforms.functional as F # type: ignore # noqa: N812 from tqdm import tqdm # type: ignore -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.lerobot_dataset import LeRobotDataset def select_rect_roi(img): diff --git a/lerobot/scripts/rl/eval_policy.py b/src/lerobot/scripts/rl/eval_policy.py similarity index 88% rename from lerobot/scripts/rl/eval_policy.py rename to src/lerobot/scripts/rl/eval_policy.py index 3762719..aa97483 100644 --- a/lerobot/scripts/rl/eval_policy.py +++ b/src/lerobot/scripts/rl/eval_policy.py @@ -15,21 +15,21 @@ # limitations under the License. import logging -from lerobot.common.cameras import opencv # noqa: F401 -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.policies.factory import make_policy -from lerobot.common.robots import ( # noqa: F401 +from lerobot.cameras import opencv # noqa: F401 +from lerobot.configs import parser +from lerobot.configs.train import TrainRLServerPipelineConfig +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.policies.factory import make_policy +from lerobot.robots import ( # noqa: F401 RobotConfig, make_robot_from_config, so100_follower, ) -from lerobot.common.teleoperators import ( +from lerobot.scripts.rl.gym_manipulator import make_robot_env +from lerobot.teleoperators import ( gamepad, # noqa: F401 so101_leader, # noqa: F401 ) -from lerobot.configs import parser -from lerobot.configs.train import TrainRLServerPipelineConfig -from lerobot.scripts.rl.gym_manipulator import make_robot_env logging.basicConfig(level=logging.INFO) diff --git a/lerobot/scripts/rl/gym_manipulator.py b/src/lerobot/scripts/rl/gym_manipulator.py similarity index 98% rename from lerobot/scripts/rl/gym_manipulator.py rename to src/lerobot/scripts/rl/gym_manipulator.py index e7327d9..76a1360 100644 --- a/lerobot/scripts/rl/gym_manipulator.py +++ b/src/lerobot/scripts/rl/gym_manipulator.py @@ -47,26 +47,26 @@ import numpy as np import torch import torchvision.transforms.functional as F # noqa: N812 -from lerobot.common.cameras import opencv # noqa: F401 -from lerobot.common.envs.configs import EnvConfig -from lerobot.common.envs.utils import preprocess_observation -from lerobot.common.model.kinematics import RobotKinematics -from lerobot.common.robots import ( # noqa: F401 +from lerobot.cameras import opencv # noqa: F401 +from lerobot.configs import parser +from lerobot.envs.configs import EnvConfig +from lerobot.envs.utils import preprocess_observation +from lerobot.model.kinematics import RobotKinematics +from lerobot.robots import ( # noqa: F401 RobotConfig, make_robot_from_config, so100_follower, ) -from lerobot.common.teleoperators import ( +from lerobot.teleoperators import ( gamepad, # noqa: F401 keyboard, # noqa: F401 make_teleoperator_from_config, so101_leader, # noqa: F401 ) -from lerobot.common.teleoperators.gamepad.teleop_gamepad import GamepadTeleop -from lerobot.common.teleoperators.keyboard.teleop_keyboard import KeyboardEndEffectorTeleop -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import log_say -from lerobot.configs import parser +from lerobot.teleoperators.gamepad.teleop_gamepad import GamepadTeleop +from lerobot.teleoperators.keyboard.teleop_keyboard import KeyboardEndEffectorTeleop +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import log_say logging.basicConfig(level=logging.INFO) @@ -1980,7 +1980,7 @@ def init_reward_classifier(cfg): if cfg.reward_classifier_pretrained_path is None: return None - from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier + from lerobot.policies.sac.reward_model.modeling_classifier import Classifier # Get device from config or default to CUDA device = getattr(cfg, "device", "cpu") @@ -2023,7 +2023,7 @@ def record_dataset(env, policy, cfg): a success (reward=1) is detected. This helps collect more positive examples for reward classifier training. """ - from lerobot.common.datasets.lerobot_dataset import LeRobotDataset + from lerobot.datasets.lerobot_dataset import LeRobotDataset # Setup initial action (zero action if using teleop) action = env.action_space.sample() * 0.0 @@ -2177,7 +2177,7 @@ def replay_episode(env, cfg): - dataset_root: Local root directory for dataset - episode: Episode ID to replay """ - from lerobot.common.datasets.lerobot_dataset import LeRobotDataset + from lerobot.datasets.lerobot_dataset import LeRobotDataset dataset = LeRobotDataset(cfg.repo_id, root=cfg.dataset_root, episodes=[cfg.episode]) env.reset() @@ -2210,7 +2210,7 @@ def main(cfg: EnvConfig): if cfg.mode == "record": policy = None if cfg.pretrained_policy_name_or_path is not None: - from lerobot.common.policies.sac.modeling_sac import SACPolicy + from lerobot.policies.sac.modeling_sac import SACPolicy policy = SACPolicy.from_pretrained(cfg.pretrained_policy_name_or_path) policy.to(cfg.device) diff --git a/lerobot/scripts/rl/learner.py b/src/lerobot/scripts/rl/learner.py similarity index 97% rename from lerobot/scripts/rl/learner.py rename to src/lerobot/scripts/rl/learner.py index 663dbe9..d8830d8 100644 --- a/lerobot/scripts/rl/learner.py +++ b/src/lerobot/scripts/rl/learner.py @@ -25,7 +25,7 @@ Examples of usage: - Start a learner server for training: ```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 ``` **NOTE**: Start the learner server before launching the actor server. The learner opens a gRPC server @@ -59,46 +59,46 @@ from torch import nn from torch.multiprocessing import Queue from torch.optim.optimizer import Optimizer -from lerobot.common.cameras import opencv # noqa: F401 -from lerobot.common.constants import ( +from lerobot.cameras import opencv # noqa: F401 +from lerobot.configs import parser +from lerobot.configs.train import TrainRLServerPipelineConfig +from lerobot.constants import ( CHECKPOINTS_DIR, LAST_CHECKPOINT_LINK, PRETRAINED_MODEL_DIR, TRAINING_STATE_DIR, ) -from lerobot.common.datasets.factory import make_dataset -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.policies.factory import make_policy -from lerobot.common.policies.sac.modeling_sac import SACPolicy -from lerobot.common.robots import so100_follower # noqa: F401 -from lerobot.common.teleoperators import gamepad, so101_leader # noqa: F401 -from lerobot.common.transport import services_pb2_grpc -from lerobot.common.transport.utils import ( +from lerobot.datasets.factory import make_dataset +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.policies.factory import make_policy +from lerobot.policies.sac.modeling_sac import SACPolicy +from lerobot.robots import so100_follower # noqa: F401 +from lerobot.scripts.rl import learner_service +from lerobot.teleoperators import gamepad, so101_leader # noqa: F401 +from lerobot.transport import services_pb2_grpc +from lerobot.transport.utils import ( bytes_to_python_object, bytes_to_transitions, state_to_bytes, ) -from lerobot.common.utils.buffer import ReplayBuffer, concatenate_batch_transitions -from lerobot.common.utils.process import ProcessSignalHandler -from lerobot.common.utils.random_utils import set_seed -from lerobot.common.utils.train_utils import ( +from lerobot.utils.buffer import ReplayBuffer, concatenate_batch_transitions +from lerobot.utils.process import ProcessSignalHandler +from lerobot.utils.random_utils import set_seed +from lerobot.utils.train_utils import ( get_step_checkpoint_dir, save_checkpoint, update_last_checkpoint, ) -from lerobot.common.utils.train_utils import ( +from lerobot.utils.train_utils import ( load_training_state as utils_load_training_state, ) -from lerobot.common.utils.transition import move_state_dict_to_device, move_transition_to_device -from lerobot.common.utils.utils import ( +from lerobot.utils.transition import move_state_dict_to_device, move_transition_to_device +from lerobot.utils.utils import ( format_big_number, get_safe_torch_device, init_logging, ) -from lerobot.common.utils.wandb_utils import WandBLogger -from lerobot.configs import parser -from lerobot.configs.train import TrainRLServerPipelineConfig -from lerobot.scripts.rl import learner_service +from lerobot.utils.wandb_utils import WandBLogger LOG_PREFIX = "[LEARNER]" @@ -157,7 +157,7 @@ def train(cfg: TrainRLServerPipelineConfig, job_name: str | None = None): # Setup WandB logging if enabled if cfg.wandb.enable and cfg.wandb.project: - from lerobot.common.utils.wandb_utils import WandBLogger + from lerobot.utils.wandb_utils import WandBLogger wandb_logger = WandBLogger(cfg) else: diff --git a/lerobot/scripts/rl/learner_service.py b/src/lerobot/scripts/rl/learner_service.py similarity index 94% rename from lerobot/scripts/rl/learner_service.py rename to src/lerobot/scripts/rl/learner_service.py index f967d81..198e529 100644 --- a/lerobot/scripts/rl/learner_service.py +++ b/src/lerobot/scripts/rl/learner_service.py @@ -19,9 +19,9 @@ import logging import time from multiprocessing import Event, Queue -from lerobot.common.transport import services_pb2, services_pb2_grpc -from lerobot.common.transport.utils import receive_bytes_in_chunks, send_bytes_in_chunks -from lerobot.common.utils.queue import get_last_item_from_queue +from lerobot.transport import services_pb2, services_pb2_grpc +from lerobot.transport.utils import receive_bytes_in_chunks, send_bytes_in_chunks +from lerobot.utils.queue import get_last_item_from_queue MAX_MESSAGE_SIZE = 4 * 1024 * 1024 # 4 MB MAX_WORKERS = 3 # Stream parameters, send transitions and interactions diff --git a/lerobot/scripts/train.py b/src/lerobot/scripts/train.py similarity index 93% rename from lerobot/scripts/train.py rename to src/lerobot/scripts/train.py index bdb17da..2f2e88d 100644 --- a/lerobot/scripts/train.py +++ b/src/lerobot/scripts/train.py @@ -24,33 +24,33 @@ from termcolor import colored from torch.amp import GradScaler from torch.optim import Optimizer -from lerobot.common.datasets.factory import make_dataset -from lerobot.common.datasets.sampler import EpisodeAwareSampler -from lerobot.common.datasets.utils import cycle -from lerobot.common.envs.factory import make_env -from lerobot.common.optim.factory import make_optimizer_and_scheduler -from lerobot.common.policies.factory import make_policy -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.policies.utils import get_device_from_parameters -from lerobot.common.utils.logging_utils import AverageMeter, MetricsTracker -from lerobot.common.utils.random_utils import set_seed -from lerobot.common.utils.train_utils import ( +from lerobot.configs import parser +from lerobot.configs.train import TrainPipelineConfig +from lerobot.datasets.factory import make_dataset +from lerobot.datasets.sampler import EpisodeAwareSampler +from lerobot.datasets.utils import cycle +from lerobot.envs.factory import make_env +from lerobot.optim.factory import make_optimizer_and_scheduler +from lerobot.policies.factory import make_policy +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.policies.utils import get_device_from_parameters +from lerobot.scripts.eval import eval_policy +from lerobot.utils.logging_utils import AverageMeter, MetricsTracker +from lerobot.utils.random_utils import set_seed +from lerobot.utils.train_utils import ( get_step_checkpoint_dir, get_step_identifier, load_training_state, save_checkpoint, update_last_checkpoint, ) -from lerobot.common.utils.utils import ( +from lerobot.utils.utils import ( format_big_number, get_safe_torch_device, has_method, init_logging, ) -from lerobot.common.utils.wandb_utils import WandBLogger -from lerobot.configs import parser -from lerobot.configs.train import TrainPipelineConfig -from lerobot.scripts.eval import eval_policy +from lerobot.utils.wandb_utils import WandBLogger def update_policy( diff --git a/lerobot/scripts/visualize_dataset.py b/src/lerobot/scripts/visualize_dataset.py similarity index 97% rename from lerobot/scripts/visualize_dataset.py rename to src/lerobot/scripts/visualize_dataset.py index cdfea6b..37db66d 100644 --- a/lerobot/scripts/visualize_dataset.py +++ b/src/lerobot/scripts/visualize_dataset.py @@ -29,14 +29,14 @@ Examples: - Visualize data stored on a local machine: ``` -local$ python lerobot/scripts/visualize_dataset.py \ +local$ python -m lerobot.scripts.visualize_dataset \ --repo-id lerobot/pusht \ --episode-index 0 ``` - Visualize data stored on a distant machine with a local viewer: ``` -distant$ python lerobot/scripts/visualize_dataset.py \ +distant$ python -m lerobot.scripts.visualize_dataset \ --repo-id lerobot/pusht \ --episode-index 0 \ --save 1 \ @@ -50,7 +50,7 @@ local$ rerun lerobot_pusht_episode_0.rrd (You need to forward the websocket port to the distant machine, with `ssh -L 9087:localhost:9087 username@remote-host`) ``` -distant$ python lerobot/scripts/visualize_dataset.py \ +distant$ python -m lerobot.scripts.visualize_dataset \ --repo-id lerobot/pusht \ --episode-index 0 \ --mode distant \ @@ -74,7 +74,7 @@ import torch import torch.utils.data import tqdm -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.lerobot_dataset import LeRobotDataset class EpisodeSampler(torch.utils.data.Sampler): diff --git a/lerobot/scripts/visualize_dataset_html.py b/src/lerobot/scripts/visualize_dataset_html.py similarity index 97% rename from lerobot/scripts/visualize_dataset_html.py rename to src/lerobot/scripts/visualize_dataset_html.py index d0c8f1a..a722da6 100644 --- a/lerobot/scripts/visualize_dataset_html.py +++ b/src/lerobot/scripts/visualize_dataset_html.py @@ -29,7 +29,7 @@ Example of usage: - Visualize data stored on a local machine: ```bash -local$ python lerobot/scripts/visualize_dataset_html.py \ +local$ python -m lerobot.scripts.visualize_dataset_html \ --repo-id lerobot/pusht local$ open http://localhost:9090 @@ -37,7 +37,7 @@ local$ open http://localhost:9090 - Visualize data stored on a distant machine with a local viewer: ```bash -distant$ python lerobot/scripts/visualize_dataset_html.py \ +distant$ python -m lerobot.scripts.visualize_dataset_html \ --repo-id lerobot/pusht local$ ssh -L 9090:localhost:9090 distant # create a ssh tunnel @@ -46,7 +46,7 @@ local$ open http://localhost:9090 - Select episodes to visualize: ```bash -python lerobot/scripts/visualize_dataset_html.py \ +python -m lerobot.scripts.visualize_dataset_html \ --repo-id lerobot/pusht \ --episodes 7 3 5 1 4 ``` @@ -68,9 +68,9 @@ import requests from flask import Flask, redirect, render_template, request, url_for from lerobot import available_datasets -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import IterableNamespace -from lerobot.common.utils.utils import init_logging +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import IterableNamespace +from lerobot.utils.utils import init_logging def run_server( diff --git a/lerobot/scripts/visualize_image_transforms.py b/src/lerobot/scripts/visualize_image_transforms.py similarity index 96% rename from lerobot/scripts/visualize_image_transforms.py rename to src/lerobot/scripts/visualize_image_transforms.py index 80935d3..14caf89 100644 --- a/lerobot/scripts/visualize_image_transforms.py +++ b/src/lerobot/scripts/visualize_image_transforms.py @@ -20,7 +20,7 @@ Additionally, each individual transform can be visualized separately as well as Example: ```bash -python lerobot/scripts/visualize_image_transforms.py \ +python -m lerobot.scripts.visualize_image_transforms \ --repo_id=lerobot/pusht \ --episodes='[0]' \ --image_transforms.enable=True @@ -35,13 +35,13 @@ from pathlib import Path import draccus from torchvision.transforms import ToPILImage -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.transforms import ( +from lerobot.configs.default import DatasetConfig +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.transforms import ( ImageTransforms, ImageTransformsConfig, make_transform_from_config, ) -from lerobot.configs.default import DatasetConfig OUTPUT_DIR = Path("outputs/image_transforms") to_pil = ToPILImage() diff --git a/lerobot/setup_motors.py b/src/lerobot/setup_motors.py similarity index 95% rename from lerobot/setup_motors.py rename to src/lerobot/setup_motors.py index 7909dc6..c54582a 100644 --- a/lerobot/setup_motors.py +++ b/src/lerobot/setup_motors.py @@ -28,7 +28,7 @@ from dataclasses import dataclass import draccus -from .common.robots import ( # noqa: F401 +from lerobot.robots import ( # noqa: F401 RobotConfig, koch_follower, lekiwi, @@ -36,7 +36,7 @@ from .common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from .common.teleoperators import ( # noqa: F401 +from lerobot.teleoperators import ( # noqa: F401 TeleoperatorConfig, koch_leader, make_teleoperator_from_config, diff --git a/lerobot/teleoperate.py b/src/lerobot/teleoperate.py similarity index 86% rename from lerobot/teleoperate.py rename to src/lerobot/teleoperate.py index 6080dfb..20b4925 100644 --- a/lerobot/teleoperate.py +++ b/src/lerobot/teleoperate.py @@ -39,9 +39,9 @@ import draccus import numpy as np import rerun as rr -from lerobot.common.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 -from lerobot.common.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 -from lerobot.common.robots import ( # noqa: F401 +from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig # noqa: F401 +from lerobot.cameras.realsense.configuration_realsense import RealSenseCameraConfig # noqa: F401 +from lerobot.robots import ( # noqa: F401 Robot, RobotConfig, koch_follower, @@ -49,16 +49,18 @@ from lerobot.common.robots import ( # noqa: F401 so100_follower, so101_follower, ) -from lerobot.common.teleoperators import ( +from lerobot.teleoperators import ( # noqa: F401 Teleoperator, TeleoperatorConfig, + gamepad, + koch_leader, make_teleoperator_from_config, + so100_leader, + so101_leader, ) -from lerobot.common.utils.robot_utils import busy_wait -from lerobot.common.utils.utils import init_logging, move_cursor_up -from lerobot.common.utils.visualization_utils import _init_rerun - -from .common.teleoperators import gamepad, koch_leader, so100_leader, so101_leader # noqa: F401 +from lerobot.utils.robot_utils import busy_wait +from lerobot.utils.utils import init_logging, move_cursor_up +from lerobot.utils.visualization_utils import _init_rerun @dataclass diff --git a/lerobot/common/teleoperators/__init__.py b/src/lerobot/teleoperators/__init__.py similarity index 100% rename from lerobot/common/teleoperators/__init__.py rename to src/lerobot/teleoperators/__init__.py diff --git a/lerobot/common/teleoperators/config.py b/src/lerobot/teleoperators/config.py similarity index 100% rename from lerobot/common/teleoperators/config.py rename to src/lerobot/teleoperators/config.py diff --git a/lerobot/common/teleoperators/gamepad/__init__.py b/src/lerobot/teleoperators/gamepad/__init__.py similarity index 100% rename from lerobot/common/teleoperators/gamepad/__init__.py rename to src/lerobot/teleoperators/gamepad/__init__.py diff --git a/lerobot/common/teleoperators/gamepad/configuration_gamepad.py b/src/lerobot/teleoperators/gamepad/configuration_gamepad.py similarity index 100% rename from lerobot/common/teleoperators/gamepad/configuration_gamepad.py rename to src/lerobot/teleoperators/gamepad/configuration_gamepad.py diff --git a/lerobot/common/teleoperators/gamepad/gamepad_utils.py b/src/lerobot/teleoperators/gamepad/gamepad_utils.py similarity index 100% rename from lerobot/common/teleoperators/gamepad/gamepad_utils.py rename to src/lerobot/teleoperators/gamepad/gamepad_utils.py diff --git a/lerobot/common/teleoperators/gamepad/teleop_gamepad.py b/src/lerobot/teleoperators/gamepad/teleop_gamepad.py similarity index 100% rename from lerobot/common/teleoperators/gamepad/teleop_gamepad.py rename to src/lerobot/teleoperators/gamepad/teleop_gamepad.py diff --git a/lerobot/common/teleoperators/keyboard/__init__.py b/src/lerobot/teleoperators/keyboard/__init__.py similarity index 100% rename from lerobot/common/teleoperators/keyboard/__init__.py rename to src/lerobot/teleoperators/keyboard/__init__.py diff --git a/lerobot/common/teleoperators/keyboard/configuration_keyboard.py b/src/lerobot/teleoperators/keyboard/configuration_keyboard.py similarity index 100% rename from lerobot/common/teleoperators/keyboard/configuration_keyboard.py rename to src/lerobot/teleoperators/keyboard/configuration_keyboard.py diff --git a/lerobot/common/teleoperators/keyboard/teleop_keyboard.py b/src/lerobot/teleoperators/keyboard/teleop_keyboard.py similarity index 98% rename from lerobot/common/teleoperators/keyboard/teleop_keyboard.py rename to src/lerobot/teleoperators/keyboard/teleop_keyboard.py index bd3ab90..41a4293 100644 --- a/lerobot/common/teleoperators/keyboard/teleop_keyboard.py +++ b/src/lerobot/teleoperators/keyboard/teleop_keyboard.py @@ -21,7 +21,7 @@ import time from queue import Queue from typing import Any -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from ..teleoperator import Teleoperator from .configuration_keyboard import KeyboardEndEffectorTeleopConfig, KeyboardTeleopConfig diff --git a/lerobot/common/teleoperators/koch_leader/__init__.py b/src/lerobot/teleoperators/koch_leader/__init__.py similarity index 100% rename from lerobot/common/teleoperators/koch_leader/__init__.py rename to src/lerobot/teleoperators/koch_leader/__init__.py diff --git a/lerobot/common/teleoperators/koch_leader/config_koch_leader.py b/src/lerobot/teleoperators/koch_leader/config_koch_leader.py similarity index 100% rename from lerobot/common/teleoperators/koch_leader/config_koch_leader.py rename to src/lerobot/teleoperators/koch_leader/config_koch_leader.py diff --git a/lerobot/common/teleoperators/koch_leader/koch_leader.py b/src/lerobot/teleoperators/koch_leader/koch_leader.py similarity index 97% rename from lerobot/common/teleoperators/koch_leader/koch_leader.py rename to src/lerobot/teleoperators/koch_leader/koch_leader.py index 820acc8..8eb076f 100644 --- a/lerobot/common/teleoperators/koch_leader/koch_leader.py +++ b/src/lerobot/teleoperators/koch_leader/koch_leader.py @@ -17,9 +17,9 @@ import logging import time -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.dynamixel import ( +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.dynamixel import ( DriveMode, DynamixelMotorsBus, OperatingMode, diff --git a/lerobot/common/teleoperators/so100_leader/__init__.py b/src/lerobot/teleoperators/so100_leader/__init__.py similarity index 100% rename from lerobot/common/teleoperators/so100_leader/__init__.py rename to src/lerobot/teleoperators/so100_leader/__init__.py diff --git a/lerobot/common/teleoperators/so100_leader/config_so100_leader.py b/src/lerobot/teleoperators/so100_leader/config_so100_leader.py similarity index 100% rename from lerobot/common/teleoperators/so100_leader/config_so100_leader.py rename to src/lerobot/teleoperators/so100_leader/config_so100_leader.py diff --git a/lerobot/common/teleoperators/so100_leader/so100_leader.py b/src/lerobot/teleoperators/so100_leader/so100_leader.py similarity index 96% rename from lerobot/common/teleoperators/so100_leader/so100_leader.py rename to src/lerobot/teleoperators/so100_leader/so100_leader.py index 59b083e..18dad44 100644 --- a/lerobot/common/teleoperators/so100_leader/so100_leader.py +++ b/src/lerobot/teleoperators/so100_leader/so100_leader.py @@ -17,9 +17,9 @@ import logging import time -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import ( +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import ( FeetechMotorsBus, OperatingMode, ) diff --git a/lerobot/common/teleoperators/so101_leader/__init__.py b/src/lerobot/teleoperators/so101_leader/__init__.py similarity index 100% rename from lerobot/common/teleoperators/so101_leader/__init__.py rename to src/lerobot/teleoperators/so101_leader/__init__.py diff --git a/lerobot/common/teleoperators/so101_leader/config_so101_leader.py b/src/lerobot/teleoperators/so101_leader/config_so101_leader.py similarity index 100% rename from lerobot/common/teleoperators/so101_leader/config_so101_leader.py rename to src/lerobot/teleoperators/so101_leader/config_so101_leader.py diff --git a/lerobot/common/teleoperators/so101_leader/so101_leader.py b/src/lerobot/teleoperators/so101_leader/so101_leader.py similarity index 96% rename from lerobot/common/teleoperators/so101_leader/so101_leader.py rename to src/lerobot/teleoperators/so101_leader/so101_leader.py index 80ddfbb..2ce28d2 100644 --- a/lerobot/common/teleoperators/so101_leader/so101_leader.py +++ b/src/lerobot/teleoperators/so101_leader/so101_leader.py @@ -17,9 +17,9 @@ import logging import time -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import ( +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import ( FeetechMotorsBus, OperatingMode, ) diff --git a/lerobot/common/teleoperators/stretch3_gamepad/__init__.py b/src/lerobot/teleoperators/stretch3_gamepad/__init__.py similarity index 100% rename from lerobot/common/teleoperators/stretch3_gamepad/__init__.py rename to src/lerobot/teleoperators/stretch3_gamepad/__init__.py diff --git a/lerobot/common/teleoperators/stretch3_gamepad/configuration_stretch3.py b/src/lerobot/teleoperators/stretch3_gamepad/configuration_stretch3.py similarity index 100% rename from lerobot/common/teleoperators/stretch3_gamepad/configuration_stretch3.py rename to src/lerobot/teleoperators/stretch3_gamepad/configuration_stretch3.py diff --git a/lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py b/src/lerobot/teleoperators/stretch3_gamepad/stretch3_gamepad.py similarity index 98% rename from lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py rename to src/lerobot/teleoperators/stretch3_gamepad/stretch3_gamepad.py index 1e9768c..bdcb57d 100644 --- a/lerobot/common/teleoperators/stretch3_gamepad/stretch3_gamepad.py +++ b/src/lerobot/teleoperators/stretch3_gamepad/stretch3_gamepad.py @@ -20,7 +20,7 @@ import numpy as np from stretch_body.gamepad_teleop import GamePadTeleop from stretch_body.robot_params import RobotParams -from lerobot.common.errors import DeviceAlreadyConnectedError +from lerobot.errors import DeviceAlreadyConnectedError from ..teleoperator import Teleoperator from .configuration_stretch3 import Stretch3GamePadConfig diff --git a/lerobot/common/teleoperators/teleoperator.py b/src/lerobot/teleoperators/teleoperator.py similarity index 97% rename from lerobot/common/teleoperators/teleoperator.py rename to src/lerobot/teleoperators/teleoperator.py index 6a20a3a..49f259c 100644 --- a/lerobot/common/teleoperators/teleoperator.py +++ b/src/lerobot/teleoperators/teleoperator.py @@ -18,8 +18,8 @@ from typing import Any, Type import draccus -from lerobot.common.constants import HF_LEROBOT_CALIBRATION, TELEOPERATORS -from lerobot.common.motors.motors_bus import MotorCalibration +from lerobot.constants import HF_LEROBOT_CALIBRATION, TELEOPERATORS +from lerobot.motors.motors_bus import MotorCalibration from .config import TeleoperatorConfig diff --git a/lerobot/common/teleoperators/utils.py b/src/lerobot/teleoperators/utils.py similarity index 100% rename from lerobot/common/teleoperators/utils.py rename to src/lerobot/teleoperators/utils.py diff --git a/lerobot/common/teleoperators/widowx/__init__.py b/src/lerobot/teleoperators/widowx/__init__.py similarity index 100% rename from lerobot/common/teleoperators/widowx/__init__.py rename to src/lerobot/teleoperators/widowx/__init__.py diff --git a/lerobot/common/teleoperators/widowx/config_widowx.py b/src/lerobot/teleoperators/widowx/config_widowx.py similarity index 100% rename from lerobot/common/teleoperators/widowx/config_widowx.py rename to src/lerobot/teleoperators/widowx/config_widowx.py diff --git a/lerobot/common/teleoperators/widowx/widowx.py b/src/lerobot/teleoperators/widowx/widowx.py similarity index 96% rename from lerobot/common/teleoperators/widowx/widowx.py rename to src/lerobot/teleoperators/widowx/widowx.py index 8a42c90..6becd76 100644 --- a/lerobot/common/teleoperators/widowx/widowx.py +++ b/src/lerobot/teleoperators/widowx/widowx.py @@ -17,9 +17,9 @@ import logging import time -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.dynamixel import ( +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.dynamixel import ( DriveMode, DynamixelMotorsBus, OperatingMode, diff --git a/lerobot/templates/lerobot_modelcard_template.md b/src/lerobot/templates/lerobot_modelcard_template.md similarity index 99% rename from lerobot/templates/lerobot_modelcard_template.md rename to src/lerobot/templates/lerobot_modelcard_template.md index ca5c182..64ad719 100644 --- a/lerobot/templates/lerobot_modelcard_template.md +++ b/src/lerobot/templates/lerobot_modelcard_template.md @@ -43,7 +43,7 @@ Below is the short version on how to train and run inference/eval: ### Train from scratch ```bash -python lerobot/scripts/train.py \ +python -m lerobot.scripts.train \ --dataset.repo_id=${HF_USER}/ \ --policy.type=act \ --output_dir=outputs/train/ \ diff --git a/lerobot/templates/visualize_dataset_homepage.html b/src/lerobot/templates/visualize_dataset_homepage.html similarity index 100% rename from lerobot/templates/visualize_dataset_homepage.html rename to src/lerobot/templates/visualize_dataset_homepage.html diff --git a/lerobot/templates/visualize_dataset_template.html b/src/lerobot/templates/visualize_dataset_template.html similarity index 100% rename from lerobot/templates/visualize_dataset_template.html rename to src/lerobot/templates/visualize_dataset_template.html diff --git a/lerobot/common/transport/services.proto b/src/lerobot/transport/services.proto similarity index 97% rename from lerobot/common/transport/services.proto rename to src/lerobot/transport/services.proto index 29d0000..89bfc10 100644 --- a/lerobot/common/transport/services.proto +++ b/src/lerobot/transport/services.proto @@ -15,7 +15,7 @@ // To generate a classes for transport part (services_pb2.py and services_pb2_grpc.py) use the following command: // -// python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. lerobot/common/transport/services.proto +// python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. src/lerobot/transport/services.proto // // The command should be launched from the root of the project. diff --git a/src/lerobot/transport/services_pb2.py b/src/lerobot/transport/services_pb2.py new file mode 100644 index 0000000..8a21376 --- /dev/null +++ b/src/lerobot/transport/services_pb2.py @@ -0,0 +1,45 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: src/lerobot/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, + '', + 'src/lerobot/transport/services.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$src/lerobot/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, 'src.lerobot.transport.services_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None + _globals['_TRANSFERSTATE']._serialized_start=302 + _globals['_TRANSFERSTATE']._serialized_end=398 + _globals['_TRANSITION']._serialized_start=51 + _globals['_TRANSITION']._serialized_end=127 + _globals['_PARAMETERS']._serialized_start=129 + _globals['_PARAMETERS']._serialized_end=205 + _globals['_INTERACTIONMESSAGE']._serialized_start=207 + _globals['_INTERACTIONMESSAGE']._serialized_end=291 + _globals['_EMPTY']._serialized_start=293 + _globals['_EMPTY']._serialized_end=300 + _globals['_LEARNERSERVICE']._serialized_start=401 + _globals['_LEARNERSERVICE']._serialized_end=658 +# @@protoc_insertion_point(module_scope) diff --git a/lerobot/common/transport/services_pb2_grpc.py b/src/lerobot/transport/services_pb2_grpc.py similarity index 72% rename from lerobot/common/transport/services_pb2_grpc.py rename to src/lerobot/transport/services_pb2_grpc.py index 5a7a924..a4fe8c5 100644 --- a/lerobot/common/transport/services_pb2_grpc.py +++ b/src/lerobot/transport/services_pb2_grpc.py @@ -3,7 +3,7 @@ import grpc import warnings -from lerobot.common.transport import services_pb2 as lerobot_dot_common_dot_transport_dot_services__pb2 +from src.lerobot.transport import services_pb2 as src_dot_lerobot_dot_transport_dot_services__pb2 GRPC_GENERATED_VERSION = '1.71.0' GRPC_VERSION = grpc.__version__ @@ -18,7 +18,7 @@ except ImportError: if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in lerobot/common/transport/services_pb2_grpc.py depends on' + + f' but the generated code in src/lerobot/transport/services_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' @@ -38,23 +38,23 @@ class LearnerServiceStub: """ self.StreamParameters = channel.unary_stream( '/transport.LearnerService/StreamParameters', - request_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, - response_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Parameters.FromString, + request_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, + response_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Parameters.FromString, _registered_method=True) self.SendTransitions = channel.stream_unary( '/transport.LearnerService/SendTransitions', - request_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Transition.SerializeToString, - response_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + request_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Transition.SerializeToString, + response_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, _registered_method=True) self.SendInteractions = channel.stream_unary( '/transport.LearnerService/SendInteractions', - request_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.InteractionMessage.SerializeToString, - response_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + request_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.InteractionMessage.SerializeToString, + response_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, _registered_method=True) self.Ready = channel.unary_unary( '/transport.LearnerService/Ready', - request_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, - response_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + request_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, + response_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, _registered_method=True) @@ -93,23 +93,23 @@ def add_LearnerServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'StreamParameters': grpc.unary_stream_rpc_method_handler( servicer.StreamParameters, - request_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, - response_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Parameters.SerializeToString, + request_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, + response_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Parameters.SerializeToString, ), 'SendTransitions': grpc.stream_unary_rpc_method_handler( servicer.SendTransitions, - request_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Transition.FromString, - response_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, + request_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Transition.FromString, + response_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, ), 'SendInteractions': grpc.stream_unary_rpc_method_handler( servicer.SendInteractions, - request_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.InteractionMessage.FromString, - response_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, + request_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.InteractionMessage.FromString, + response_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, ), 'Ready': grpc.unary_unary_rpc_method_handler( servicer.Ready, - request_deserializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, - response_serializer=lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, + request_deserializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, + response_serializer=src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( @@ -139,8 +139,8 @@ class LearnerService: request, target, '/transport.LearnerService/StreamParameters', - lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, - lerobot_dot_common_dot_transport_dot_services__pb2.Parameters.FromString, + src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, + src_dot_lerobot_dot_transport_dot_services__pb2.Parameters.FromString, options, channel_credentials, insecure, @@ -166,8 +166,8 @@ class LearnerService: request_iterator, target, '/transport.LearnerService/SendTransitions', - lerobot_dot_common_dot_transport_dot_services__pb2.Transition.SerializeToString, - lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + src_dot_lerobot_dot_transport_dot_services__pb2.Transition.SerializeToString, + src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, options, channel_credentials, insecure, @@ -193,8 +193,8 @@ class LearnerService: request_iterator, target, '/transport.LearnerService/SendInteractions', - lerobot_dot_common_dot_transport_dot_services__pb2.InteractionMessage.SerializeToString, - lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + src_dot_lerobot_dot_transport_dot_services__pb2.InteractionMessage.SerializeToString, + src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, options, channel_credentials, insecure, @@ -220,8 +220,8 @@ class LearnerService: request, target, '/transport.LearnerService/Ready', - lerobot_dot_common_dot_transport_dot_services__pb2.Empty.SerializeToString, - lerobot_dot_common_dot_transport_dot_services__pb2.Empty.FromString, + src_dot_lerobot_dot_transport_dot_services__pb2.Empty.SerializeToString, + src_dot_lerobot_dot_transport_dot_services__pb2.Empty.FromString, options, channel_credentials, insecure, diff --git a/lerobot/common/transport/utils.py b/src/lerobot/transport/utils.py similarity index 97% rename from lerobot/common/transport/utils.py rename to src/lerobot/transport/utils.py index 774721f..1c66832 100644 --- a/lerobot/common/transport/utils.py +++ b/src/lerobot/transport/utils.py @@ -23,8 +23,8 @@ from typing import Any import torch -from lerobot.common.transport import services_pb2 -from lerobot.common.utils.transition import Transition +from lerobot.transport import services_pb2 +from lerobot.utils.transition import Transition CHUNK_SIZE = 2 * 1024 * 1024 # 2 MB diff --git a/lerobot/common/utils/benchmark.py b/src/lerobot/utils/benchmark.py similarity index 100% rename from lerobot/common/utils/benchmark.py rename to src/lerobot/utils/benchmark.py diff --git a/lerobot/common/utils/buffer.py b/src/lerobot/utils/buffer.py similarity index 99% rename from lerobot/common/utils/buffer.py rename to src/lerobot/utils/buffer.py index 9ae231a..7f8d989 100644 --- a/lerobot/common/utils/buffer.py +++ b/src/lerobot/utils/buffer.py @@ -22,8 +22,8 @@ import torch import torch.nn.functional as F # noqa: N812 from tqdm import tqdm -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.utils.transition import Transition +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.utils.transition import Transition class BatchTransition(TypedDict): diff --git a/lerobot/common/utils/control_utils.py b/src/lerobot/utils/control_utils.py similarity index 97% rename from lerobot/common/utils/control_utils.py rename to src/lerobot/utils/control_utils.py index b66977a..4bcc241 100644 --- a/lerobot/common/utils/control_utils.py +++ b/src/lerobot/utils/control_utils.py @@ -28,10 +28,10 @@ import torch from deepdiff import DeepDiff from termcolor import colored -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.utils import DEFAULT_FEATURES -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.robots import Robot +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.utils import DEFAULT_FEATURES +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.robots import Robot def log_control_info(robot: Robot, dt_s, episode_index=None, frame_index=None, fps=None): diff --git a/lerobot/common/utils/encoding_utils.py b/src/lerobot/utils/encoding_utils.py similarity index 100% rename from lerobot/common/utils/encoding_utils.py rename to src/lerobot/utils/encoding_utils.py diff --git a/lerobot/common/utils/hub.py b/src/lerobot/utils/hub.py similarity index 100% rename from lerobot/common/utils/hub.py rename to src/lerobot/utils/hub.py diff --git a/lerobot/common/utils/import_utils.py b/src/lerobot/utils/import_utils.py similarity index 100% rename from lerobot/common/utils/import_utils.py rename to src/lerobot/utils/import_utils.py diff --git a/lerobot/common/utils/io_utils.py b/src/lerobot/utils/io_utils.py similarity index 100% rename from lerobot/common/utils/io_utils.py rename to src/lerobot/utils/io_utils.py diff --git a/lerobot/common/utils/logging_utils.py b/src/lerobot/utils/logging_utils.py similarity index 98% rename from lerobot/common/utils/logging_utils.py rename to src/lerobot/utils/logging_utils.py index 56c9abb..b6404e6 100644 --- a/lerobot/common/utils/logging_utils.py +++ b/src/lerobot/utils/logging_utils.py @@ -15,7 +15,7 @@ # limitations under the License. from typing import Any -from lerobot.common.utils.utils import format_big_number +from lerobot.utils.utils import format_big_number class AverageMeter: diff --git a/lerobot/common/utils/process.py b/src/lerobot/utils/process.py similarity index 100% rename from lerobot/common/utils/process.py rename to src/lerobot/utils/process.py diff --git a/lerobot/common/utils/queue.py b/src/lerobot/utils/queue.py similarity index 100% rename from lerobot/common/utils/queue.py rename to src/lerobot/utils/queue.py diff --git a/lerobot/common/utils/random_utils.py b/src/lerobot/utils/random_utils.py similarity index 98% rename from lerobot/common/utils/random_utils.py rename to src/lerobot/utils/random_utils.py index 3d9bf4d..31fed1d 100644 --- a/lerobot/common/utils/random_utils.py +++ b/src/lerobot/utils/random_utils.py @@ -22,8 +22,8 @@ import numpy as np import torch from safetensors.torch import load_file, save_file -from lerobot.common.constants import RNG_STATE -from lerobot.common.datasets.utils import flatten_dict, unflatten_dict +from lerobot.constants import RNG_STATE +from lerobot.datasets.utils import flatten_dict, unflatten_dict def serialize_python_rng_state() -> dict[str, torch.Tensor]: diff --git a/lerobot/common/utils/robot_utils.py b/src/lerobot/utils/robot_utils.py similarity index 100% rename from lerobot/common/utils/robot_utils.py rename to src/lerobot/utils/robot_utils.py diff --git a/lerobot/common/utils/train_utils.py b/src/lerobot/utils/train_utils.py similarity index 93% rename from lerobot/common/utils/train_utils.py rename to src/lerobot/utils/train_utils.py index a799831..2859fe0 100644 --- a/lerobot/common/utils/train_utils.py +++ b/src/lerobot/utils/train_utils.py @@ -20,19 +20,19 @@ from termcolor import colored from torch.optim import Optimizer from torch.optim.lr_scheduler import LRScheduler -from lerobot.common.constants import ( +from lerobot.configs.train import TrainPipelineConfig +from lerobot.constants import ( CHECKPOINTS_DIR, LAST_CHECKPOINT_LINK, PRETRAINED_MODEL_DIR, TRAINING_STATE_DIR, TRAINING_STEP, ) -from lerobot.common.datasets.utils import load_json, write_json -from lerobot.common.optim.optimizers import load_optimizer_state, save_optimizer_state -from lerobot.common.optim.schedulers import load_scheduler_state, save_scheduler_state -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.utils.random_utils import load_rng_state, save_rng_state -from lerobot.configs.train import TrainPipelineConfig +from lerobot.datasets.utils import load_json, write_json +from lerobot.optim.optimizers import load_optimizer_state, save_optimizer_state +from lerobot.optim.schedulers import load_scheduler_state, save_scheduler_state +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.utils.random_utils import load_rng_state, save_rng_state def log_output_dir(out_dir): diff --git a/lerobot/common/utils/transition.py b/src/lerobot/utils/transition.py similarity index 100% rename from lerobot/common/utils/transition.py rename to src/lerobot/utils/transition.py diff --git a/lerobot/common/utils/utils.py b/src/lerobot/utils/utils.py similarity index 100% rename from lerobot/common/utils/utils.py rename to src/lerobot/utils/utils.py diff --git a/lerobot/common/utils/visualization_utils.py b/src/lerobot/utils/visualization_utils.py similarity index 100% rename from lerobot/common/utils/visualization_utils.py rename to src/lerobot/utils/visualization_utils.py diff --git a/lerobot/common/utils/wandb_utils.py b/src/lerobot/utils/wandb_utils.py similarity index 99% rename from lerobot/common/utils/wandb_utils.py rename to src/lerobot/utils/wandb_utils.py index ac4d223..91b4ec9 100644 --- a/lerobot/common/utils/wandb_utils.py +++ b/src/lerobot/utils/wandb_utils.py @@ -22,8 +22,8 @@ from pathlib import Path from huggingface_hub.constants import SAFETENSORS_SINGLE_FILE from termcolor import colored -from lerobot.common.constants import PRETRAINED_MODEL_DIR from lerobot.configs.train import TrainPipelineConfig +from lerobot.constants import PRETRAINED_MODEL_DIR def cfg_to_group(cfg: TrainPipelineConfig, return_list: bool = False) -> list[str] | str: diff --git a/tests/artifacts/datasets/save_dataset_to_safetensors.py b/tests/artifacts/datasets/save_dataset_to_safetensors.py index 74d42a3..419961b 100644 --- a/tests/artifacts/datasets/save_dataset_to_safetensors.py +++ b/tests/artifacts/datasets/save_dataset_to_safetensors.py @@ -31,7 +31,7 @@ from pathlib import Path from safetensors.torch import save_file -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.lerobot_dataset import LeRobotDataset def save_dataset_to_safetensors(output_dir, repo_id="lerobot/pusht"): diff --git a/tests/artifacts/image_transforms/save_image_transforms_to_safetensors.py b/tests/artifacts/image_transforms/save_image_transforms_to_safetensors.py index be47d9a..ce15d16 100644 --- a/tests/artifacts/image_transforms/save_image_transforms_to_safetensors.py +++ b/tests/artifacts/image_transforms/save_image_transforms_to_safetensors.py @@ -18,14 +18,14 @@ from pathlib import Path import torch from safetensors.torch import save_file -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.datasets.transforms import ( +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.datasets.transforms import ( ImageTransformConfig, ImageTransforms, ImageTransformsConfig, make_transform_from_config, ) -from lerobot.common.utils.random_utils import seeded_context +from lerobot.utils.random_utils import seeded_context ARTIFACT_DIR = Path("tests/artifacts/image_transforms") DATASET_REPO_ID = "lerobot/aloha_static_cups_open" diff --git a/tests/artifacts/policies/save_policy_to_safetensors.py b/tests/artifacts/policies/save_policy_to_safetensors.py index 785f296..6ccb47c 100644 --- a/tests/artifacts/policies/save_policy_to_safetensors.py +++ b/tests/artifacts/policies/save_policy_to_safetensors.py @@ -19,12 +19,12 @@ from pathlib import Path import torch from safetensors.torch import save_file -from lerobot.common.datasets.factory import make_dataset -from lerobot.common.optim.factory import make_optimizer_and_scheduler -from lerobot.common.policies.factory import make_policy, make_policy_config -from lerobot.common.utils.random_utils import set_seed from lerobot.configs.default import DatasetConfig from lerobot.configs.train import TrainPipelineConfig +from lerobot.datasets.factory import make_dataset +from lerobot.optim.factory import make_optimizer_and_scheduler +from lerobot.policies.factory import make_policy, make_policy_config +from lerobot.utils.random_utils import set_seed def get_policy_stats(ds_repo_id: str, policy_name: str, policy_kwargs: dict): diff --git a/tests/cameras/test_opencv.py b/tests/cameras/test_opencv.py index 7ba04b2..a9c060c 100644 --- a/tests/cameras/test_opencv.py +++ b/tests/cameras/test_opencv.py @@ -24,9 +24,9 @@ from pathlib import Path import numpy as np import pytest -from lerobot.common.cameras.configs import Cv2Rotation -from lerobot.common.cameras.opencv import OpenCVCamera, OpenCVCameraConfig -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.cameras.configs import Cv2Rotation +from lerobot.cameras.opencv import OpenCVCamera, OpenCVCameraConfig +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError # NOTE(Steven): more tests + assertions? TEST_ARTIFACTS_DIR = Path(__file__).parent.parent / "artifacts" / "cameras" diff --git a/tests/cameras/test_realsense.py b/tests/cameras/test_realsense.py index 5fb1767..3957baf 100644 --- a/tests/cameras/test_realsense.py +++ b/tests/cameras/test_realsense.py @@ -25,12 +25,12 @@ from unittest.mock import patch import numpy as np import pytest -from lerobot.common.cameras.configs import Cv2Rotation -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.cameras.configs import Cv2Rotation +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError pytest.importorskip("pyrealsense2") -from lerobot.common.cameras.realsense import RealSenseCamera, RealSenseCameraConfig +from lerobot.cameras.realsense import RealSenseCamera, RealSenseCameraConfig TEST_ARTIFACTS_DIR = Path(__file__).parent.parent / "artifacts" / "cameras" BAG_FILE_PATH = TEST_ARTIFACTS_DIR / "test_rs.bag" diff --git a/tests/configs/test_plugin_loading.py b/tests/configs/test_plugin_loading.py index 1a8ccee..957574e 100644 --- a/tests/configs/test_plugin_loading.py +++ b/tests/configs/test_plugin_loading.py @@ -5,15 +5,15 @@ from typing import Generator import pytest -from lerobot.common.envs.configs import EnvConfig from lerobot.configs.parser import PluginLoadError, load_plugin, parse_plugin_args, wrap +from lerobot.envs.configs import EnvConfig def create_plugin_code(*, base_class: str = "EnvConfig", plugin_name: str = "test_env") -> str: """Creates a dummy plugin module that implements its own EnvConfig subclass.""" return f""" from dataclasses import dataclass -from lerobot.common.envs.configs import {base_class} +from lerobot.envs.configs import {base_class} @{base_class}.register_subclass("{plugin_name}") @dataclass diff --git a/tests/datasets/test_compute_stats.py b/tests/datasets/test_compute_stats.py index d9032c8..8f8179c 100644 --- a/tests/datasets/test_compute_stats.py +++ b/tests/datasets/test_compute_stats.py @@ -18,7 +18,7 @@ from unittest.mock import patch import numpy as np import pytest -from lerobot.common.datasets.compute_stats import ( +from lerobot.datasets.compute_stats import ( _assert_type_and_shape, aggregate_feature_stats, aggregate_stats, @@ -61,7 +61,7 @@ def test_sample_indices(): assert len(indices) == estimate_num_samples(10) -@patch("lerobot.common.datasets.compute_stats.load_image_as_numpy", side_effect=mock_load_image_as_numpy) +@patch("lerobot.datasets.compute_stats.load_image_as_numpy", side_effect=mock_load_image_as_numpy) def test_sample_images(mock_load): image_paths = [f"image_{i}.jpg" for i in range(100)] images = sample_images(image_paths) @@ -144,9 +144,7 @@ def test_compute_episode_stats(): "observation.state": {"dtype": "numeric"}, } - with patch( - "lerobot.common.datasets.compute_stats.load_image_as_numpy", side_effect=mock_load_image_as_numpy - ): + with patch("lerobot.datasets.compute_stats.load_image_as_numpy", side_effect=mock_load_image_as_numpy): stats = compute_episode_stats(episode_data, features) assert "observation.image" in stats and "observation.state" in stats diff --git a/tests/datasets/test_datasets.py b/tests/datasets/test_datasets.py index b4fca77..d3b78dd 100644 --- a/tests/datasets/test_datasets.py +++ b/tests/datasets/test_datasets.py @@ -28,21 +28,21 @@ from PIL import Image from safetensors.torch import load_file import lerobot -from lerobot.common.datasets.factory import make_dataset -from lerobot.common.datasets.image_writer import image_array_to_pil_image -from lerobot.common.datasets.lerobot_dataset import ( +from lerobot.configs.default import DatasetConfig +from lerobot.configs.train import TrainPipelineConfig +from lerobot.datasets.factory import make_dataset +from lerobot.datasets.image_writer import image_array_to_pil_image +from lerobot.datasets.lerobot_dataset import ( LeRobotDataset, MultiLeRobotDataset, ) -from lerobot.common.datasets.utils import ( +from lerobot.datasets.utils import ( create_branch, flatten_dict, unflatten_dict, ) -from lerobot.common.envs.factory import make_env_config -from lerobot.common.policies.factory import make_policy_config -from lerobot.configs.default import DatasetConfig -from lerobot.configs.train import TrainPipelineConfig +from lerobot.envs.factory import make_env_config +from lerobot.policies.factory import make_policy_config from tests.fixtures.constants import DUMMY_CHW, DUMMY_HWC, DUMMY_REPO_ID from tests.utils import require_x86_64_kernel @@ -558,7 +558,7 @@ def test_create_branch(): def test_dataset_feature_with_forward_slash_raises_error(): # make sure dir does not exist - from lerobot.common.constants import HF_LEROBOT_HOME + from lerobot.constants import HF_LEROBOT_HOME dataset_dir = HF_LEROBOT_HOME / "lerobot/test/with/slash" # make sure does not exist diff --git a/tests/datasets/test_delta_timestamps.py b/tests/datasets/test_delta_timestamps.py index 3501464..786b90c 100644 --- a/tests/datasets/test_delta_timestamps.py +++ b/tests/datasets/test_delta_timestamps.py @@ -19,7 +19,7 @@ import pyarrow.compute as pc import pytest import torch -from lerobot.common.datasets.utils import ( +from lerobot.datasets.utils import ( check_delta_timestamps, check_timestamps_sync, get_delta_indices, diff --git a/tests/datasets/test_image_transforms.py b/tests/datasets/test_image_transforms.py index 146a4dc..3ab93cb 100644 --- a/tests/datasets/test_image_transforms.py +++ b/tests/datasets/test_image_transforms.py @@ -21,7 +21,7 @@ from safetensors.torch import load_file from torchvision.transforms import v2 from torchvision.transforms.v2 import functional as F # noqa: N812 -from lerobot.common.datasets.transforms import ( +from lerobot.datasets.transforms import ( ImageTransformConfig, ImageTransforms, ImageTransformsConfig, @@ -29,11 +29,11 @@ from lerobot.common.datasets.transforms import ( SharpnessJitter, make_transform_from_config, ) -from lerobot.common.utils.random_utils import seeded_context from lerobot.scripts.visualize_image_transforms import ( save_all_transforms, save_each_transform, ) +from lerobot.utils.random_utils import seeded_context from tests.artifacts.image_transforms.save_image_transforms_to_safetensors import ARTIFACT_DIR from tests.utils import require_x86_64_kernel diff --git a/tests/datasets/test_image_writer.py b/tests/datasets/test_image_writer.py index 802fe0d..99c8b24 100644 --- a/tests/datasets/test_image_writer.py +++ b/tests/datasets/test_image_writer.py @@ -20,7 +20,7 @@ import numpy as np import pytest from PIL import Image -from lerobot.common.datasets.image_writer import ( +from lerobot.datasets.image_writer import ( AsyncImageWriter, image_array_to_pil_image, safe_stop_image_writer, diff --git a/tests/datasets/test_online_buffer.py b/tests/datasets/test_online_buffer.py index 339f684..887da60 100644 --- a/tests/datasets/test_online_buffer.py +++ b/tests/datasets/test_online_buffer.py @@ -20,7 +20,7 @@ import numpy as np import pytest import torch -from lerobot.common.datasets.online_buffer import OnlineBuffer, compute_sampler_weights +from lerobot.datasets.online_buffer import OnlineBuffer, compute_sampler_weights # Some constants for OnlineBuffer tests. data_key = "data" diff --git a/tests/datasets/test_sampler.py b/tests/datasets/test_sampler.py index ee143f3..94576a3 100644 --- a/tests/datasets/test_sampler.py +++ b/tests/datasets/test_sampler.py @@ -15,9 +15,9 @@ # limitations under the License. from datasets import Dataset -from lerobot.common.datasets.push_dataset_to_hub.utils import calculate_episode_data_index -from lerobot.common.datasets.sampler import EpisodeAwareSampler -from lerobot.common.datasets.utils import ( +from lerobot.datasets.push_dataset_to_hub.utils import calculate_episode_data_index +from lerobot.datasets.sampler import EpisodeAwareSampler +from lerobot.datasets.utils import ( hf_transform_to_torch, ) diff --git a/tests/datasets/test_utils.py b/tests/datasets/test_utils.py index 0d02218..ba16874 100644 --- a/tests/datasets/test_utils.py +++ b/tests/datasets/test_utils.py @@ -18,8 +18,8 @@ import torch from datasets import Dataset from huggingface_hub import DatasetCard -from lerobot.common.datasets.push_dataset_to_hub.utils import calculate_episode_data_index -from lerobot.common.datasets.utils import create_lerobot_dataset_card, hf_transform_to_torch +from lerobot.datasets.push_dataset_to_hub.utils import calculate_episode_data_index +from lerobot.datasets.utils import create_lerobot_dataset_card, hf_transform_to_torch def test_default_parameters(): diff --git a/tests/envs/test_envs.py b/tests/envs/test_envs.py index b318abb..140e9df 100644 --- a/tests/envs/test_envs.py +++ b/tests/envs/test_envs.py @@ -21,8 +21,8 @@ import torch from gymnasium.utils.env_checker import check_env import lerobot -from lerobot.common.envs.factory import make_env, make_env_config -from lerobot.common.envs.utils import preprocess_observation +from lerobot.envs.factory import make_env, make_env_config +from lerobot.envs.utils import preprocess_observation from tests.utils import require_env OBS_TYPES = ["state", "pixels", "pixels_agent_pos"] diff --git a/tests/fixtures/constants.py b/tests/fixtures/constants.py index 5e5c762..d69a463 100644 --- a/tests/fixtures/constants.py +++ b/tests/fixtures/constants.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from lerobot.common.constants import HF_LEROBOT_HOME +from lerobot.constants import HF_LEROBOT_HOME LEROBOT_TEST_DIR = HF_LEROBOT_HOME / "_testing" DUMMY_REPO_ID = "dummy/repo" diff --git a/tests/fixtures/dataset_factories.py b/tests/fixtures/dataset_factories.py index 531977d..047db33 100644 --- a/tests/fixtures/dataset_factories.py +++ b/tests/fixtures/dataset_factories.py @@ -23,8 +23,8 @@ import PIL.Image import pytest import torch -from lerobot.common.datasets.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset, LeRobotDatasetMetadata -from lerobot.common.datasets.utils import ( +from lerobot.datasets.lerobot_dataset import CODEBASE_VERSION, LeRobotDataset, LeRobotDatasetMetadata +from lerobot.datasets.utils import ( DEFAULT_CHUNK_SIZE, DEFAULT_FEATURES, DEFAULT_PARQUET_PATH, @@ -351,10 +351,8 @@ def lerobot_dataset_metadata_factory( episodes=episodes, ) with ( - patch("lerobot.common.datasets.lerobot_dataset.get_safe_version") as mock_get_safe_version_patch, - patch( - "lerobot.common.datasets.lerobot_dataset.snapshot_download" - ) as mock_snapshot_download_patch, + patch("lerobot.datasets.lerobot_dataset.get_safe_version") as mock_get_safe_version_patch, + patch("lerobot.datasets.lerobot_dataset.snapshot_download") as mock_snapshot_download_patch, ): mock_get_safe_version_patch.side_effect = lambda repo_id, version: version mock_snapshot_download_patch.side_effect = mock_snapshot_download @@ -428,11 +426,9 @@ def lerobot_dataset_factory( episodes=episode_dicts, ) with ( - patch("lerobot.common.datasets.lerobot_dataset.LeRobotDatasetMetadata") as mock_metadata_patch, - patch("lerobot.common.datasets.lerobot_dataset.get_safe_version") as mock_get_safe_version_patch, - patch( - "lerobot.common.datasets.lerobot_dataset.snapshot_download" - ) as mock_snapshot_download_patch, + patch("lerobot.datasets.lerobot_dataset.LeRobotDatasetMetadata") as mock_metadata_patch, + patch("lerobot.datasets.lerobot_dataset.get_safe_version") as mock_get_safe_version_patch, + patch("lerobot.datasets.lerobot_dataset.snapshot_download") as mock_snapshot_download_patch, ): mock_metadata_patch.return_value = mock_metadata mock_get_safe_version_patch.side_effect = lambda repo_id, version: version diff --git a/tests/fixtures/files.py b/tests/fixtures/files.py index 678d1f3..e0553f7 100644 --- a/tests/fixtures/files.py +++ b/tests/fixtures/files.py @@ -20,7 +20,7 @@ import pyarrow.compute as pc import pyarrow.parquet as pq import pytest -from lerobot.common.datasets.utils import ( +from lerobot.datasets.utils import ( EPISODES_PATH, EPISODES_STATS_PATH, INFO_PATH, diff --git a/tests/fixtures/hub.py b/tests/fixtures/hub.py index aa2768e..f7c5f5b 100644 --- a/tests/fixtures/hub.py +++ b/tests/fixtures/hub.py @@ -17,7 +17,7 @@ import datasets import pytest from huggingface_hub.utils import filter_repo_objects -from lerobot.common.datasets.utils import ( +from lerobot.datasets.utils import ( EPISODES_PATH, EPISODES_STATS_PATH, INFO_PATH, diff --git a/tests/fixtures/optimizers.py b/tests/fixtures/optimizers.py index 6548856..a1b4a9d 100644 --- a/tests/fixtures/optimizers.py +++ b/tests/fixtures/optimizers.py @@ -14,8 +14,8 @@ import pytest import torch -from lerobot.common.optim.optimizers import AdamConfig -from lerobot.common.optim.schedulers import VQBeTSchedulerConfig +from lerobot.optim.optimizers import AdamConfig +from lerobot.optim.schedulers import VQBeTSchedulerConfig @pytest.fixture diff --git a/tests/mocks/mock_dynamixel.py b/tests/mocks/mock_dynamixel.py index d446bf2..6459243 100644 --- a/tests/mocks/mock_dynamixel.py +++ b/tests/mocks/mock_dynamixel.py @@ -5,7 +5,7 @@ import dynamixel_sdk as dxl import serial from mock_serial.mock_serial import MockSerial -from lerobot.common.motors.dynamixel.dynamixel import _split_into_byte_chunks +from lerobot.motors.dynamixel.dynamixel import _split_into_byte_chunks from .mock_serial_patch import WaitableStub diff --git a/tests/mocks/mock_feetech.py b/tests/mocks/mock_feetech.py index 5279b1d..e0b677d 100644 --- a/tests/mocks/mock_feetech.py +++ b/tests/mocks/mock_feetech.py @@ -5,7 +5,7 @@ import scservo_sdk as scs import serial from mock_serial import MockSerial -from lerobot.common.motors.feetech.feetech import _split_into_byte_chunks, patch_setPacketTimeout +from lerobot.motors.feetech.feetech import _split_into_byte_chunks, patch_setPacketTimeout from .mock_serial_patch import WaitableStub diff --git a/tests/mocks/mock_motors_bus.py b/tests/mocks/mock_motors_bus.py index e322eae..91e3347 100644 --- a/tests/mocks/mock_motors_bus.py +++ b/tests/mocks/mock_motors_bus.py @@ -1,6 +1,6 @@ # ruff: noqa: N802 -from lerobot.common.motors.motors_bus import ( +from lerobot.motors.motors_bus import ( Motor, MotorsBus, ) diff --git a/tests/mocks/mock_robot.py b/tests/mocks/mock_robot.py index 40d8fbd..971fc00 100644 --- a/tests/mocks/mock_robot.py +++ b/tests/mocks/mock_robot.py @@ -3,9 +3,9 @@ from dataclasses import dataclass, field from functools import cached_property from typing import Any -from lerobot.common.cameras import CameraConfig, make_cameras_from_configs -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.robots import Robot, RobotConfig +from lerobot.cameras import CameraConfig, make_cameras_from_configs +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.robots import Robot, RobotConfig @RobotConfig.register_subclass("mock_robot") diff --git a/tests/mocks/mock_teleop.py b/tests/mocks/mock_teleop.py index a7f5cad..c29cc92 100644 --- a/tests/mocks/mock_teleop.py +++ b/tests/mocks/mock_teleop.py @@ -3,8 +3,8 @@ from dataclasses import dataclass from functools import cached_property from typing import Any -from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError -from lerobot.common.teleoperators import Teleoperator, TeleoperatorConfig +from lerobot.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError +from lerobot.teleoperators import Teleoperator, TeleoperatorConfig @TeleoperatorConfig.register_subclass("mock_teleop") diff --git a/tests/motors/test_dynamixel.py b/tests/motors/test_dynamixel.py index dcce8f6..a54e490 100644 --- a/tests/motors/test_dynamixel.py +++ b/tests/motors/test_dynamixel.py @@ -5,10 +5,10 @@ from unittest.mock import MagicMock, patch import pytest -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.dynamixel import MODEL_NUMBER_TABLE, DynamixelMotorsBus -from lerobot.common.motors.dynamixel.tables import X_SERIES_CONTROL_TABLE -from lerobot.common.utils.encoding_utils import encode_twos_complement +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.dynamixel import MODEL_NUMBER_TABLE, DynamixelMotorsBus +from lerobot.motors.dynamixel.tables import X_SERIES_CONTROL_TABLE +from lerobot.utils.encoding_utils import encode_twos_complement try: import dynamixel_sdk as dxl @@ -389,7 +389,7 @@ def test_record_ranges_of_motion(mock_motors, dummy_motors): read_pos_stub = mock_motors.build_sequential_sync_read_stub( *X_SERIES_CONTROL_TABLE["Present_Position"], positions ) - with patch("lerobot.common.motors.motors_bus.enter_pressed", side_effect=[False, True]): + with patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]): bus = DynamixelMotorsBus(port=mock_motors.port, motors=dummy_motors) bus.connect(handshake=False) diff --git a/tests/motors/test_feetech.py b/tests/motors/test_feetech.py index 2e7b2ff..7f9e5dd 100644 --- a/tests/motors/test_feetech.py +++ b/tests/motors/test_feetech.py @@ -5,10 +5,10 @@ from unittest.mock import MagicMock, patch import pytest -from lerobot.common.motors import Motor, MotorCalibration, MotorNormMode -from lerobot.common.motors.feetech import MODEL_NUMBER, MODEL_NUMBER_TABLE, FeetechMotorsBus -from lerobot.common.motors.feetech.tables import STS_SMS_SERIES_CONTROL_TABLE -from lerobot.common.utils.encoding_utils import encode_sign_magnitude +from lerobot.motors import Motor, MotorCalibration, MotorNormMode +from lerobot.motors.feetech import MODEL_NUMBER, MODEL_NUMBER_TABLE, FeetechMotorsBus +from lerobot.motors.feetech.tables import STS_SMS_SERIES_CONTROL_TABLE +from lerobot.utils.encoding_utils import encode_sign_magnitude try: import scservo_sdk as scs @@ -432,7 +432,7 @@ def test_record_ranges_of_motion(mock_motors, dummy_motors): stub = mock_motors.build_sequential_sync_read_stub( *STS_SMS_SERIES_CONTROL_TABLE["Present_Position"], positions ) - with patch("lerobot.common.motors.motors_bus.enter_pressed", side_effect=[False, True]): + with patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]): bus = FeetechMotorsBus(port=mock_motors.port, motors=dummy_motors) bus.connect(handshake=False) diff --git a/tests/motors/test_motors_bus.py b/tests/motors/test_motors_bus.py index 78b7a47..966af3f 100644 --- a/tests/motors/test_motors_bus.py +++ b/tests/motors/test_motors_bus.py @@ -3,7 +3,7 @@ from unittest.mock import patch import pytest -from lerobot.common.motors.motors_bus import ( +from lerobot.motors.motors_bus import ( Motor, MotorNormMode, assert_same_address, diff --git a/tests/optim/test_optimizers.py b/tests/optim/test_optimizers.py index 630353f..4152c7f 100644 --- a/tests/optim/test_optimizers.py +++ b/tests/optim/test_optimizers.py @@ -14,11 +14,11 @@ import pytest import torch -from lerobot.common.constants import ( +from lerobot.constants import ( OPTIMIZER_PARAM_GROUPS, OPTIMIZER_STATE, ) -from lerobot.common.optim.optimizers import ( +from lerobot.optim.optimizers import ( AdamConfig, AdamWConfig, MultiAdamConfig, diff --git a/tests/optim/test_schedulers.py b/tests/optim/test_schedulers.py index d6191dc..43851c4 100644 --- a/tests/optim/test_schedulers.py +++ b/tests/optim/test_schedulers.py @@ -13,8 +13,8 @@ # limitations under the License. from torch.optim.lr_scheduler import LambdaLR -from lerobot.common.constants import SCHEDULER_STATE -from lerobot.common.optim.schedulers import ( +from lerobot.constants import SCHEDULER_STATE +from lerobot.optim.schedulers import ( CosineDecayWithWarmupSchedulerConfig, DiffuserSchedulerConfig, VQBeTSchedulerConfig, diff --git a/tests/policies/hilserl/test_modeling_classifier.py b/tests/policies/hilserl/test_modeling_classifier.py index 526e1f1..0be1b9c 100644 --- a/tests/policies/hilserl/test_modeling_classifier.py +++ b/tests/policies/hilserl/test_modeling_classifier.py @@ -16,9 +16,9 @@ import torch -from lerobot.common.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig -from lerobot.common.policies.sac.reward_model.modeling_classifier import ClassifierOutput from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.policies.sac.reward_model.configuration_classifier import RewardClassifierConfig +from lerobot.policies.sac.reward_model.modeling_classifier import ClassifierOutput from tests.utils import require_package @@ -37,7 +37,7 @@ def test_classifier_output(): @require_package("transformers") def test_binary_classifier_with_default_params(): - from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier + from lerobot.policies.sac.reward_model.modeling_classifier import Classifier config = RewardClassifierConfig() config.input_features = { @@ -78,7 +78,7 @@ def test_binary_classifier_with_default_params(): @require_package("transformers") def test_multiclass_classifier(): - from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier + from lerobot.policies.sac.reward_model.modeling_classifier import Classifier num_classes = 5 config = RewardClassifierConfig() @@ -117,7 +117,7 @@ def test_multiclass_classifier(): @require_package("transformers") def test_default_device(): - from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier + from lerobot.policies.sac.reward_model.modeling_classifier import Classifier config = RewardClassifierConfig() assert config.device == "cpu" @@ -129,7 +129,7 @@ def test_default_device(): @require_package("transformers") def test_explicit_device_setup(): - from lerobot.common.policies.sac.reward_model.modeling_classifier import Classifier + from lerobot.policies.sac.reward_model.modeling_classifier import Classifier config = RewardClassifierConfig(device="cpu") assert config.device == "cpu" diff --git a/tests/policies/test_policies.py b/tests/policies/test_policies.py index 1b40c66..ed37fed 100644 --- a/tests/policies/test_policies.py +++ b/tests/policies/test_policies.py @@ -24,23 +24,23 @@ from packaging import version from safetensors.torch import load_file from lerobot import available_policies -from lerobot.common.datasets.factory import make_dataset -from lerobot.common.datasets.utils import cycle, dataset_to_policy_features -from lerobot.common.envs.factory import make_env, make_env_config -from lerobot.common.envs.utils import preprocess_observation -from lerobot.common.optim.factory import make_optimizer_and_scheduler -from lerobot.common.policies.act.modeling_act import ACTTemporalEnsembler -from lerobot.common.policies.factory import ( +from lerobot.configs.default import DatasetConfig +from lerobot.configs.train import TrainPipelineConfig +from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.datasets.factory import make_dataset +from lerobot.datasets.utils import cycle, dataset_to_policy_features +from lerobot.envs.factory import make_env, make_env_config +from lerobot.envs.utils import preprocess_observation +from lerobot.optim.factory import make_optimizer_and_scheduler +from lerobot.policies.act.modeling_act import ACTTemporalEnsembler +from lerobot.policies.factory import ( get_policy_class, make_policy, make_policy_config, ) -from lerobot.common.policies.normalize import Normalize, Unnormalize -from lerobot.common.policies.pretrained import PreTrainedPolicy -from lerobot.common.utils.random_utils import seeded_context -from lerobot.configs.default import DatasetConfig -from lerobot.configs.train import TrainPipelineConfig -from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.policies.normalize import Normalize, Unnormalize +from lerobot.policies.pretrained import PreTrainedPolicy +from lerobot.utils.random_utils import seeded_context from tests.artifacts.policies.save_policy_to_safetensors import get_policy_stats from tests.utils import DEVICE, require_cpu, require_env, require_x86_64_kernel diff --git a/tests/policies/test_sac_config.py b/tests/policies/test_sac_config.py index d94ee41..a67815e 100644 --- a/tests/policies/test_sac_config.py +++ b/tests/policies/test_sac_config.py @@ -16,7 +16,8 @@ import pytest -from lerobot.common.policies.sac.configuration_sac import ( +from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature +from lerobot.policies.sac.configuration_sac import ( ActorLearnerConfig, ActorNetworkConfig, ConcurrencyConfig, @@ -24,7 +25,6 @@ from lerobot.common.policies.sac.configuration_sac import ( PolicyConfig, SACConfig, ) -from lerobot.configs.types import FeatureType, NormalizationMode, PolicyFeature def test_sac_config_default_initialization(): diff --git a/tests/policies/test_sac_policy.py b/tests/policies/test_sac_policy.py index e4e2dd8..7891c2e 100644 --- a/tests/policies/test_sac_policy.py +++ b/tests/policies/test_sac_policy.py @@ -20,10 +20,10 @@ import pytest import torch from torch import Tensor, nn -from lerobot.common.policies.sac.configuration_sac import SACConfig -from lerobot.common.policies.sac.modeling_sac import MLP, SACPolicy -from lerobot.common.utils.random_utils import seeded_context, set_seed from lerobot.configs.types import FeatureType, PolicyFeature +from lerobot.policies.sac.configuration_sac import SACConfig +from lerobot.policies.sac.modeling_sac import MLP, SACPolicy +from lerobot.utils.random_utils import seeded_context, set_seed try: import transformers # noqa: F401 diff --git a/tests/rl/test_actor.py b/tests/rl/test_actor.py index 0cf6a8f..f078b46 100644 --- a/tests/rl/test_actor.py +++ b/tests/rl/test_actor.py @@ -21,14 +21,14 @@ import pytest import torch from torch.multiprocessing import Event, Queue -from lerobot.common.utils.transition import Transition +from lerobot.utils.transition import Transition from tests.utils import require_package def create_learner_service_stub(): import grpc - from lerobot.common.transport import services_pb2, services_pb2_grpc + from lerobot.transport import services_pb2, services_pb2_grpc class MockLearnerService(services_pb2_grpc.LearnerServiceServicer): def __init__(self): @@ -101,8 +101,8 @@ def test_establish_learner_connection_failure(): @require_package("grpc") def test_push_transitions_to_transport_queue(): - from lerobot.common.transport.utils import bytes_to_transitions from lerobot.scripts.rl.actor import push_transitions_to_transport_queue + from lerobot.transport.utils import bytes_to_transitions from tests.transport.test_transport_utils import assert_transitions_equal """Test pushing transitions to transport queue.""" @@ -169,8 +169,8 @@ def test_transitions_stream(): @require_package("grpc") @pytest.mark.timeout(3) # force cross-platform watchdog def test_interactions_stream(): - from lerobot.common.transport.utils import bytes_to_python_object, python_object_to_bytes from lerobot.scripts.rl.actor import interactions_stream + from lerobot.transport.utils import bytes_to_python_object, python_object_to_bytes """Test interactions stream functionality.""" shutdown_event = Event() diff --git a/tests/rl/test_actor_learner.py b/tests/rl/test_actor_learner.py index cb72da7..b2a7a5d 100644 --- a/tests/rl/test_actor_learner.py +++ b/tests/rl/test_actor_learner.py @@ -22,9 +22,9 @@ import pytest import torch from torch.multiprocessing import Event, Queue -from lerobot.common.policies.sac.configuration_sac import SACConfig -from lerobot.common.utils.transition import Transition from lerobot.configs.train import TrainRLServerPipelineConfig +from lerobot.policies.sac.configuration_sac import SACConfig +from lerobot.utils.transition import Transition from tests.utils import require_package @@ -90,7 +90,6 @@ def cfg(): @require_package("grpc") @pytest.mark.timeout(10) # force cross-platform watchdog def test_end_to_end_transitions_flow(cfg): - from lerobot.common.transport.utils import bytes_to_transitions from lerobot.scripts.rl.actor import ( establish_learner_connection, learner_service_client, @@ -98,6 +97,7 @@ def test_end_to_end_transitions_flow(cfg): send_transitions, ) from lerobot.scripts.rl.learner import start_learner + from lerobot.transport.utils import bytes_to_transitions from tests.transport.test_transport_utils import assert_transitions_equal """Test complete transitions flow from actor to learner.""" @@ -152,13 +152,13 @@ def test_end_to_end_transitions_flow(cfg): @require_package("grpc") @pytest.mark.timeout(10) def test_end_to_end_interactions_flow(cfg): - from lerobot.common.transport.utils import bytes_to_python_object, python_object_to_bytes from lerobot.scripts.rl.actor import ( establish_learner_connection, learner_service_client, send_interactions, ) from lerobot.scripts.rl.learner import start_learner + from lerobot.transport.utils import bytes_to_python_object, python_object_to_bytes """Test complete interactions flow from actor to learner.""" # Queues for actor-learner communication @@ -226,9 +226,9 @@ def test_end_to_end_interactions_flow(cfg): @pytest.mark.parametrize("data_size", ["small", "large"]) @pytest.mark.timeout(10) def test_end_to_end_parameters_flow(cfg, data_size): - from lerobot.common.transport.utils import bytes_to_state_dict, state_to_bytes from lerobot.scripts.rl.actor import establish_learner_connection, learner_service_client, receive_policy from lerobot.scripts.rl.learner import start_learner + from lerobot.transport.utils import bytes_to_state_dict, state_to_bytes """Test complete parameter flow from learner to actor, with small and large data.""" # Actor's local queue to receive params diff --git a/tests/rl/test_learner_service.py b/tests/rl/test_learner_service.py index ee9d06e..f5e1e8d 100644 --- a/tests/rl/test_learner_service.py +++ b/tests/rl/test_learner_service.py @@ -50,8 +50,8 @@ def create_learner_service_stub( ): import grpc - from lerobot.common.transport import services_pb2_grpc # generated from .proto from lerobot.scripts.rl.learner_service import LearnerService + from lerobot.transport import services_pb2_grpc # generated from .proto """Fixture to start a LearnerService gRPC server and provide a connected stub.""" @@ -83,7 +83,7 @@ def close_learner_service_stub(channel, server): @pytest.mark.timeout(3) # force cross-platform watchdog def test_ready_method(learner_service_stub): - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test the ready method of the UserService.""" request = services_pb2.Empty() @@ -94,7 +94,7 @@ def test_ready_method(learner_service_stub): @require_package("grpc") @pytest.mark.timeout(3) # force cross-platform watchdog def test_send_interactions(): - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 shutdown_event = Event() @@ -138,7 +138,7 @@ def test_send_interactions(): @require_package("grpc") @pytest.mark.timeout(3) # force cross-platform watchdog def test_send_transitions(): - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test the SendTransitions method with various transition data.""" shutdown_event = Event() @@ -184,7 +184,7 @@ def test_send_transitions(): @require_package("grpc") @pytest.mark.timeout(3) # force cross-platform watchdog def test_send_transitions_empty_stream(): - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test SendTransitions with empty stream.""" shutdown_event = Event() @@ -214,7 +214,7 @@ def test_send_transitions_empty_stream(): def test_stream_parameters(): import time - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test the StreamParameters method.""" shutdown_event = Event() @@ -270,7 +270,7 @@ def test_stream_parameters(): @require_package("grpc") @pytest.mark.timeout(3) # force cross-platform watchdog def test_stream_parameters_with_shutdown(): - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test StreamParameters handles shutdown gracefully.""" shutdown_event = Event() @@ -325,7 +325,7 @@ def test_stream_parameters_waits_and_retries_on_empty_queue(): import threading import time - from lerobot.common.transport import services_pb2 + from lerobot.transport import services_pb2 """Test that StreamParameters waits and retries when the queue is empty.""" shutdown_event = Event() diff --git a/tests/robots/test_so100_follower.py b/tests/robots/test_so100_follower.py index 81d9d6a..498eec9 100644 --- a/tests/robots/test_so100_follower.py +++ b/tests/robots/test_so100_follower.py @@ -3,7 +3,7 @@ from unittest.mock import MagicMock, patch import pytest -from lerobot.common.robots.so100_follower import ( +from lerobot.robots.so100_follower import ( SO100Follower, SO100FollowerConfig, ) @@ -50,7 +50,7 @@ def follower(): with ( patch( - "lerobot.common.robots.so100_follower.so100_follower.FeetechMotorsBus", + "lerobot.robots.so100_follower.so100_follower.FeetechMotorsBus", side_effect=_bus_side_effect, ), patch.object(SO100Follower, "configure", lambda self: None), diff --git a/tests/test_available.py b/tests/test_available.py index a18b95f..19e39b2 100644 --- a/tests/test_available.py +++ b/tests/test_available.py @@ -19,10 +19,10 @@ import gymnasium as gym import pytest import lerobot -from lerobot.common.policies.act.modeling_act import ACTPolicy -from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy -from lerobot.common.policies.tdmpc.modeling_tdmpc import TDMPCPolicy -from lerobot.common.policies.vqbet.modeling_vqbet import VQBeTPolicy +from lerobot.policies.act.modeling_act import ACTPolicy +from lerobot.policies.diffusion.modeling_diffusion import DiffusionPolicy +from lerobot.policies.tdmpc.modeling_tdmpc import TDMPCPolicy +from lerobot.policies.vqbet.modeling_vqbet import VQBeTPolicy from tests.utils import require_env diff --git a/tests/transport/test_transport_utils.py b/tests/transport/test_transport_utils.py index cf33f52..79edad4 100644 --- a/tests/transport/test_transport_utils.py +++ b/tests/transport/test_transport_utils.py @@ -21,13 +21,13 @@ from pickle import UnpicklingError import pytest import torch -from lerobot.common.utils.transition import Transition +from lerobot.utils.transition import Transition from tests.utils import require_cuda, require_package @require_package("grpc") def test_bytes_buffer_size_empty_buffer(): - from lerobot.common.transport.utils import bytes_buffer_size + from lerobot.transport.utils import bytes_buffer_size """Test with an empty buffer.""" buffer = io.BytesIO() @@ -38,7 +38,7 @@ def test_bytes_buffer_size_empty_buffer(): @require_package("grpc") def test_bytes_buffer_size_small_buffer(): - from lerobot.common.transport.utils import bytes_buffer_size + from lerobot.transport.utils import bytes_buffer_size """Test with a small buffer.""" buffer = io.BytesIO(b"Hello, World!") @@ -48,7 +48,7 @@ def test_bytes_buffer_size_small_buffer(): @require_package("grpc") def test_bytes_buffer_size_large_buffer(): - from lerobot.common.transport.utils import CHUNK_SIZE, bytes_buffer_size + from lerobot.transport.utils import CHUNK_SIZE, bytes_buffer_size """Test with a large buffer.""" data = b"x" * (CHUNK_SIZE * 2 + 1000) @@ -59,7 +59,7 @@ def test_bytes_buffer_size_large_buffer(): @require_package("grpc") def test_send_bytes_in_chunks_empty_data(): - from lerobot.common.transport.utils import send_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import send_bytes_in_chunks, services_pb2 """Test sending empty data.""" message_class = services_pb2.InteractionMessage @@ -69,7 +69,7 @@ def test_send_bytes_in_chunks_empty_data(): @require_package("grpc") def test_single_chunk_small_data(): - from lerobot.common.transport.utils import send_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import send_bytes_in_chunks, services_pb2 """Test data that fits in a single chunk.""" data = b"Some data" @@ -83,7 +83,7 @@ def test_single_chunk_small_data(): @require_package("grpc") def test_not_silent_mode(): - from lerobot.common.transport.utils import send_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import send_bytes_in_chunks, services_pb2 """Test not silent mode.""" data = b"Some data" @@ -95,7 +95,7 @@ def test_not_silent_mode(): @require_package("grpc") def test_send_bytes_in_chunks_large_data(): - from lerobot.common.transport.utils import CHUNK_SIZE, send_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import CHUNK_SIZE, send_bytes_in_chunks, services_pb2 """Test sending large data.""" data = b"x" * (CHUNK_SIZE * 2 + 1000) @@ -112,7 +112,7 @@ def test_send_bytes_in_chunks_large_data(): @require_package("grpc") def test_send_bytes_in_chunks_large_data_with_exact_chunk_size(): - from lerobot.common.transport.utils import CHUNK_SIZE, send_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import CHUNK_SIZE, send_bytes_in_chunks, services_pb2 """Test sending large data with exact chunk size.""" data = b"x" * CHUNK_SIZE @@ -125,7 +125,7 @@ def test_send_bytes_in_chunks_large_data_with_exact_chunk_size(): @require_package("grpc") def test_receive_bytes_in_chunks_empty_data(): - from lerobot.common.transport.utils import receive_bytes_in_chunks + from lerobot.transport.utils import receive_bytes_in_chunks """Test receiving empty data.""" queue = Queue() @@ -139,7 +139,7 @@ def test_receive_bytes_in_chunks_empty_data(): @require_package("grpc") def test_receive_bytes_in_chunks_single_chunk(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving a single chunk message.""" queue = Queue() @@ -158,7 +158,7 @@ def test_receive_bytes_in_chunks_single_chunk(): @require_package("grpc") def test_receive_bytes_in_chunks_single_not_end_chunk(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving a single chunk message.""" queue = Queue() @@ -176,7 +176,7 @@ def test_receive_bytes_in_chunks_single_not_end_chunk(): @require_package("grpc") def test_receive_bytes_in_chunks_multiple_chunks(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving a multi-chunk message.""" queue = Queue() @@ -200,7 +200,7 @@ def test_receive_bytes_in_chunks_multiple_chunks(): @require_package("grpc") def test_receive_bytes_in_chunks_multiple_messages(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving multiple complete messages in sequence.""" queue = Queue() @@ -236,7 +236,7 @@ def test_receive_bytes_in_chunks_multiple_messages(): @require_package("grpc") def test_receive_bytes_in_chunks_shutdown_during_receive(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test that shutdown event stops receiving mid-stream.""" queue = Queue() @@ -260,7 +260,7 @@ def test_receive_bytes_in_chunks_shutdown_during_receive(): @require_package("grpc") def test_receive_bytes_in_chunks_only_begin_chunk(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving only a BEGIN chunk without END.""" queue = Queue() @@ -280,7 +280,7 @@ def test_receive_bytes_in_chunks_only_begin_chunk(): @require_package("grpc") def test_receive_bytes_in_chunks_missing_begin(): - from lerobot.common.transport.utils import receive_bytes_in_chunks, services_pb2 + from lerobot.transport.utils import receive_bytes_in_chunks, services_pb2 """Test receiving chunks starting with MIDDLE instead of BEGIN.""" queue = Queue() @@ -304,7 +304,7 @@ def test_receive_bytes_in_chunks_missing_begin(): # Tests for state_to_bytes and bytes_to_state_dict @require_package("grpc") def test_state_to_bytes_empty_dict(): - from lerobot.common.transport.utils import bytes_to_state_dict, state_to_bytes + from lerobot.transport.utils import bytes_to_state_dict, state_to_bytes """Test converting empty state dict to bytes.""" state_dict = {} @@ -315,7 +315,7 @@ def test_state_to_bytes_empty_dict(): @require_package("grpc") def test_bytes_to_state_dict_empty_data(): - from lerobot.common.transport.utils import bytes_to_state_dict + from lerobot.transport.utils import bytes_to_state_dict """Test converting empty data to state dict.""" with pytest.raises(EOFError): @@ -324,7 +324,7 @@ def test_bytes_to_state_dict_empty_data(): @require_package("grpc") def test_state_to_bytes_simple_dict(): - from lerobot.common.transport.utils import bytes_to_state_dict, state_to_bytes + from lerobot.transport.utils import bytes_to_state_dict, state_to_bytes """Test converting simple state dict to bytes.""" state_dict = { @@ -348,7 +348,7 @@ def test_state_to_bytes_simple_dict(): @require_package("grpc") def test_state_to_bytes_various_dtypes(): - from lerobot.common.transport.utils import bytes_to_state_dict, state_to_bytes + from lerobot.transport.utils import bytes_to_state_dict, state_to_bytes """Test converting state dict with various tensor dtypes.""" state_dict = { @@ -373,7 +373,7 @@ def test_state_to_bytes_various_dtypes(): @require_package("grpc") def test_bytes_to_state_dict_invalid_data(): - from lerobot.common.transport.utils import bytes_to_state_dict + from lerobot.transport.utils import bytes_to_state_dict """Test bytes_to_state_dict with invalid data.""" with pytest.raises(UnpicklingError): @@ -383,7 +383,7 @@ def test_bytes_to_state_dict_invalid_data(): @require_cuda @require_package("grpc") def test_state_to_bytes_various_dtypes_cuda(): - from lerobot.common.transport.utils import bytes_to_state_dict, state_to_bytes + from lerobot.transport.utils import bytes_to_state_dict, state_to_bytes """Test converting state dict with various tensor dtypes.""" state_dict = { @@ -408,7 +408,7 @@ def test_state_to_bytes_various_dtypes_cuda(): @require_package("grpc") def test_python_object_to_bytes_none(): - from lerobot.common.transport.utils import bytes_to_python_object, python_object_to_bytes + from lerobot.transport.utils import bytes_to_python_object, python_object_to_bytes """Test converting None to bytes.""" obj = None @@ -440,7 +440,7 @@ def test_python_object_to_bytes_none(): ) @require_package("grpc") def test_python_object_to_bytes_simple_types(obj): - from lerobot.common.transport.utils import bytes_to_python_object, python_object_to_bytes + from lerobot.transport.utils import bytes_to_python_object, python_object_to_bytes """Test converting simple Python types.""" data = python_object_to_bytes(obj) @@ -451,7 +451,7 @@ def test_python_object_to_bytes_simple_types(obj): @require_package("grpc") def test_python_object_to_bytes_with_tensors(): - from lerobot.common.transport.utils import bytes_to_python_object, python_object_to_bytes + from lerobot.transport.utils import bytes_to_python_object, python_object_to_bytes """Test converting objects containing PyTorch tensors.""" obj = { @@ -476,7 +476,7 @@ def test_python_object_to_bytes_with_tensors(): @require_package("grpc") def test_transitions_to_bytes_empty_list(): - from lerobot.common.transport.utils import bytes_to_transitions, transitions_to_bytes + from lerobot.transport.utils import bytes_to_transitions, transitions_to_bytes """Test converting empty transitions list.""" transitions = [] @@ -488,7 +488,7 @@ def test_transitions_to_bytes_empty_list(): @require_package("grpc") def test_transitions_to_bytes_single_transition(): - from lerobot.common.transport.utils import bytes_to_transitions, transitions_to_bytes + from lerobot.transport.utils import bytes_to_transitions, transitions_to_bytes """Test converting a single transition.""" transition = Transition( @@ -528,7 +528,7 @@ def assert_observation_equal(o1: dict, o2: dict): @require_package("grpc") def test_transitions_to_bytes_multiple_transitions(): - from lerobot.common.transport.utils import bytes_to_transitions, transitions_to_bytes + from lerobot.transport.utils import bytes_to_transitions, transitions_to_bytes """Test converting multiple transitions.""" transitions = [] @@ -552,7 +552,7 @@ def test_transitions_to_bytes_multiple_transitions(): @require_package("grpc") def test_receive_bytes_in_chunks_unknown_state(): - from lerobot.common.transport.utils import receive_bytes_in_chunks + from lerobot.transport.utils import receive_bytes_in_chunks """Test receive_bytes_in_chunks with an unknown transfer state.""" diff --git a/tests/utils.py b/tests/utils.py index 103b973..800b7d4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -21,7 +21,7 @@ import pytest import torch from lerobot import available_cameras, available_motors, available_robots -from lerobot.common.utils.import_utils import is_package_available +from lerobot.utils.import_utils import is_package_available DEVICE = os.environ.get("LEROBOT_TEST_DEVICE", "cuda") if torch.cuda.is_available() else "cpu" diff --git a/tests/utils/test_encoding_utils.py b/tests/utils/test_encoding_utils.py index c21c808..9c97967 100644 --- a/tests/utils/test_encoding_utils.py +++ b/tests/utils/test_encoding_utils.py @@ -1,6 +1,6 @@ import pytest -from lerobot.common.utils.encoding_utils import ( +from lerobot.utils.encoding_utils import ( decode_sign_magnitude, decode_twos_complement, encode_sign_magnitude, diff --git a/tests/utils/test_io_utils.py b/tests/utils/test_io_utils.py index c1b776d..9768a5e 100644 --- a/tests/utils/test_io_utils.py +++ b/tests/utils/test_io_utils.py @@ -17,7 +17,7 @@ from typing import Any import pytest -from lerobot.common.utils.io_utils import deserialize_json_into_object +from lerobot.utils.io_utils import deserialize_json_into_object @pytest.fixture diff --git a/tests/utils/test_logging_utils.py b/tests/utils/test_logging_utils.py index 1ba1829..927fdc1 100644 --- a/tests/utils/test_logging_utils.py +++ b/tests/utils/test_logging_utils.py @@ -13,7 +13,7 @@ # limitations under the License. import pytest -from lerobot.common.utils.logging_utils import AverageMeter, MetricsTracker +from lerobot.utils.logging_utils import AverageMeter, MetricsTracker @pytest.fixture diff --git a/tests/utils/test_process.py b/tests/utils/test_process.py index 054a859..61e6e2c 100644 --- a/tests/utils/test_process.py +++ b/tests/utils/test_process.py @@ -22,7 +22,7 @@ from unittest.mock import patch import pytest -from lerobot.common.utils.process import ProcessSignalHandler +from lerobot.utils.process import ProcessSignalHandler # Fixture to reset shutdown_event_counter and original signal handlers before and after each test diff --git a/tests/utils/test_queue.py b/tests/utils/test_queue.py index 863231e..0a0d217 100644 --- a/tests/utils/test_queue.py +++ b/tests/utils/test_queue.py @@ -18,7 +18,7 @@ import threading import time from queue import Queue -from lerobot.common.utils.queue import get_last_item_from_queue +from lerobot.utils.queue import get_last_item_from_queue def test_get_last_item_single_item(): diff --git a/tests/utils/test_random_utils.py b/tests/utils/test_random_utils.py index daf08a8..5865361 100644 --- a/tests/utils/test_random_utils.py +++ b/tests/utils/test_random_utils.py @@ -17,7 +17,7 @@ import numpy as np import pytest import torch -from lerobot.common.utils.random_utils import ( +from lerobot.utils.random_utils import ( deserialize_numpy_rng_state, deserialize_python_rng_state, deserialize_rng_state, diff --git a/tests/utils/test_replay_buffer.py b/tests/utils/test_replay_buffer.py index f7a055b..2602760 100644 --- a/tests/utils/test_replay_buffer.py +++ b/tests/utils/test_replay_buffer.py @@ -20,8 +20,8 @@ from typing import Callable import pytest import torch -from lerobot.common.datasets.lerobot_dataset import LeRobotDataset -from lerobot.common.utils.buffer import BatchTransition, ReplayBuffer, random_crop_vectorized +from lerobot.datasets.lerobot_dataset import LeRobotDataset +from lerobot.utils.buffer import BatchTransition, ReplayBuffer, random_crop_vectorized from tests.fixtures.constants import DUMMY_REPO_ID diff --git a/tests/utils/test_train_utils.py b/tests/utils/test_train_utils.py index b78f6e4..2d963d7 100644 --- a/tests/utils/test_train_utils.py +++ b/tests/utils/test_train_utils.py @@ -14,7 +14,7 @@ from pathlib import Path from unittest.mock import Mock, patch -from lerobot.common.constants import ( +from lerobot.constants import ( CHECKPOINTS_DIR, LAST_CHECKPOINT_LINK, OPTIMIZER_PARAM_GROUPS, @@ -24,7 +24,7 @@ from lerobot.common.constants import ( TRAINING_STATE_DIR, TRAINING_STEP, ) -from lerobot.common.utils.train_utils import ( +from lerobot.utils.train_utils import ( get_step_checkpoint_dir, get_step_identifier, load_training_state, @@ -69,7 +69,7 @@ def test_update_last_checkpoint(tmp_path): assert last_checkpoint.resolve() == checkpoint -@patch("lerobot.common.utils.train_utils.save_training_state") +@patch("lerobot.utils.train_utils.save_training_state") def test_save_checkpoint(mock_save_training_state, tmp_path, optimizer): policy = Mock() cfg = Mock()