LeRobot documentation

LeIsaac × LeRobot EnvHub

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

LeIsaac × LeRobot EnvHub

LeRobot EnvHub는 이제 LeIsaac를 통해 시뮬레이션에서의 모방 학습을 지원합니다. 일상적인 조작 작업을 설정하고, 로봇을 텔레오퍼레이션하며, 데모를 수집한 후 Hub에 업로드하고, LeRobot에서 정책을 학습하세요 — 모든 과정을 하나의 루프에서 처리할 수 있습니다.

LeIsaac은 IsaacLab 및 SO101 Leader/Follower 구성과 통합되어 다음을 제공합니다:

  • 🕹️ 데이터 수집을 위한 텔레오퍼레이션 우선 워크플로
  • 📦 LeRobot 학습에 바로 사용할 수 있는 내장 데이터 변환
  • 🤖 오렌지 고르기, 큐브 들어올리기, 테이블 닦기, 천 접기 같은 일상 기술
  • ☁️ LightWheel의 지속적인 업그레이드: 클라우드 시뮬레이션, EnvHub 지원, Sim2Real 도구 및 기타

아래는 LeRobot EnvHub를 통해 노출된 현재 지원되는 LeIsaac 작업 목록입니다.

사용 가능한 환경

다음 표에는 LeIsaac x LeRobot EnvHub에서 사용할 수 있는 모든 작업과 환경이 나열되어 있습니다. 다음 명령을 실행하여 최신 환경 목록을 가져올 수도 있습니다:

python scripts/environments/list_envs.py
작업환경 ID작업 설명관련 로봇
LeIsaac-SO101-PickOrange-v0

LeIsaac-SO101-PickOrange-Direct-v0
오렌지 세 개를 고른 후 접시에 넣고, 팔을 휴식 상태로 리셋합니다.싱글-암 SO101 팔로워
LeIsaac-SO101-LiftCube-v0

LeIsaac-SO101-LiftCube-Direct-v0
…싱글-암 SO101 팔로워
LeIsaac-SO101-CleanToyTable-v0

LeIsaac-SO101-CleanToyTable-BiArm-v0

LeIsaac-SO101-CleanToyTable-BiArm-Direct-v0
letter e 객체 두 개를 상자 안에 넣고, 팔을 휴지 상태로 초기화합니다.단팔 SO101 팔로어

이팔 SO101 팔로어
LeIsaac-SO101-FoldCloth-BiArm-v0

LeIsaac-SO101-FoldCloth-BiArm-Direct-v0
천을 접고, 팔을 휴지 상태로 재설정합니다.

참고: 이 작업에서는 DirectEnv만 check_success를 지원합니다.
Bi-Arm SO101 팔로워

LeIsaac을 LeRobot에서 한 줄의 코드로 직접 로드

EnvHub: HuggingFace를 통해 LeIsaac 환경을 공유

EnvHub는 재현 가능한 환경 허브로, 한 줄로 패키징된 시뮬레이션을 시작하고 즉시 실험하며 커뮤니티를 위해 자체 태스크를 게시할 수 있습니다.

LeIsaac은 EnvHub 지원을 제공하여 몇 가지 명령만으로 작업을 사용하거나 공유할 수 있습니다.

시작 방법, 환경 설정

코드 환경을 설정하려면 다음 명령을 실행하세요:

# Refer to Getting Started/Installation to install leisaac firstly
conda create -n leisaac_envhub python=3.11
conda activate leisaac_envhub

conda install -c "nvidia/label/cuda-12.8.1" cuda-toolkit
pip install -U torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128
pip install 'leisaac[isaaclab] @ git+https://github.com/LightwheelAI/leisaac.git#subdirectory=source/leisaac' --extra-index-url https://pypi.nvidia.com

# Install lerobot
pip install lerobot==0.4.1

# Fix numpy version
pip install numpy==1.26.0

사용 예시

EnvHub은 LeIsaac이 지원하는 모든 작업을 일관된 인터페이스로 제공합니다. 아래 예제는 so101_pick_orange를 로드하여 랜덤 액션 롤아웃과 인터랙티브 텔레오페이션을 시연합니다.

무작위 동작

Click to expand code example
# envhub_random_action.py

import torch
from lerobot.envs import make_env

# Load from the hub
envs_dict = make_env("LightwheelAI/leisaac_env:envs/so101_pick_orange.py", n_envs=1, trust_remote_code=True)

# Access the environment
suite_name = next(iter(envs_dict))
sync_vector_env = envs_dict[suite_name][0]
# retrieve the isaac environment from the sync vector env
env = sync_vector_env.envs[0].unwrapped

# Use it like any gym environment
obs, info = env.reset()

while True:
    action = torch.tensor(env.action_space.sample())
    obs, reward, terminated, truncated, info = env.step(action)
    if terminated or truncated:
        obs, info = env.reset()

env.close()
python envhub_random_action.py

순수하게 무작위된 명령으로 SO101 팔이 흔들리는 것을 확인해야 합니다.

원격 조작

LeRobot의 텔레오퍼레이션 스택은 시뮬레이션된 팔을 구동할 수 있습니다.

SO101 리더 컨트롤러를 연결하고 아래 보정 명령을 실행하세요.

lerobot-calibrate \
    --teleop.type=so101_leader \
    --teleop.port=/dev/ttyACM0 \
    --teleop.id=leader

그리고 teleop 스크립트를 실행합니다.

Click to expand code example
# envhub_teleop_example.py

import logging
import time
import gymnasium as gym

from dataclasses import asdict, dataclass
from pprint import pformat

from lerobot.teleoperators import (  # noqa: F401
    Teleoperator,
    TeleoperatorConfig,
    make_teleoperator_from_config,
    so_leader,
    bi_so_leader,
)
from lerobot.utils.robot_utils import precise_sleep
from lerobot.utils.utils import init_logging
from lerobot.envs import make_env


@dataclass
class TeleoperateConfig:
    teleop: TeleoperatorConfig
    env_name: str = "so101_pick_orange"
    fps: int = 60


@dataclass
class EnvWrap:
    env: gym.Env


def make_env_from_leisaac(env_name: str = "so101_pick_orange"):
    envs_dict = make_env(
        f'LightwheelAI/leisaac_env:envs/{env_name}.py',
        n_envs=1,
        trust_remote_code=True
    )
    suite_name = next(iter(envs_dict))
    sync_vector_env = envs_dict[suite_name][0]
    env = sync_vector_env.envs[0].unwrapped

    return env


def teleop_loop(teleop: Teleoperator, env: gym.Env, fps: int):
    from leisaac.devices.action_process import preprocess_device_action
    from leisaac.assets.robots.lerobot import SO101_FOLLOWER_MOTOR_LIMITS
    from leisaac.utils.env_utils import dynamic_reset_gripper_effort_limit_sim

    env_wrap = EnvWrap(env=env)

    obs, info = env.reset()
    while True:
        loop_start = time.perf_counter()
        if env.cfg.dynamic_reset_gripper_effort_limit:
            dynamic_reset_gripper_effort_limit_sim(env, 'so101leader')

        raw_action = teleop.get_action()
        processed_action = preprocess_device_action(
            dict(
                so101_leader=True,
                joint_state={
                    k.removesuffix(".pos"): v for k, v in raw_action.items()},
                motor_limits=SO101_FOLLOWER_MOTOR_LIMITS),
            env_wrap
        )
        obs, reward, terminated, truncated, info = env.step(processed_action)
        if terminated or truncated:
            obs, info = env.reset()

        dt_s = time.perf_counter() - loop_start
        precise_sleep(max(1 / fps - dt_s, 0.0))
        loop_s = time.perf_counter() - loop_start
        print(f"\ntime: {loop_s * 1e3:.2f}ms ({1 / loop_s:.0f} Hz)")


def teleoperate(cfg: TeleoperateConfig):
    init_logging()
    logging.info(pformat(asdict(cfg)))

    teleop = make_teleoperator_from_config(cfg.teleop)
    env = make_env_from_leisaac(cfg.env_name)

    teleop.connect()
    if hasattr(env, 'initialize'):
        env.initialize()
    try:
        teleop_loop(teleop=teleop, env=env, fps=cfg.fps)
    except KeyboardInterrupt:
        pass
    finally:
        teleop.disconnect()
        env.close()


def main():
    teleoperate(TeleoperateConfig(
        teleop=so_leader.SO101LeaderConfig(
            port="/dev/ttyACM0",
            id='leader',
            use_degrees=False,
        ),
        env_name="so101_pick_orange",
        fps=60,
    ))


if __name__ == "__main__":
    main()
python envhub_teleop_example.py

스크립트를 실행하면 물리적 Leader 기기를 사용하여 시뮬레이션된 팔을 조작할 수 있습니다.

☁️ 클라우드 시뮬레이션 (GPU 불필요)

로컬 GPU나 올바른 드라이버가 없으신가요? 걱정 마세요! LeIsaac을 설정 과정 없이 클라우드에서 완전히 실행할 수 있습니다. LeIsaac은 NVIDIA Brev에서 바로 작동하며, 브라우저에서 완전히 구성된 환경을 제공합니다.

👉 여기서 시작하세요: https://lightwheelai.github.io/leisaac/docs/cloud_simulation/nvidia_brev

인스턴스가 배포되면 포트 80 (HTTP) 링크를 열기만 하면 Visual Studio Code Server가 시작됩니다(기본 비밀번호: password). 여기서 시뮬레이션을 실행하고, 코드를 편집하고, IsaacLab 환경을 시각화할 수 있으며, 모든 작업을 웹 브라우저에서 수행할 수 있습니다.

GPU, 드라이버, 로컬 설치 불필요. 클릭만 하면 실행됩니다.

추가 참고 사항

EnvHub의 커버리지를 LeIsaac 작업과 일치하도록 유지합니다. 현재 지원되는 항목:

  • so101_pick_orange
  • so101_lift_cube
  • so101_clean_toytable
  • bi_so101_fold_cloth

make_env를 호출할 때 다른 스크립트를 대상으로 지정하여 작업을 전환할 수 있습니다. 예를 들어:

envs_dict_pick_orange = make_env("LightwheelAI/leisaac_env:envs/so101_pick_orange.py", n_envs=1, trust_remote_code=True)
envs_dict_lift_cube = make_env("LightwheelAI/leisaac_env:envs/so101_lift_cube.py", n_envs=1, trust_remote_code=True)
envs_dict_clean_toytable = make_env("LightwheelAI/leisaac_env:envs/so101_clean_toytable.py", n_envs=1, trust_remote_code=True)
envs_dict_fold_cloth = make_env("LightwheelAI/leisaac_env:envs/bi_so101_fold_cloth.py", n_envs=1, trust_remote_code=True)

참고: bi_so101_fold_cloth를 다룰 때는 다른 작업을 수행하기 전에 env를 가져온 직후 initialize()를 호출하세요:

Click to expand code example
import torch
from lerobot.envs import make_env

# Load from the hub
envs_dict = make_env("LightwheelAI/leisaac_env:envs/bi_so101_fold_cloth.py", n_envs=1, trust_remote_code=True)

# Access the environment
suite_name = next(iter(envs_dict))
sync_vector_env = envs_dict[suite_name][0]
# retrieve the isaac environment from the sync vector env
env = sync_vector_env.envs[0].unwrapped

# NOTE: initialize() first
env.initialize()

# other operation with env...
Update on GitHub