Hello Robot¶
学習目標¶
このチュートリアルを修了すると、以下の内容を習得できます:
- Nucleus サーバーからロボットアセットをシーンに読み込む方法
Robotクラスを使用してロボットプリムをラップし、高レベル API でアクセスする方法- アーティキュレーション(関節構造)のジョイントに速度指令を送ってロボットを動かす方法
- 物理演算コールバックを使ってシミュレーション中に継続的にアクションを適用する方法
WheeledRobotクラスを使って車輪型ロボットをより簡潔に制御する方法
はじめに¶
前提条件¶
- チュートリアル 1: Hello World を完了していること
/Isaacフォルダを含む Omniverse Nucleus サーバーが設定済みであること
所要時間¶
約 10〜15 分
ソースコードの準備¶
このチュートリアルでは、引き続き Hello World サンプルの hello_world.py を編集していきます。前回のチュートリアルから続けて作業している場合はそのまま進めてください。別の日に作業を再開する場合は、以下の手順でソースコードを開いてください。
- Windows > Examples > Robotics Examples をアクティブにして、Robotics Examples タブを開きます。
- Robotics Examples > General > Hello World をクリックします。
- Open Source Code ボタンをクリックし、Visual Studio Code で
hello_world.pyを開きます。
詳しい手順は Hello World の「サンプルを開く」セクションを参照してください。
ロボットをシーンに追加する¶
前回のチュートリアルでは立方体をシーンに追加しましたが、今回はロボットを追加します。ここでは NVIDIA の Jetbot(2輪の差動駆動ロボット)を使用します。
GUI でロボットを追加する方法(クリックで展開)
Python コードを書かなくても、Isaac Sim Assets ブラウザからドラッグ&ドロップでロボットをシーンに追加できます。
-
Window > Browsers > Isaac Sim Assets をクリックして、Isaac Sim Assets ウィンドウを有効にします。

初回起動時の注意
Isaac Sim Assets ウィンドウを初めて開く際、アセットデータのダウンロードが行われるため、表示されるまでに時間がかかることがあります。ネットワーク環境によっては数分以上かかる場合があります。
-
検索バーに「Jetbot」と入力し、表示された Jetbot アセットをビューポートにドラッグ&ドロップします。

この方法は素早くロボットを配置したい場合に便利ですが、Python API を使った方法を覚えることで、プログラムから動的にロボットを追加・制御できるようになります。以降ではPython APIを使った方法を解説します。
Python API によるロボットの追加¶
ロボットアセットは Omniverse Nucleus サーバーに格納されています。get_assets_root_path() でアセットのルートパスを取得し、add_reference_to_stage() でアセットを USD Stage に読み込みます。
ただし、add_reference_to_stage() だけではロボットの 3D モデルと物理プロパティが Stage 上に配置されるだけで、関節の位置取得や速度指令といったロボットとしての制御はできません。制御するには低レベルな USD API や PhysX API を直接操作する必要があります。
そこで、読み込んだロボットのプリムを Robot クラスでラップし、world.scene.add() で Scene に登録します。Robot クラスは既存のプリムを参照するだけで、プリムのコピーや変換は行いません。同じ /World/Fancy_Robot プリムに対して、get_joint_positions() や apply_action() などの高レベル API を提供する Python オブジェクトを作成します。
| 処理 | 役割 |
|---|---|
add_reference_to_stage() |
USD Stage 上にロボットのプリムを作成する |
Robot(prim_path=...) |
既存のプリムを参照し、高レベル API を提供する Python ラッパーを作成する |
world.scene.add() |
ラッパーを Scene に登録し、World のライフサイクル(reset/step)と連携させる |
参照(Reference)について
add_reference_to_stage() は USD ファイルを参照(Reference)として Stage に追加します。元のファイルへのリンクを保持するため、アセットの変更が自動的に反映されます。USD の内容を Stage に直接コピーする方法もありますが、ロボットアセットの読み込みでは参照方式が一般的です。
コードを保存してシミュレーションを確認します:
- Ctrl+S を押してコードを保存し、Isaac Sim をホットリロードします。
- Hello World サンプル拡張機能のウィンドウを再度開きます。
- File > New From Stage Template > Empty でワールドを新規作成してから、LOAD ボタンを押します。
- ターミナルの出力を確認します。
物理ハンドルに関する重要なポイント¶
setup_scene と setup_post_load で表示される num_dof(自由度の数)が異なることに注目してください。
| タイミング | num_dof の値 |
理由 |
|---|---|---|
setup_scene(リセット前) |
None |
物理ハンドルが未初期化 |
setup_post_load(リセット後) |
2 |
物理ハンドルが初期化済み(左右の車輪) |
注意
アーティキュレーション(関節構造)のプロパティ(自由度、ジョイント位置など)は、最初のリセットが行われるまでアクセスできません。これらの情報を取得する処理は、必ず setup_post_load 以降で行ってください。
ロボットを動かす¶
次に、Jetbot の車輪に速度指令を送って動かします。
ロボットの動作制御には ArticulationController(アーティキュレーションコントローラ)を使用します。これは暗黙的な PD コントローラとして動作し、PD ゲインの設定、アクションの適用、制御モードの切り替えなどを行えます。
暗黙的な PD コントローラとは(クリックで展開)
実際のロボットでは、モータに「目標位置」や「目標速度」を指定すると、モータドライバ内の制御器が目標値と現在値の差に応じて電流(トルク)を計算し、関節を動かします。
Isaac Sim の物理エンジン(PhysX)でも同様の仕組みが内部に組み込まれています。joint_positions や joint_velocities で目標値を指定すると、PhysX が内部で PD 制御(比例-微分制御) を行い、目標に追従するために必要な力を自動計算します。
この PD コントローラはユーザーが明示的に実装するのではなく、物理エンジンに暗黙的に組み込まれているため、「暗黙的な PD コントローラ」と呼ばれます。\(K_p\)(比例ゲイン)と \(K_d\)(微分ゲイン)は ArticulationController を通じて調整できます。
ArticulationAction には以下の3つのパラメータを指定できます:
| パラメータ | 説明 |
|---|---|
joint_positions |
各ジョイントの目標位置 |
joint_velocities |
各ジョイントの目標速度 |
joint_efforts |
各ジョイントに適用するトルク/力 |
いずれも numpy 配列、list、または None(その自由度には指令を送らない)を指定できます。
2つの apply_action の使い分け
コード中のコメントにある通り、同じ処理は self._jetbot.apply_action(...) でも呼び出せます。それぞれの特徴は以下の通りです:
| 呼び出し方 | 特徴 |
|---|---|
robot.get_articulation_controller().apply_action() |
PD ゲインの変更や制御モードの切り替えなど、ArticulationController の詳細な設定にアクセスできる |
robot.apply_action() |
簡潔に書ける。内部で ArticulationController を呼び出しているため動作は同じ |
PD ゲインの調整が不要な場合は robot.apply_action() で十分です。次のチュートリアルからはこちらの簡潔な書き方を使用します。
コードを保存してシミュレーションを確認します:
- Ctrl+S を押してコードを保存し、Isaac Sim をホットリロードします。
- File > New From Stage Template > Empty でワールドを新規作成してから、LOAD ボタンを押します。
- PLAY ボタンを押して、Jetbot がランダムに動き回る様子を確認します。

毎ステップで左右の車輪にランダムな速度(0〜5 の範囲)を適用しているため、Jetbot は不規則に動きます。
練習問題¶
以下の練習問題に挑戦して、ロボット制御の理解を深めましょう。
問題 1: 後退させる — Jetbot を後ろ向きに移動させてみましょう。
ヒント(クリックで展開)
車輪の速度を負の値にします。
問題 2: 右に旋回させる — Jetbot を右方向に旋回させてみましょう。
ヒント(クリックで展開)
左右の車輪に異なる速度を設定します(左の車輪を速く、右を遅く)。
問題 3: 5秒後に停止させる — シミュレーション開始から5秒後に Jetbot を停止させてみましょう。
ヒント(クリックで展開)
step_size を毎ステップ累積して経過時間を計算し、条件分岐で停止させます。
WheeledRobot クラスを使う¶
ここまでは汎用的な Robot クラスを使用していました。Isaac Sim には、特定のロボットタイプに特化したクラスも用意されています。車輪型ロボットの場合は WheeledRobot クラスを使うことで、より簡潔にコードを記述できます。
Robot クラスと WheeledRobot クラスの違いを見てみましょう:
| 特徴 | Robot クラス |
WheeledRobot クラス |
|---|---|---|
| アセット読み込み | add_reference_to_stage + Robot() の2段階 |
WheeledRobot() で一括(create_robot=True) |
| 車輪のジョイント | インデックスで指定 | ジョイント名で指定可能 |
| アクション適用 | get_articulation_controller().apply_action() |
apply_wheel_actions() で直接指定 |
WheeledRobot を使った場合のポイント:
add_reference_to_stageの呼び出しが不要(create_robot=Trueでアセット読み込みも含まれる)wheel_dof_namesで車輪のジョイント名を明示的に指定できるapply_wheel_actions()で車輪に特化したアクション適用が可能
まとめ¶
このチュートリアルでは以下のトピックを扱いました:
- Nucleus サーバーからロボットアセットを読み込みシーンに追加する方法
- Robot クラスでロボットプリムをラップし、高レベル API でアクセスする方法
- ArticulationController と ArticulationAction によるジョイント制御
- 物理演算コールバックを使ったシミュレーション中の継続的なアクション適用
- WheeledRobot クラスを使った車輪型ロボットの簡潔な制御
次のステップ¶
次のチュートリアル「コントローラの追加」に進み、ロボットにコントローラを追加してより高度な動作を実現する方法を学びましょう。
注釈
以降のチュートリアルでも主に Extension Workflow を使用して開発を進めます。Standalone Workflow への変換方法は Hello World で学んだ手順と同様です。