Back to Lerobot

🤗 LeRobot Quickstart

examples/notebooks/quickstart.ipynb

0.6.06.9 KB
Original Source

🤗 LeRobot Quickstart

Calibration → teleoperation → data collection → training → evaluation.

Install the required dependencies: pip install -e .[notebook,dataset,training,viz,hardware].

How to use:

  1. Edit the Configuration cell with your settings.
  2. Run all cells (Run All).
  3. Each section prints a ready-to-paste terminal command - copy it and run it.

Each setup is different, please refer to the LeRobot documentation for more details on each step and available options.

Feel free to make this notebook your own and adapt it to your needs!


Utils

python
def _cameras_arg(cameras: dict) -> str:
    if not cameras:
        return ""
    entries = [f"{n}: {{{', '.join(f'{k}: {v}' for k, v in cfg.items())}}}" for n, cfg in cameras.items()]
    return "{ " + ", ".join(entries) + " }"


def print_cmd(*parts: str) -> None:
    """Print a shell command with line continuations, skipping empty parts."""
    non_empty = [p for p in parts if p]
    print(" \\\n    ".join(non_empty))

Configuration

Edit this cell, then Run All to generate all commands below.

python
# Robot (follower) - run `lerobot-find-port` to discover the port
ROBOT_TYPE = "so101_follower"
ROBOT_PORT = "/dev/ttyACM0"
ROBOT_ID = "my_follower_arm"

# Teleop (leader) - run `lerobot-find-port` to discover the port
TELEOP_TYPE = "so101_leader"
TELEOP_PORT = "/dev/ttyACM1"
TELEOP_ID = "my_leader_arm"

# Cameras - set to {} to disable
# Run `lerobot-find-cameras opencv` to list available cameras and their indices
CAMERAS = {
    "top": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30},
    "wrist": {"type": "opencv", "index_or_path": 4, "width": 640, "height": 480, "fps": 30},
}

# Dataset
HF_USER = "your_hf_username"  # `hf auth whoami` to find your username
DATASET_NAME = "my_so101_dataset"
TASK_DESCRIPTION = "pick and place the block"
NUM_EPISODES = 10

# Training
POLICY_TYPE = "act"  # act, diffusion, smolvla, ...
POLICY_DEVICE = "cuda"  # cuda / cpu / mps
TRAIN_STEPS = 10_000
SAVE_FREQ = 2_000
OUTPUT_DIR = f"outputs/train/{DATASET_NAME}"

# Inference - Hub repo ID or local checkpoint path
# e.g. set to f"{OUTPUT_DIR}/checkpoints/last" to use a local checkpoint
POLICY_PATH = f"{HF_USER}/{DATASET_NAME}_{POLICY_TYPE}"
LAST_CHECKPOINT_PATH = f"{OUTPUT_DIR}/checkpoints/last"

# Derived
DATASET_REPO_ID = f"{HF_USER}/{DATASET_NAME}"
DATASET_ROOT = f"data/{DATASET_NAME}"
POLICY_REPO_ID = f"{HF_USER}/{DATASET_NAME}_{POLICY_TYPE}"
EVAL_REPO_ID = f"{HF_USER}/eval_{DATASET_NAME}"
CAMERAS_ARG = _cameras_arg(CAMERAS)
CAMERAS_FLAG = f'--robot.cameras="{CAMERAS_ARG}"' if CAMERAS_ARG else ""

print(f"Robot  : {ROBOT_TYPE} @ {ROBOT_PORT}")
print(f"Teleop : {TELEOP_TYPE} @ {TELEOP_PORT}")
print(f"Cameras: {list(CAMERAS) or 'none'}")
print(f"Dataset: {DATASET_REPO_ID} ({NUM_EPISODES} episodes) saved to {DATASET_ROOT}")
print(f"Policy : {POLICY_TYPE} -> {POLICY_REPO_ID}")

1. Calibration

Run once per arm before first use.

python
# Follower
print_cmd(
    "lerobot-calibrate",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    f"--robot.id={ROBOT_ID}",
)
python
# Leader
print_cmd(
    "lerobot-calibrate",
    f"--teleop.type={TELEOP_TYPE}",
    f"--teleop.port={TELEOP_PORT}",
    f"--teleop.id={TELEOP_ID}",
)

2. Teleoperation

See the teleoperation docs and the cameras guide for more options.

python
print_cmd(
    "lerobot-teleoperate",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    f"--robot.id={ROBOT_ID}",
    CAMERAS_FLAG,
    f"--teleop.type={TELEOP_TYPE}",
    f"--teleop.port={TELEOP_PORT}",
    f"--teleop.id={TELEOP_ID}",
    "--display_data=true",
)

3. Record Dataset

See the recording docs for tips on gathering good data.

python
print_cmd(
    "lerobot-record",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    f"--robot.id={ROBOT_ID}",
    CAMERAS_FLAG,
    f"--teleop.type={TELEOP_TYPE}",
    f"--teleop.port={TELEOP_PORT}",
    f"--teleop.id={TELEOP_ID}",
    f"--dataset.repo_id={DATASET_REPO_ID}",
    f"--dataset.num_episodes={NUM_EPISODES}",
    f'--dataset.single_task="{TASK_DESCRIPTION}"',
    "--dataset.streaming_encoding=true",
    "--display_data=true",
)
python
# Resume a previously interrupted recording session
print_cmd(
    "lerobot-record",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    f"--robot.id={ROBOT_ID}",
    CAMERAS_FLAG,
    f"--teleop.type={TELEOP_TYPE}",
    f"--teleop.port={TELEOP_PORT}",
    f"--teleop.id={TELEOP_ID}",
    f"--dataset.repo_id={DATASET_REPO_ID}",
    f"--dataset.root={DATASET_ROOT}",
    f"--dataset.num_episodes={NUM_EPISODES}",
    f'--dataset.single_task="{TASK_DESCRIPTION}"',
    "--dataset.streaming_encoding=true",
    "--display_data=true",
    "--resume=true",
)

4. Train Policy

See the training docs for configuration options and tips.

python
print_cmd(
    "lerobot-train",
    f"--dataset.repo_id={DATASET_REPO_ID}",
    f"--policy.type={POLICY_TYPE}",
    f"--policy.device={POLICY_DEVICE}",
    f"--policy.repo_id={POLICY_REPO_ID}",
    f"--output_dir={OUTPUT_DIR}",
    f"--steps={TRAIN_STEPS}",
    f"--save_freq={SAVE_FREQ}",
)
python
# Resume a previously interrupted training session
print_cmd(
    "lerobot-train",
    f"--config_path={LAST_CHECKPOINT_PATH}/pretrained_model/train_config.json",
    "--resume=true",
)

5. Inference

Uses POLICY_PATH from the Configuration cell (defaults to the Hub repo ID). You can also put there the LAST_CHECKPOINT_PATH.

See the inference docs for details.

Recently lerobot-rollout was introduced, you can read more about it here.

python
print_cmd(
    "lerobot-rollout",
    "--strategy.type=base",
    f"--policy.path={POLICY_PATH}",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    CAMERAS_FLAG,
    f'--task="{TASK_DESCRIPTION}"',
    "--duration=60",
)

if you are using the V0.5.1 release you should use lerobot-record instead of rollout

python
print_cmd(
    "lerobot-record",
    f"--policy.path={POLICY_PATH}",
    f"--robot.type={ROBOT_TYPE}",
    f"--robot.port={ROBOT_PORT}",
    f"--robot.id={ROBOT_ID}",
    CAMERAS_FLAG,
    f"--teleop.type={TELEOP_TYPE}",
    f"--teleop.port={TELEOP_PORT}",
    f"--teleop.id={TELEOP_ID}",
    f"--dataset.repo_id={EVAL_REPO_ID}",
    f"--dataset.num_episodes={NUM_EPISODES}",
    f'--dataset.single_task="{TASK_DESCRIPTION}"',
    "--dataset.streaming_encoding=true",
)