はじめに
ネクスティ エレクトロニクスの開発部隊による技術コラムになります。
フィジカルAIの実用化に向けて、世界中で開発競争が加速しています。その鍵となるのが、仮想空間上でロボットを学習させるロボットシミュレーション技術です。NVIDIAのIsaac SimとIsaac
Labは、この分野で現在最も注目されている開発基盤の一つです。
今回はDockerでIsaac Sim / Isaac
Labを立ち上げ、サンプル実行までの手順を紹介します。構成は「まずシーンを見る」→「四足で学ぶ」→「ライブラリを差し替える」→「ヒューマノイドで難易度を上げる」です。ソフトウェアのバージョンによって手順や画面は変わることがあります。実際に使用する環境の仕様も併せて確認してください。
Isaac SimとIsaac Labとは
混同しやすいので、先に役割を整理します。
| Isaac Sim | Isaac Lab | |
|---|---|---|
| 役割 | 物理シミュレーション、レンダリング、USDシーン | 並列環境、タスク定義、強化学習・模倣学習の実行枠 |
| 本記事での例え | 「ロボットと床と物理がある世界」 | 「その世界を何千体も並べて学習する装置」 |
| 最初のサンプル | サンプル1:Jetbot + Franka(学習なし) | サンプル2〜4:Go2 / G1 の歩行学習 |
Isaac LabはIsaac Simの上に載っています。Labの学習スクリプトを実行すると、内部でSimの物理エンジンとアセットが動きます。
[ホストOSとNVIDIAドライバ]
↓
[Dockerコンテナ]
↓
[Isaac Sim] 物理・レンダリング・USD
↓
[Isaac Lab] 並列環境・タスク定義
↓
[RLライブラリ] RSL-RL / SKRL など
本記事で作るもの
Isaac SimとIsaac Labの役割を整理し、Dockerで環境を作り、次の4つを再現します。
- 1. サンプル1:Isaac Sim上で複数ロボット(Jetbot + Franka)を動かす
- 2. サンプル2:四足ロボット(Unitree Go2)の歩行を強化学習する
- 3. サンプル3:同じタスクのままRLライブラリを切り替える
- 4. サンプル4:ヒューマノイド(Unitree G1)の不整地歩行を強化学習する
読み終わったときに、次ができるようになっていることをゴールにします。
- DockerでIsaac Labコンテナを起動し、中に入れる
- Isaac Simの「シーンを動かす」と、Isaac Labの「並列環境で強化学習する」の違いを説明できる
- Go2の平面歩行とG1の不整地歩行を学習・再生でき、RLライブラリを選ぶ観点を持てる
想定読者
本記事は、以下のような方を対象としています。
- ロボット学習やシミュレーションに興味がある人
- Isaac Sim / Isaac Labを初めて使う人
- DockerやPythonからGPUシミュレーションを動かしてみたい人
- 四足やヒューマノイドの歩行学習を、公式サンプルで試したい人
Isaacの経験は不要です。一方で、Linux(Ubuntu系)の基本操作、Dockerの基本、Pythonのコマンド実行、NVIDIA GPU搭載マシンへのアクセスは使える前提です。
使用機材
記事作成時点の環境は下記です。
- OS:Ubuntu 24.04.3 LTS
- GPU:NVIDIA GeForce RTX 5090(VRAM 32GB)
- NVIDIAドライバ:580.126.09
- CUDA:13.0
- ソフトウェア:Docker、NVIDIA Container Toolkit、Git、Python 3
- GUI確認用:Isaac Sim WebRTC Streaming Client
Isaac Sim WebRTC Streaming
Clientは、ヘッドレスで動いているシミュレータの画面を、ホストPCへリアルタイム転送して見る専用アプリです。コンテナ内にウィンドウを出さず、映像と操作だけを外から扱います。本記事の検証ではこのクライアントを使います。
ホストへのIsaac Simバイナリインストールはしません。依存関係が重いため、コンテナで構築します。歩行学習では既定で4096体のロボットを同時に動かします。VRAMには余裕を見ておいてください。
参考:Isaac Sim container installation
環境構築:なぜDockerか
Dockerを選ぶ理由
Isaac Sim / Isaac Labは、単なるPythonパッケージではありません。Omniverse(Kit)本体、CUDA、レンダラ、拡張機能、PhysX、学習ライブラリが一体です。ホストに直接入れると、次が起きやすくなります。
- 既存のCUDA / PyTorch / ドライバと衝突する
- バージョンを固定できず、再現実験が崩れる
- 「動いたマシン」と「動かないマシン」の差を切り分けにくい
Dockerなら、公式イメージとIsaac Lab付属のdocker/container.pyでスタックをまとめられます。GPUはNVIDIA Container Toolkit経由でコンテナに渡します。ホスト側に残すのはドライバとDockerだけで、Python環境はコンテナ内に閉じられます。
コンテナの手順はIsaac Simのインストール案内にもあります。
1. Dockerのインストール
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
dockerグループへの追加後は、一度ログアウトしないと権限エラーになります。
2. NVIDIA Container Toolkitのインストール
インストール案内に従い、NVIDIA Container Toolkitをインストールします。
3. Isaac Labのクローンとコンテナ起動
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab/
python3 docker/container.py start
python3 docker/container.py enter
startは初回のイメージ取得とコンテナ作成に時間がかかります。起動後の作業ディレクトリは/workspace/isaaclabです。以降の学習コマンドは、特に断らない限りコンテナ内で実行します。
サンプル1: Adding Multiple Robots(Jetbot + Franka)
ここは Isaac Labの強化学習ではありません。Isaac SimのPython APIでUSDシーンを組み、Jetbotが赤いキューブを押し、隣にFrankaアームを置くデモです。
「シミュレータが起動し、ロボットが物理に従って動く」ことを先に確認します。学習ループ、報酬、並列環境はまだ出てきません。
スクリプトを置く
ホストまたはコンテナ内で、次の場所にファイルを作ります。
mkdir -p /workspace/isaaclab/scripts/nexty_sample
multi_robot_livestream_demo.pyの要点は次です。
SimulationAppでKitをヘッドレス起動し、livestream拡張を有効化する- Nucleus上の環境・Jetbot・Franka USDをステージに載せる
- Jetbotを
Articulationとして速度指令する - タイムラインがPLAYされるたびにカウンタを戻し、同じ押し動作を繰り返せるようにする
import argparse
from isaacsim import SimulationApp
parser = argparse.ArgumentParser()
parser.add_argument("--test", default=False, action="store_true")
args, _ = parser.parse_known_args()
CONFIG = {
"width": 1280,
"height": 720,
"window_width": 1920,
"window_height": 1080,
"headless": True,
"hide_ui": False,
"renderer": "RaytracedLighting",
"display_options": 3286,
}
kit = SimulationApp(launch_config=CONFIG)
from isaacsim.core.experimental.utils.app import enable_extension
kit.set_setting("/app/window/drawMouse", True)
enable_extension("omni.kit.livestream.app")
# --- シーン構築: 床、Jetbot、赤いキューブ、Franka ---
import isaacsim.core.experimental.utils.stage as stage_utils
import numpy as np
from isaacsim.core.experimental.materials import PreviewSurfaceMaterial
from isaacsim.core.experimental.objects import Cube
from isaacsim.core.experimental.prims import Articulation, GeomPrim, RigidPrim, XformPrim
from isaacsim.storage.native import get_assets_root_path
import omni.timeline
assets_root_path = get_assets_root_path()
stage_utils.add_reference_to_stage(
usd_path=assets_root_path + "/Isaac/Environments/Grid/default_environment.usd",
path="/World/ground",
)
stage_utils.add_reference_to_stage(
usd_path=assets_root_path + "/Isaac/Robots/NVIDIA/Jetbot/jetbot.usd",
path="/World/Jetbot",
)
visual_material = PreviewSurfaceMaterial("/World/Materials/red")
visual_material.set_input_values("diffuseColor", [1.0, 0.0, 0.0])
cube_shape = Cube(
paths="/World/Cube",
positions=np.array([[0.15, 0.0, 0.025]]),
sizes=[1.0],
scales=np.array([[0.05, 0.05, 0.05]]),
reset_xform_op_properties=True,
)
GeomPrim(paths=cube_shape.paths, apply_collision_apis=True)
RigidPrim(paths=cube_shape.paths)
cube_shape.apply_visual_materials(visual_material)
stage_utils.add_reference_to_stage(
usd_path=assets_root_path + "/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd",
path="/World/Franka",
)
XformPrim("/World/Franka").set_world_poses(positions=np.array([[0.8, -0.5, 0.0]]))
for _ in range(5):
kit.update()
jetbot = Articulation("/World/Jetbot")
timeline = omni.timeline.get_timeline_interface()
# PLAY(Stop→Play、Reset→Playを含む)のたびに押し動作をやり直す
state = {"step_counter": 0}
def on_timeline_event(event):
if event.type == int(omni.timeline.TimelineEventType.PLAY):
state["step_counter"] = 0
print("[INFO] PLAY detected. Jetbot will push the cube again.")
timeline_event_stream = timeline.get_timeline_event_stream()
timeline_sub = timeline_event_stream.create_subscription_to_pop(on_timeline_event)
timeline.play()
while kit._app.is_running() and not kit.is_exiting():
kit.update()
if timeline.is_playing():
state["step_counter"] += 1
if state["step_counter"] < 300:
jetbot.set_dof_velocity_targets([[10.0, 10.0]])
else:
jetbot.set_dof_velocity_targets([[0.0, 0.0]])
if args.test and state["step_counter"] >= 400:
break
kit.close()
実行とWebRTC接続
コンテナ内で、次のコマンドを実行します。
isaaclab -p /workspace/isaaclab/scripts/nexty_sample/multi_robot_livestream_demo.py
ホスト側で Isaac Sim WebRTC Streaming Clientを入れ、
127.0.0.1に Connect します。接続できると、Jetbotがキューブを押し、奥にFrankaが見えます。UIのPLAYで同じ動作をやり直せます。
ここまで動けば、Docker・GPU・livestreamの経路は通っています。
強化学習とRLライブラリの選び方
サンプル2(Go2の歩行学習)へ進む前に、強化学習とIsaac Labから呼べる学習ライブラリを整理します。
強化学習とは
NVIDIAの解説 にあるように、強化学習(RL: Reinforcement Learning)は、ロボットが仮想環境で試行錯誤しながら行動を学ぶ機械学習です。望ましい行動には高い報酬を与え、そうでない行動は低く評価します。この繰り返しで、ポリシー(制御方針)を少しずつ良くしていきます。
従来のプログラミングでは書き切れない歩行や把持も、シミュレーション上で何千体も並列に動かして経験を集めれば学習できます。Isaac Labは、この物理シミュレーションと報酬計算をGPU上で回します。ライブラリの比較はReinforcement Learning Library Comparisonにあります。
| 項目 | RL-Games | RSL-RL | SKRL | Stable Baselines3 |
|---|---|---|---|---|
| 主なアルゴリズム | PPO, SAC, A2C | PPO, Distillation | 多種(PPO, SAC, TD3, AMP, IPPO, MAPPO など) | 多種(PPO, SAC, TD3, DQN, A2C など) |
| ベクトル化学習 | あり | あり | あり | なし |
| 分散学習 | あり | あり | あり | なし |
| ML基盤 | PyTorch | PyTorch | PyTorch / JAX | PyTorch |
| マルチエージェント | PPO | PPO | PPO + 専用アルゴリズム | 外部プロジェクト依存 |
| ドキュメント | 少なめ | 少なめ | 充実 | 最も充実 |
| Isaac Labの例 | 多い | 多い | 多い | 少ない |
| 向き | 高スループット、マルチGPU | 脚式ロコモーション | 研究用途、アルゴリズム差し替え | 教育・標準実装との比較 |
Isaac Labから呼べるライブラリは、次の4つです。いずれも「環境から観測を受け取り、行動を返し、報酬でポリシーを更新する」役割は同じですが、速さ・対応タスク・扱いやすさが違います。
- ■ RSL-RL(ETH Zürich Robotic Systems Lab)は脚式向けに軽いPPO実装です。公式ベンチマークでも学習が速く、論文やUnitree系のsim-to-real事例でもよく使われます。サンプル2とサンプル4ではこちらを使います。
- ■ SKRL はモジュール性が高く、PPO以外のアルゴリズムやJAXにも対応します。同じGo2タスクを別実装で試すのに向きます。サンプル3で使います。
- ■ RL-Games は速い一方、タスクごとに専用設定が必要です。今回の
Isaac-Velocity-Flat-Unitree-Go2-v0には設定がなく、実行できませんでした。 - ■ Stable Baselines3 はドキュメントが厚い反面、ベクトル化・分散がなく、Isaac Labの大規模並列の恩恵を受けにくいです。
インストールは初回だけです。今回使うのは RSL-RL と SKRL です。
isaaclab -i rsl_rl
isaaclab -i skrl
以降、Go2平面歩行は RSL-RLとSKRLだけ を使います。
サンプル2: 四足ロボットの歩行学習(RSL-RL)
タスクはIsaac-Velocity-Flat-Unitree-Go2-v0です。平面上のGo2が、速度指令(前後・旋回)に追従するようPPOで学習します。既定では4096体のロボットを同時に動かします。
学習
isaaclab -p scripts/reinforcement_learning/rsl_rl/train.py \
--task Isaac-Velocity-Flat-Unitree-Go2-v0 \
--headless \
--max_iterations 50
短い確認なら--max_iterations 50、比較用なら1000、しっかり歩かせるならさらに伸ばします。学習中は iteration、steps per second、各報酬項、転倒(base_contact)などが流れます。
GUIで学習中の様子を見る場合は--livestream 2を付け、WebRTCクライアントから繋ぎます。
イテレーションとは
--max_iterationsの1回は、「同時に動かしている全ロボットから一定ステップ分の経験を集め、ポリシーを1回更新する」まとまりです。Go2 / G1のRSL-RL設定では、1体あたり24ステップ(num_steps_per_env = 24)です。
総ステップ数は次の式になります。
総ステップ数 = 同時に動かすロボットの数 × 1体あたりのステップ数 × イテレーション数
= 4096 × 24 × イテレーション数
たとえば--max_iterations 50なら、4096 × 24 × 50 = 4,915,200ステップです。イテレーション1000なら約9830万ステップ、7500なら約7.37億ステップです。以降の実行結果では、この換算も併記します。
再生(動画出力)
isaaclab -p scripts/reinforcement_learning/rsl_rl/play.py \
--task Isaac-Velocity-Flat-Unitree-Go2-v0 \
--num_envs 32 \
--headless \
--video \
--video_length 200特定のチェックポイントを見るときは--load_run <run名>を付けます。動画は各run配下のvideos/に保存されます。再生時の--num_envsは表示する個体数です。
実行結果
同じタスクを、イテレーションだけ変えて再生した結果です。
■ イテレーション 50(約491万ステップ)
歩行はまだ始まっていません。転倒はせず、立ったまま静止しています。
■ イテレーション 1000(約9830万ステップ)
平面を移動できるようになります。指令方向に応じて、個体ごとに進む向きが違います。
・ 32台(移動する方向の命令は個体によって違う)
・ 1台のみ
■ イテレーション 7500(約7.37億ステップ)
より安定して歩けます。ただし、後述のとおり発散することもあります。
・ 32台(移動する方向の命令は個体によって違う)
・ 1台のみ
注意: RSL-RLで値が発散することがある
Isaac Lab + RSL-RLの組み合わせでは、学習が進んだあと損失や報酬は発散します。その結果、ポリシーは壊れます。TensorBoardで value loss や報酬の急上昇、NaNの有無を見てください。
チェックポイントを遡るか、ライブラリを変える判断材料になります。そのため、同じタスクを次の章でSKRLでも回します。
この発散は、Isaac LabとRSL-RLを組み合わせたときに起こりうる既知の問題(バグ)です。
サンプル3: 同じ四足タスクをSKRLで
比較の軸を揃えるため、タスクは変えません。Isaac-Velocity-Flat-Unitree-Go2-v0のまま、学習スクリプトのディレクトリだけ変えます。
scripts/reinforcement_learning/rsl_rl/train.py
scripts/reinforcement_learning/skrl/train.pySKRLで1000イテレーション
isaaclab -p scripts/reinforcement_learning/skrl/train.py \
--task Isaac-Velocity-Flat-Unitree-Go2-v0 \
--headless \
--max_iterations 1000再生はサンプル2と同じplay.py です。パスを skrl に変えて実行します。
実行結果(1000回時点の比較)
| RSL-RL | SKRL | |
|---|---|---|
| このタスクの公式設定 | あり | あり |
| 1000回後の歩行 | 移動できる | 移動できる |
| 向く場面 | 脚式で速度を優先したいとき | 実装を読み替え・差し替えたいとき |
| 今回の注意 | 長めの学習で発散しうることがある | 警告は出るが、完走は安定していた |
■ RSL-RL(イテレーション 1000、約9830万ステップ)
■ SKRL(イテレーション 1000、約9830万ステップ相当)
※RL-GamesとSB3は、このタスクでは使いませんでした。
サンプル4: ヒューマノイドの歩行(Unitree G1)
四足で経路を確認したうえで、二足の不整地に進みます。タスクは Isaac-Velocity-Rough-G1-v0 です。 [Unitree G1] 向けの、凹凸のある地形での速度追従です。
四足より難しい理由は、以下の通りです。
- ■ 支持脚が少ない。転倒(胴体接触)でエピソードが終わりやすい
- ■ 地形がRough。平面のGo2と違い、段差をまたぐ必要がある
- ■ 報酬の制約が増える 。二足では四足と同じ報酬だけでは足りず、転倒ペナルティや腕・胴のブレ抑制などが上書きされます。満たすべき条件が増えるため、学習は収束しにくくなります
G1側の上書きの例です(公式タスク設定の要点)。
- 転倒に重いペナルティ(
termination_penalty) - 二足用の滞空報酬(
feet_air_time_positive_biped) - 足首の関節限界、腰・腕・胴のデフォルト姿勢からのずれを罰する
- yaw追従の成功閾値を四足より緩める
- ベースリンクは
torso_linkです。二足では、ベース質量のランダム化を無効にします。
速度指令の範囲も四足より狭いです。前後方向を0.0〜1.0(前進のみ)に限り、左右への横歩きはしません。その場での左右旋回(ヨー)だけを許します。まずは前に歩くことを優先する設計です。
学習と再生
isaaclab -p scripts/reinforcement_learning/rsl_rl/train.py \
--task Isaac-Velocity-Rough-G1-v0 \
--max_iterations 50 \
--headless確認用に50回、本学習では数百〜2000回まで伸ばします。再生はサンプル2と同じです。--task を Isaac-Velocity-Rough-G1-v0 に変えます。
実行結果
二足ロコモーションは、イテレーションが進むにつれて「ばたつく → 立つ → 重心を移す → 一歩出す → 歩容が滑らかになる」と段階が分かれます。(参考記事:G1 RL locomotion training)
四足の1000回で「歩ける」のと、二足不整地の1000回は中身が違います。G1は2000回付近でようやく歩容らしくなりました。短いイテレーションで判断しない方がよいです。
■ イテレーション 50(約491万ステップ)
立つことすらできずに倒れます。
■ イテレーション 200(約1970万ステップ)
ギリギリ立ってはいますが、歩いているとは言い難い状態です。
■ イテレーション 500(約4915万ステップ)
イテレーション200よりは、移動の兆しが見えます。
■ イテレーション 1000(約9830万ステップ)
段差を越えられるようになります。
■ イテレーション 2000(約1.97億ステップ)
歩行として成立するようになります。
■ イテレーション 5000(約4.92億ステップ)
2000回時点より、床から足を離す時が長くなり、高く足を上げて歩いています。
おわりに
本記事では、DockerでIsaac Labを立ち上げ、Isaac Simのシーン確認から四足・ヒューマノイドの歩行学習までを紹介しました。
最初のインストールは、ホストを汚さない Docker + NVIDIA Container Toolkit が現実的です。Isaac Simはシーンと物理、Isaac Labはその上の並列学習です。サンプル1とサンプル2以降でAPIが切り替わります。脚式ではRSL-RLを第一選択にしやすいです。ただし、タスクにagent設定があるか、長時間学習で発散しないかは確認してください。ヒューマノイドの不整地歩行では、四足より多くのイテレーションとサンプル数が必要です。公式には、遠隔操作で人間の動きを学習し、模倣する Isaac Lab Mimic もあります。
アームのピックアンドプレースや、ヒューマノイドの操作デモが対象です。強化学習で「歩ける・掴める」ポリシーを作ったあと、人の操作をデータにする経路です。手順とデータセットの扱い方は、別記事で追う予定です。公式の入口はTeleoperation and Imitation Learning です。
Isaac SimやIsaac Labを活用したロボットシミュレーション、強化学習についてご興味がございましたら、お気軽にお問い合わせください。
参考
お問い合わせ
関連技術コラム
関連製品情報

CO2センサーデモシステム
当社開発のCO2センサーデモシステムは、測定したCO2測定値をBLE経由で専用のAndroidアプリへ送信し、測定結果をグラフ表示可能です。
- Infineon Technologies AG
- ICT・インダストリアル
- スマートファクトリー・ロボティクス

AD4080:20ビット、40MSPS、差動SAR ADC
AD4080は20ビット、40MSPSの高速低ノイズSAR ADCで、広帯域な高精度データ取得と評価ボードやシミュレーションモデルが利用可能です。
- Analog Devices, Inc.
- ICT・インダストリアル
- スマートファクトリー・ロボティクス

カメラを用いた非接触のバイタルセンシング (アナログ・デバイセズ製品ユースケース)
カメラを用いた非接触のバイタルセンシングを低コストで導入できます。独自のアルゴリズムを用いて解析することで、ストレス、感情も推定できます。
- Analog Devices, Inc.
- NEXT Mobility

音声インターフェイスの要「音源分離」技術の紹介 (アナログ・デバイセズ製品ユースケース)
ネクスティ エレクトロニクスが開発した音源分離システムは、複数の音源から運転手や助手席など特定の話者の音声のみを抽出する事ができます。
- Analog Devices, Inc.
- NEXT Mobility
- ICT・インダストリアル

ADG1736:低電圧、2.4ΩデュアルSPDTスイッチ(2mm × 2mm LGAパッケージ)
ADG1736は、2.4Ωの低オン抵抗を備えた独立2回路SPDTスイッチで、低電圧動作と2×2mmLGAの小型実装に対応し、医療機器などの信号ルーティングに適します。
- Analog Devices, Inc.
- ICT・インダストリアル
- スマートファクトリー・ロボティクス

車載向け高速伝送技術GMSL2の特徴と製品ラインナップについて
より高画素なカメラの映像データを扱うことができるアナログ・デバイセズの次世代GMSL、GMSL2について特徴を説明します。
- Analog Devices, Inc.
- NEXT Mobility
- ICT・インダストリアル







