# LeIsaac × LeRobot EnvHub

LeRobot EnvHubは現在、LeIsaacによる**シミュレーションでの模倣学習**に対応しています。日常的な操作タスクを起動し、ロボットをテレオペレーションしてデモを収集し、Hubにプッシュし、LeRobotでポリシーを学習します。すべてを1つのループで実行できます。

[LeIsaac](https://github.com/LightwheelAI/leisaac)はIsaacLabおよびSO101 Leader/Follower構成と統合されており、以下を提供します：

- 🕹️ データ収集のための**テレオペレーション優先ワークフロー**
- 📦 LeRobotの学習に備えた**組み込みデータ変換**
- 🤖 オレンジの収穫、立方体の持ち上げ、テーブルの清掃、布の折りたたみなどの**日常のスキル**
- ☁️ [LightWheel](https://lightwheel.ai/)による**継続的なアップグレード**：クラウドシミュレーション、EnvHubのサポート、Sim2Realツール、その他

以下に、LeRobot EnvHub 経由で公開されている現在サポートされている LeIsaac タスクを掲載しています。

# 利用可能な環境

LeIsaac x LeRobot EnvHub で利用可能なすべてのタスクと環境を、以下の表に示します。また、以下のコマンドを実行することで、最新の環境のリストを取得できます。

```bash
python scripts/environments/list_envs.py
```

| タスク                                                                                                                                                            | 環境ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | タスクの説明                                                                                                           | 関連するRobot                                              |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- |
|  | [LeIsaac-SO101-PickOrange-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/pick_orange/pick_orange_env_cfg.py)[LeIsaac-SO101-PickOrange-Direct-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/pick_orange/direct/pick_orange_env.py)                                                                                                                                                                                                                        | オレンジを3個選んで皿に置き、その後アームをレスト状態にリセットします。                                          | Single-Arm SO101 Follower                                  |
|  | [LeIsaac-SO101-LiftCube-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/lift_cube/lift_cube_env_cfg.py)[LeIsaac-SO101-LiftCube-Direct-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/lift_cube/direct/lift_cube_env.py)                                                                                                                                                                                                                                    | 赤い立方体を上に持ち上げてください。                                                                                                      | Single-Arm SO101 Follower                                  |
|  | [LeIsaac-SO101-CleanToyTable-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/clean_toy_table/clean_toy_table_env_cfg.py)[LeIsaac-SO101-CleanToyTable-BiArm-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/clean_toy_table/clean_toy_table_bi_arm_env_cfg.py)[LeIsaac-SO101-CleanToyTable-BiArm-Direct-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/clean_toy_table/direct/clean_toy_table_bi_arm_env.py) | boxに、文字eのオブジェクトを2つ入れ、アームをレスト状態にリセットします。                                                   | Single-Arm SO101 FollowerBi-Arm SO101 Follower |
|  | [LeIsaac-SO101-FoldCloth-BiArm-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/fold_cloth/fold_cloth_bi_arm_env_cfg.py)[LeIsaac-SO101-FoldCloth-BiArm-Direct-v0](https://github.com/LightwheelAI/leisaac/blob/main/source/leisaac/leisaac/tasks/fold_cloth/direct/fold_cloth_bi_arm_env.py)                                                                                                                                                                                                    | 布を折り、アームをレスト状態にリセットします。注: このタスクでは、DirectEnvのみcheck_successをサポートしています。 | Bi-Arm SO101 Follower                                      |

# LeIsaacをLeRobotに1行のコードで直接読み込む

> EnvHub: HuggingFaceを通じてLeIsaac環境を共有

[EnvHub](https://huggingface.co/docs/lerobot/envhub)は、再現可能な環境のハブです。1行でパッケージ化されたシミュレーションを起動し、すぐに実験を開始できます。また、コミュニティ向けに独自のタスクを公開することも可能です。

LeIsaacはEnvHubをサポートしており、数コマンドでタスクを消費したり共有したりできます。

<video
  controls
  src="https://github.com/user-attachments/assets/687666f5-ebe0-421d-84a0-eb86116ac5f8"
  style={{ width: "100%", maxWidth: "960px", borderRadius: "8px" }}
/>

## はじめる方法、環境のセットアップ

以下のコマンドを実行して、コード環境を設定します。

```bash
# 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`を読み込み、ランダムなアクションによるロールアウトとインタラクティブなテレオペレーションをデモしています。

### ランダムアクション

クリックしてコード例を展開

```python
# 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()
```

```bash
python envhub_random_action.py
```

純粋にランダムなコマンドによってSO101アームが振動しているのが確認できるはずです。

### テレオペレーション

LeRobotのテレオペレーションスタックは、シミュレートされたアームを駆動できます。

SO101 Leaderコントローラーを接続し、以下のキャリブレーションコマンドを実行してください。

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

その後、テレオペスクリプトを起動します。

クリックしてコード例を展開

```python
# 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()

```

```bash
python envhub_teleop_example.py
```

スクリプトを実行すると、物理的なLeaderデバイスを使用してシミュレートされたアームを操作できます。

## ☁️ クラウドシミュレーション（GPU不要）

ローカルGPUや適切なドライバーがありませんか？問題ありません！LeIsaacはセットアップゼロで完全にクラウド上で実行できます。LeIsaacは**NVIDIA Brev**でそのまま動作し、ブラウザ上で完全に設定された環境を利用できます。

👉 **ここから始めましょう:** [https://lightwheelai.github.io/leisaac/docs/cloud_simulation/nvidia_brev](https://lightwheelai.github.io/leisaac/docs/cloud_simulation/nvidia_brev)

インスタンスのデプロイが完了したら、**ポート 80 (HTTP)** のリンクを開くだけで、**Visual Studio Code Server** が起動します（デフォルトのパスワード: `password`）。そこから、シミュレーションの実行、コードの編集、IsaacLab 環境の可視化を、すべて Web ブラウザから行えます。

**GPUもドライバもローカルインストールも不要。クリックするだけで実行できます。**

## 追加の注記

EnvHubのカバレッジはLeIsaacタスクに合わせて維持されています。現在サポートされているもの:

- `so101_pick_orange`
- `so101_lift_cube`
- `so101_clean_toytable`
- `bi_so101_fold_cloth`

`make_env`を呼び出す際に別のスクリプトを指定することで、タスクを切り替えることができます。例:

```python
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()`を呼び出してください:

クリックしてコード例を展開

```python
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...
```

