address minor review comments

This commit is contained in:
Steven Palma
2026-04-12 11:27:59 +02:00
parent 8ef4d78178
commit 87528186c0
17 changed files with 120 additions and 78 deletions
+16 -16
View File
@@ -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
View File
@@ -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]"]
+5 -5
View File
@@ -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__
+4 -5
View File
@@ -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
+12 -16
View File
@@ -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):
+12 -16
View File
@@ -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] = {}
+2
View File
@@ -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.
+3
View File
@@ -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)
+2
View File
@@ -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
+2
View File
@@ -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
+5
View File
@@ -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
+17 -2
View File
@@ -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,
+17 -1
View File
@@ -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:
Generated
+16 -16
View File
@@ -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"