mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-23 20:50:02 +00:00
address minor review comments
This commit is contained in:
@@ -133,16 +133,16 @@ Then, install the library in editable mode. This is useful if you plan to contri
|
||||
<hfoptions id="install_lerobot_src">
|
||||
<hfoption id="conda">
|
||||
```bash
|
||||
pip install -e ".[robot]" # For real robot workflows (recording, replaying)
|
||||
pip install -e ".[training]" # For training policies
|
||||
pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
|
||||
pip install -e ".[core_scripts]" # For robot workflows (recording, replaying, calibrate)
|
||||
pip install -e ".[training]" # For training policies
|
||||
pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
|
||||
```
|
||||
</hfoption>
|
||||
<hfoption id="uv">
|
||||
```bash
|
||||
uv pip install -e ".[robot]" # For real robot workflows (recording, replaying)
|
||||
uv pip install -e ".[training]" # For training policies
|
||||
uv pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
|
||||
uv pip install -e ".[core_scripts]" # For robot workflows (recording, replaying, calibrate)
|
||||
uv pip install -e ".[training]" # For training policies
|
||||
uv pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
|
||||
```
|
||||
</hfoption>
|
||||
</hfoptions>
|
||||
@@ -183,17 +183,17 @@ LeRobot provides **feature-scoped extras** that map to common workflows. If you
|
||||
|
||||
**Composite Extras** combine feature extras for common CLI scripts:
|
||||
|
||||
| Extra | Includes | Typical use case |
|
||||
| ------------- | ------------------------------ | ------------------------------------------------------- |
|
||||
| `robot` | `dataset` + `hardware` + `viz` | `lerobot-record`, `lerobot-replay`, `lerobot-calibrate` |
|
||||
| `evaluation` | `av` | `lerobot-eval` (add policy + env extras as needed) |
|
||||
| `dataset_viz` | `dataset` + `viz` | `lerobot-dataset-viz`, `lerobot-imgtransform-viz` |
|
||||
| Extra | Includes | Typical use case |
|
||||
| -------------- | ------------------------------ | ------------------------------------------------------- |
|
||||
| `core_scripts` | `dataset` + `hardware` + `viz` | `lerobot-record`, `lerobot-replay`, `lerobot-calibrate` |
|
||||
| `evaluation` | `av` | `lerobot-eval` (add policy + env extras as needed) |
|
||||
| `dataset_viz` | `dataset` + `viz` | `lerobot-dataset-viz`, `lerobot-imgtransform-viz` |
|
||||
|
||||
```bash
|
||||
pip install 'lerobot[robot]' # Record, replay, calibrate
|
||||
pip install 'lerobot[training]' # Train policies
|
||||
pip install 'lerobot[robot,training]' # Record + train
|
||||
pip install 'lerobot[all]' # Everything
|
||||
pip install 'lerobot[core_scripts]' # Record, replay, calibrate
|
||||
pip install 'lerobot[training]' # Train policies
|
||||
pip install 'lerobot[core_scripts,training]' # Record + train
|
||||
pip install 'lerobot[all]' # Everything
|
||||
```
|
||||
|
||||
**Policy, environment, and hardware extras** are still available for specific dependencies:
|
||||
@@ -206,7 +206,7 @@ pip install 'lerobot[aloha,pusht]' # Simulation environments
|
||||
pip install 'lerobot[feetech]' # Feetech motor support
|
||||
```
|
||||
|
||||
_Multiple extras can be combined (e.g., `.[robot,pi,pusht]`). For a full list of available extras, refer to `pyproject.toml`._
|
||||
_Multiple extras can be combined (e.g., `.[core_scripts,pi,pusht]`). For a full list of available extras, refer to `pyproject.toml`._
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ build = [
|
||||
|
||||
# ── User-facing composite extras (map to CLI scripts) ─────
|
||||
# lerobot-record, lerobot-replay, lerobot-calibrate, lerobot-teleoperate, etc.
|
||||
robot = ["lerobot[dataset]", "lerobot[hardware]", "lerobot[viz]"]
|
||||
core_scripts = ["lerobot[dataset]", "lerobot[hardware]", "lerobot[viz]"]
|
||||
# lerobot-eval -- base evaluation framework. You also need the policy's extra (e.g., lerobot[pi])
|
||||
# and the environment's extra (e.g., lerobot[pusht]) if evaluating in simulation.
|
||||
evaluation = ["lerobot[av-dep]"]
|
||||
|
||||
@@ -24,11 +24,11 @@ model and dataset sharing.
|
||||
The base install is intentionally lightweight. Feature-specific dependencies
|
||||
are gated behind optional extras::
|
||||
|
||||
pip install 'lerobot[dataset]' # dataset loading & creation
|
||||
pip install 'lerobot[training]' # training loop + wandb
|
||||
pip install 'lerobot[hardware]' # real robot control
|
||||
pip install 'lerobot[robot]' # dataset + hardware + viz (recording)
|
||||
pip install 'lerobot[all]' # everything
|
||||
pip install 'lerobot[dataset]' # dataset loading & creation
|
||||
pip install 'lerobot[training]' # training loop + wandb
|
||||
pip install 'lerobot[hardware]' # real robot control
|
||||
pip install 'lerobot[core_scripts]' # dataset + hardware + viz (record, replay, calibrate, etc.)
|
||||
pip install 'lerobot[all]' # everything
|
||||
"""
|
||||
|
||||
from lerobot.__version__ import __version__
|
||||
|
||||
@@ -13,11 +13,10 @@
|
||||
# limitations under the License.
|
||||
|
||||
# NOTE: gymnasium is currently a core dependency but is a candidate for moving to an
|
||||
# optional extra in the future. This guard is here to ensure a clear error message
|
||||
# if/when that transition happens.
|
||||
from lerobot.utils.import_utils import require_package
|
||||
|
||||
require_package("gymnasium", extra="evaluation", import_name="gymnasium")
|
||||
# optional extra in the future. When that transition happens, uncomment the guard below
|
||||
# and update the extra name to the one that will contain gymnasium.
|
||||
# from lerobot.utils.import_utils import require_package
|
||||
# require_package("gymnasium", extra="<update_extra>", import_name="gymnasium")
|
||||
|
||||
from .configs import AlohaEnv, EnvConfig, HILSerlRobotEnvConfig, HubEnvConfig, PushtEnv
|
||||
from .factory import make_env, make_env_config, make_env_pre_post_processors
|
||||
|
||||
@@ -90,21 +90,6 @@ class TorqueMode(Enum):
|
||||
DISABLED = 0
|
||||
|
||||
|
||||
def _split_into_byte_chunks(value: int, length: int) -> list[int]:
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [dxl.DXL_LOBYTE(value), dxl.DXL_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
dxl.DXL_LOBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_LOBYTE(dxl.DXL_HIWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
class DynamixelMotorsBus(SerialMotorsBus):
|
||||
"""
|
||||
The Dynamixel implementation for a MotorsBus. It relies on the python dynamixel sdk to communicate with
|
||||
@@ -249,7 +234,18 @@ class DynamixelMotorsBus(SerialMotorsBus):
|
||||
return half_turn_homings
|
||||
|
||||
def _split_into_byte_chunks(self, value: int, length: int) -> list[int]:
|
||||
return _split_into_byte_chunks(value, length)
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [dxl.DXL_LOBYTE(value), dxl.DXL_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
dxl.DXL_LOBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_LOBYTE(dxl.DXL_HIWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
def broadcast_ping(self, num_retry: int = 0, raise_on_error: bool = False) -> dict[int, int] | None:
|
||||
for n_try in range(1 + num_retry):
|
||||
|
||||
@@ -73,21 +73,6 @@ class TorqueMode(Enum):
|
||||
DISABLED = 0
|
||||
|
||||
|
||||
def _split_into_byte_chunks(value: int, length: int) -> list[int]:
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [scs.SCS_LOBYTE(value), scs.SCS_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
scs.SCS_LOBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_LOBYTE(scs.SCS_HIWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
def patch_setPacketTimeout(self, packet_length): # noqa: N802
|
||||
"""
|
||||
HACK: This patches the PortHandler behavior to set the correct packet timeouts.
|
||||
@@ -332,7 +317,18 @@ class FeetechMotorsBus(SerialMotorsBus):
|
||||
return ids_values
|
||||
|
||||
def _split_into_byte_chunks(self, value: int, length: int) -> list[int]:
|
||||
return _split_into_byte_chunks(value, length)
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [scs.SCS_LOBYTE(value), scs.SCS_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
scs.SCS_LOBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_LOBYTE(scs.SCS_HIWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
def _broadcast_ping(self) -> tuple[dict[int, int], int]:
|
||||
data_list: dict[int, int] = {}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"""
|
||||
Helper to recalibrate your device (robot or teleoperator).
|
||||
|
||||
Requires: pip install 'lerobot[hardware]'
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# limitations under the License.
|
||||
""" Visualize data of **all** frames of any episode of a dataset of type LeRobotDataset.
|
||||
|
||||
Requires: pip install 'lerobot[dataset_viz]' (includes dataset + viz extras)
|
||||
|
||||
Note: The last frame of the episode doesn't always correspond to a final state.
|
||||
That's because our datasets are composed of transition from state to state up to
|
||||
the antepenultimate state associated to the ultimate action to arrive in the final state.
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
"""
|
||||
Edit LeRobot datasets using various transformation tools.
|
||||
|
||||
Requires: pip install 'lerobot[dataset]'
|
||||
|
||||
This script allows you to delete episodes, split datasets, merge datasets,
|
||||
remove features, modify tasks, recompute stats, and convert image datasets to video format.
|
||||
When new_repo_id is specified, creates a new dataset.
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
# limitations under the License.
|
||||
"""Evaluate a policy on an environment by running rollouts and computing metrics.
|
||||
|
||||
Requires: pip install 'lerobot[evaluation]' plus the policy extra (e.g. lerobot[pi])
|
||||
and the environment extra (e.g. lerobot[pusht]) if evaluating in simulation.
|
||||
|
||||
Usage examples:
|
||||
|
||||
You want to evaluate a model from the hub (eg: https://huggingface.co/lerobot/diffusion_pusht)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"""
|
||||
Records a dataset. Actions for the robot can be either generated by teleoperation or by a policy.
|
||||
|
||||
Requires: pip install 'lerobot[core_scripts]' (includes dataset + hardware + viz extras)
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"""
|
||||
Replays the actions of an episode from a dataset on a robot.
|
||||
|
||||
Requires: pip install 'lerobot[core_scripts]' (includes dataset + hardware + viz extras)
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"""
|
||||
Simple script to control a robot from teleoperation.
|
||||
|
||||
Requires: pip install 'lerobot[hardware]'
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
# 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.
|
||||
"""Train a policy.
|
||||
|
||||
Requires: pip install 'lerobot[training]' (includes dataset + accelerate + wandb extras)
|
||||
"""
|
||||
|
||||
import dataclasses
|
||||
import logging
|
||||
import time
|
||||
|
||||
@@ -21,10 +21,25 @@ import dynamixel_sdk as dxl
|
||||
import serial
|
||||
from mock_serial.mock_serial import MockSerial
|
||||
|
||||
from lerobot.motors.dynamixel.dynamixel import _split_into_byte_chunks
|
||||
|
||||
from .mock_serial_patch import WaitableStub
|
||||
|
||||
|
||||
def _split_into_byte_chunks(value: int, length: int) -> list[int]:
|
||||
"""Split an integer into a list of byte-sized integers (little-endian)."""
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [dxl.DXL_LOBYTE(value), dxl.DXL_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
dxl.DXL_LOBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_LOWORD(value)),
|
||||
dxl.DXL_LOBYTE(dxl.DXL_HIWORD(value)),
|
||||
dxl.DXL_HIBYTE(dxl.DXL_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
# https://emanual.robotis.com/docs/en/dxl/crc/
|
||||
DXL_CRC_TABLE = [
|
||||
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
|
||||
|
||||
@@ -21,11 +21,27 @@ import scservo_sdk as scs
|
||||
import serial
|
||||
from mock_serial import MockSerial
|
||||
|
||||
from lerobot.motors.feetech.feetech import _split_into_byte_chunks, patch_setPacketTimeout
|
||||
from lerobot.motors.feetech.feetech import patch_setPacketTimeout
|
||||
|
||||
from .mock_serial_patch import WaitableStub
|
||||
|
||||
|
||||
def _split_into_byte_chunks(value: int, length: int) -> list[int]:
|
||||
"""Split an integer into a list of byte-sized integers (little-endian)."""
|
||||
if length == 1:
|
||||
data = [value]
|
||||
elif length == 2:
|
||||
data = [scs.SCS_LOBYTE(value), scs.SCS_HIBYTE(value)]
|
||||
elif length == 4:
|
||||
data = [
|
||||
scs.SCS_LOBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_LOWORD(value)),
|
||||
scs.SCS_LOBYTE(scs.SCS_HIWORD(value)),
|
||||
scs.SCS_HIBYTE(scs.SCS_HIWORD(value)),
|
||||
]
|
||||
return data
|
||||
|
||||
|
||||
class MockFeetechPacket(abc.ABC):
|
||||
@classmethod
|
||||
def build(cls, scs_id: int, params: list[int], length: int, *args, **kwargs) -> bytes:
|
||||
|
||||
@@ -2304,6 +2304,18 @@ build = [
|
||||
can-dep = [
|
||||
{ name = "python-can" },
|
||||
]
|
||||
core-scripts = [
|
||||
{ name = "av" },
|
||||
{ name = "datasets" },
|
||||
{ name = "deepdiff" },
|
||||
{ name = "jsonlines" },
|
||||
{ name = "pandas" },
|
||||
{ name = "pyarrow" },
|
||||
{ name = "pynput" },
|
||||
{ name = "pyserial" },
|
||||
{ name = "rerun-sdk" },
|
||||
{ name = "torchcodec", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux') or (platform_machine != 'x86_64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
|
||||
]
|
||||
damiao = [
|
||||
{ name = "python-can" },
|
||||
]
|
||||
@@ -2477,18 +2489,6 @@ qwen-vl-utils-dep = [
|
||||
reachy2 = [
|
||||
{ name = "reachy2-sdk" },
|
||||
]
|
||||
robot = [
|
||||
{ name = "av" },
|
||||
{ name = "datasets" },
|
||||
{ name = "deepdiff" },
|
||||
{ name = "jsonlines" },
|
||||
{ name = "pandas" },
|
||||
{ name = "pyarrow" },
|
||||
{ name = "pynput" },
|
||||
{ name = "pyserial" },
|
||||
{ name = "rerun-sdk" },
|
||||
{ name = "torchcodec", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux') or (platform_machine != 'x86_64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
|
||||
]
|
||||
robstride = [
|
||||
{ name = "python-can" },
|
||||
]
|
||||
@@ -2607,12 +2607,12 @@ requires-dist = [
|
||||
{ name = "lerobot", extras = ["damiao"], marker = "extra == 'openarms'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'aloha'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'core-scripts'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'dataset-viz'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'dev'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'libero'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'metaworld'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'pusht'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'robot'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'test'" },
|
||||
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'training'" },
|
||||
{ name = "lerobot", extras = ["dev"], marker = "extra == 'all'" },
|
||||
@@ -2628,8 +2628,8 @@ requires-dist = [
|
||||
{ name = "lerobot", extras = ["grpcio-dep"], marker = "extra == 'dev'" },
|
||||
{ name = "lerobot", extras = ["grpcio-dep"], marker = "extra == 'hilserl'" },
|
||||
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'core-scripts'" },
|
||||
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'dev'" },
|
||||
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'robot'" },
|
||||
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'test'" },
|
||||
{ name = "lerobot", extras = ["hilserl"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["hopejr"], marker = "extra == 'all'" },
|
||||
@@ -2680,9 +2680,9 @@ requires-dist = [
|
||||
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'xvla'" },
|
||||
{ name = "lerobot", extras = ["video-benchmark"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'core-scripts'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'dataset-viz'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'dev'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'robot'" },
|
||||
{ name = "lerobot", extras = ["viz"], marker = "extra == 'test'" },
|
||||
{ name = "lerobot", extras = ["wallx"], marker = "extra == 'all'" },
|
||||
{ name = "lerobot", extras = ["xvla"], marker = "extra == 'all'" },
|
||||
@@ -2740,7 +2740,7 @@ requires-dist = [
|
||||
{ name = "transformers", marker = "extra == 'transformers-dep'", specifier = "==5.3.0" },
|
||||
{ name = "wandb", marker = "extra == 'training'", specifier = ">=0.24.0,<0.25.0" },
|
||||
]
|
||||
provides-extras = ["dataset", "training", "hardware", "viz", "build", "robot", "evaluation", "dataset-viz", "av-dep", "pygame-dep", "placo-dep", "transformers-dep", "grpcio-dep", "can-dep", "peft-dep", "scipy-dep", "diffusers-dep", "qwen-vl-utils-dep", "matplotlib-dep", "feetech", "dynamixel", "damiao", "robstride", "openarms", "gamepad", "hopejr", "lekiwi", "unitree-g1", "reachy2", "kinematics", "intelrealsense", "phone", "diffusion", "wallx", "pi", "smolvla", "multi-task-dit", "groot", "sarm", "xvla", "hilserl", "async", "peft", "dev", "test", "video-benchmark", "aloha", "pusht", "libero", "metaworld", "all"]
|
||||
provides-extras = ["dataset", "training", "hardware", "viz", "build", "core-scripts", "evaluation", "dataset-viz", "av-dep", "pygame-dep", "placo-dep", "transformers-dep", "grpcio-dep", "can-dep", "peft-dep", "scipy-dep", "diffusers-dep", "qwen-vl-utils-dep", "matplotlib-dep", "feetech", "dynamixel", "damiao", "robstride", "openarms", "gamepad", "hopejr", "lekiwi", "unitree-g1", "reachy2", "kinematics", "intelrealsense", "phone", "diffusion", "wallx", "pi", "smolvla", "multi-task-dit", "groot", "sarm", "xvla", "hilserl", "async", "peft", "dev", "test", "video-benchmark", "aloha", "pusht", "libero", "metaworld", "all"]
|
||||
|
||||
[[package]]
|
||||
name = "librt"
|
||||
|
||||
Reference in New Issue
Block a user