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"> <hfoptions id="install_lerobot_src">
<hfoption id="conda"> <hfoption id="conda">
```bash ```bash
pip install -e ".[robot]" # For real robot workflows (recording, replaying) pip install -e ".[core_scripts]" # For robot workflows (recording, replaying, calibrate)
pip install -e ".[training]" # For training policies pip install -e ".[training]" # For training policies
pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools) pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
``` ```
</hfoption> </hfoption>
<hfoption id="uv"> <hfoption id="uv">
```bash ```bash
uv pip install -e ".[robot]" # For real robot workflows (recording, replaying) uv pip install -e ".[core_scripts]" # For robot workflows (recording, replaying, calibrate)
uv pip install -e ".[training]" # For training policies uv pip install -e ".[training]" # For training policies
uv pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools) uv pip install -e ".[all]" # Everything (all policies, envs, hardware, dev tools)
``` ```
</hfoption> </hfoption>
</hfoptions> </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: **Composite Extras** combine feature extras for common CLI scripts:
| Extra | Includes | Typical use case | | Extra | Includes | Typical use case |
| ------------- | ------------------------------ | ------------------------------------------------------- | | -------------- | ------------------------------ | ------------------------------------------------------- |
| `robot` | `dataset` + `hardware` + `viz` | `lerobot-record`, `lerobot-replay`, `lerobot-calibrate` | | `core_scripts` | `dataset` + `hardware` + `viz` | `lerobot-record`, `lerobot-replay`, `lerobot-calibrate` |
| `evaluation` | `av` | `lerobot-eval` (add policy + env extras as needed) | | `evaluation` | `av` | `lerobot-eval` (add policy + env extras as needed) |
| `dataset_viz` | `dataset` + `viz` | `lerobot-dataset-viz`, `lerobot-imgtransform-viz` | | `dataset_viz` | `dataset` + `viz` | `lerobot-dataset-viz`, `lerobot-imgtransform-viz` |
```bash ```bash
pip install 'lerobot[robot]' # Record, replay, calibrate pip install 'lerobot[core_scripts]' # Record, replay, calibrate
pip install 'lerobot[training]' # Train policies pip install 'lerobot[training]' # Train policies
pip install 'lerobot[robot,training]' # Record + train pip install 'lerobot[core_scripts,training]' # Record + train
pip install 'lerobot[all]' # Everything pip install 'lerobot[all]' # Everything
``` ```
**Policy, environment, and hardware extras** are still available for specific dependencies: **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 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 ### Troubleshooting
+1 -1
View File
@@ -118,7 +118,7 @@ build = [
# ── User-facing composite extras (map to CLI scripts) ───── # ── User-facing composite extras (map to CLI scripts) ─────
# lerobot-record, lerobot-replay, lerobot-calibrate, lerobot-teleoperate, etc. # 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]) # 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. # and the environment's extra (e.g., lerobot[pusht]) if evaluating in simulation.
evaluation = ["lerobot[av-dep]"] 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 The base install is intentionally lightweight. Feature-specific dependencies
are gated behind optional extras:: are gated behind optional extras::
pip install 'lerobot[dataset]' # dataset loading & creation pip install 'lerobot[dataset]' # dataset loading & creation
pip install 'lerobot[training]' # training loop + wandb pip install 'lerobot[training]' # training loop + wandb
pip install 'lerobot[hardware]' # real robot control pip install 'lerobot[hardware]' # real robot control
pip install 'lerobot[robot]' # dataset + hardware + viz (recording) pip install 'lerobot[core_scripts]' # dataset + hardware + viz (record, replay, calibrate, etc.)
pip install 'lerobot[all]' # everything pip install 'lerobot[all]' # everything
""" """
from lerobot.__version__ import __version__ from lerobot.__version__ import __version__
+4 -5
View File
@@ -13,11 +13,10 @@
# limitations under the License. # limitations under the License.
# NOTE: gymnasium is currently a core dependency but is a candidate for moving to an # 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 # optional extra in the future. When that transition happens, uncomment the guard below
# if/when that transition happens. # and update the extra name to the one that will contain gymnasium.
from lerobot.utils.import_utils import require_package # from lerobot.utils.import_utils import require_package
# require_package("gymnasium", extra="<update_extra>", import_name="gymnasium")
require_package("gymnasium", extra="evaluation", import_name="gymnasium")
from .configs import AlohaEnv, EnvConfig, HILSerlRobotEnvConfig, HubEnvConfig, PushtEnv from .configs import AlohaEnv, EnvConfig, HILSerlRobotEnvConfig, HubEnvConfig, PushtEnv
from .factory import make_env, make_env_config, make_env_pre_post_processors 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 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): class DynamixelMotorsBus(SerialMotorsBus):
""" """
The Dynamixel implementation for a MotorsBus. It relies on the python dynamixel sdk to communicate with 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 return half_turn_homings
def _split_into_byte_chunks(self, value: int, length: int) -> list[int]: 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: 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): for n_try in range(1 + num_retry):
+12 -16
View File
@@ -73,21 +73,6 @@ class TorqueMode(Enum):
DISABLED = 0 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 def patch_setPacketTimeout(self, packet_length): # noqa: N802
""" """
HACK: This patches the PortHandler behavior to set the correct packet timeouts. HACK: This patches the PortHandler behavior to set the correct packet timeouts.
@@ -332,7 +317,18 @@ class FeetechMotorsBus(SerialMotorsBus):
return ids_values return ids_values
def _split_into_byte_chunks(self, value: int, length: int) -> list[int]: 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]: def _broadcast_ping(self) -> tuple[dict[int, int], int]:
data_list: dict[int, int] = {} data_list: dict[int, int] = {}
+2
View File
@@ -15,6 +15,8 @@
""" """
Helper to recalibrate your device (robot or teleoperator). Helper to recalibrate your device (robot or teleoperator).
Requires: pip install 'lerobot[hardware]'
Example: Example:
```shell ```shell
@@ -15,6 +15,8 @@
# limitations under the License. # limitations under the License.
""" Visualize data of **all** frames of any episode of a dataset of type LeRobotDataset. """ 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. 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 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. 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. Edit LeRobot datasets using various transformation tools.
Requires: pip install 'lerobot[dataset]'
This script allows you to delete episodes, split datasets, merge datasets, This script allows you to delete episodes, split datasets, merge datasets,
remove features, modify tasks, recompute stats, and convert image datasets to video format. remove features, modify tasks, recompute stats, and convert image datasets to video format.
When new_repo_id is specified, creates a new dataset. When new_repo_id is specified, creates a new dataset.
+3
View File
@@ -15,6 +15,9 @@
# limitations under the License. # limitations under the License.
"""Evaluate a policy on an environment by running rollouts and computing metrics. """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: Usage examples:
You want to evaluate a model from the hub (eg: https://huggingface.co/lerobot/diffusion_pusht) 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. 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: Example:
```shell ```shell
+2
View File
@@ -15,6 +15,8 @@
""" """
Replays the actions of an episode from a dataset on a robot. Replays the actions of an episode from a dataset on a robot.
Requires: pip install 'lerobot[core_scripts]' (includes dataset + hardware + viz extras)
Examples: Examples:
```shell ```shell
@@ -15,6 +15,8 @@
""" """
Simple script to control a robot from teleoperation. Simple script to control a robot from teleoperation.
Requires: pip install 'lerobot[hardware]'
Example: Example:
```shell ```shell
+5
View File
@@ -13,6 +13,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
"""Train a policy.
Requires: pip install 'lerobot[training]' (includes dataset + accelerate + wandb extras)
"""
import dataclasses import dataclasses
import logging import logging
import time import time
+17 -2
View File
@@ -21,10 +21,25 @@ import dynamixel_sdk as dxl
import serial import serial
from mock_serial.mock_serial import MockSerial from mock_serial.mock_serial import MockSerial
from lerobot.motors.dynamixel.dynamixel import _split_into_byte_chunks
from .mock_serial_patch import WaitableStub 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/ # https://emanual.robotis.com/docs/en/dxl/crc/
DXL_CRC_TABLE = [ DXL_CRC_TABLE = [
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
+17 -1
View File
@@ -21,11 +21,27 @@ import scservo_sdk as scs
import serial import serial
from mock_serial import MockSerial 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 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): class MockFeetechPacket(abc.ABC):
@classmethod @classmethod
def build(cls, scs_id: int, params: list[int], length: int, *args, **kwargs) -> bytes: 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 = [ can-dep = [
{ name = "python-can" }, { 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 = [ damiao = [
{ name = "python-can" }, { name = "python-can" },
] ]
@@ -2477,18 +2489,6 @@ qwen-vl-utils-dep = [
reachy2 = [ reachy2 = [
{ name = "reachy2-sdk" }, { 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 = [ robstride = [
{ name = "python-can" }, { name = "python-can" },
] ]
@@ -2607,12 +2607,12 @@ requires-dist = [
{ name = "lerobot", extras = ["damiao"], marker = "extra == 'openarms'" }, { name = "lerobot", extras = ["damiao"], marker = "extra == 'openarms'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'aloha'" }, { 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 == 'dataset-viz'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'dev'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'dev'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'libero'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'libero'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'metaworld'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'metaworld'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'pusht'" }, { 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 == 'test'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'training'" }, { name = "lerobot", extras = ["dataset"], marker = "extra == 'training'" },
{ name = "lerobot", extras = ["dev"], marker = "extra == 'all'" }, { 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 == 'dev'" },
{ name = "lerobot", extras = ["grpcio-dep"], marker = "extra == 'hilserl'" }, { name = "lerobot", extras = ["grpcio-dep"], marker = "extra == 'hilserl'" },
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'all'" }, { 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 == 'dev'" },
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'robot'" },
{ name = "lerobot", extras = ["hardware"], marker = "extra == 'test'" }, { name = "lerobot", extras = ["hardware"], marker = "extra == 'test'" },
{ name = "lerobot", extras = ["hilserl"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["hilserl"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["hopejr"], 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 = ["transformers-dep"], marker = "extra == 'xvla'" },
{ name = "lerobot", extras = ["video-benchmark"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["video-benchmark"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["viz"], 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 == 'dataset-viz'" },
{ name = "lerobot", extras = ["viz"], marker = "extra == 'dev'" }, { name = "lerobot", extras = ["viz"], marker = "extra == 'dev'" },
{ name = "lerobot", extras = ["viz"], marker = "extra == 'robot'" },
{ name = "lerobot", extras = ["viz"], marker = "extra == 'test'" }, { name = "lerobot", extras = ["viz"], marker = "extra == 'test'" },
{ name = "lerobot", extras = ["wallx"], marker = "extra == 'all'" }, { name = "lerobot", extras = ["wallx"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["xvla"], 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 = "transformers", marker = "extra == 'transformers-dep'", specifier = "==5.3.0" },
{ name = "wandb", marker = "extra == 'training'", specifier = ">=0.24.0,<0.25.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]] [[package]]
name = "librt" name = "librt"