🌊

【Isaac Sim × Isaac Lab入門】#1-2 Isaac Simに空のシーンを表示するコードの解説

に公開

以下の記事にて、Python経由でNVIDIA Isaac Sim に空のシーンを表示させることができた。
https://zenn.dev/kprn/articles/57dea2a3951bd3

今回は、上記で実行したコードの中身を詳しく調査する。

基本はこちらのサイト通りだが、理解できたことを記載する。

コード

空のシーンを表示するために使用したコードは以下である。

create_empty_scene.py
import argparse
from isaaclab.app import AppLauncher

# ステップ0. 引数を受け取る
parser = argparse.ArgumentParser(description="Tutorial on creating an empty stage.")
AppLauncher.add_app_launcher_args(parser)
args_cli = parser.parse_args()

# ステップ1. シミュレータの起動
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app

# ステップ2. Isaac Simからモジュールをインポート
from isaaclab.sim import SimulationCfg, SimulationContext

# ステップ3. シミュレーションコンテキストの設定
sim_cfg = SimulationCfg(dt=0.01)
sim = SimulationContext(sim_cfg)

# ステップ4. ビューポートを映すカメラの位置・注視点を設定
sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])

# ステップ5. シミュレーションの実行
sim.reset()
while simulation_app.is_running():
    sim.step()

# ステップ6. シミュレーションを終了
simulation_app.close()

コードを理解する

コードの流れ

コードの流れは、以下のようになっている。

それぞれ詳しく見ていく。

ステップ0. 引数を受け取る

コードは以下。

parser = argparse.ArgumentParser(description="Tutorial on creating an empty stage.")
AppLauncher.add_app_launcher_args(parser)
args_cli = parser.parse_args()

このステップでは、コマンドプロンプトから渡した引数を受け取る。

以下は、引数がない場合と、引数がある場合(--headless)の実行例。

例.

引数がない
isaaclab.bat -p ..\python_scripts\create_empty_scene.py
引数がある
isaaclab.bat -p ..\python_scripts\create_empty_scene.py --headless

例えば--headlessを指定すると、シミュレータの画面を開かずに、シミュレーションを行うことができる。

ステップ1. シミュレータの起動

コードは以下。

app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app

このステップでは、シミュレータに引数args_cliを渡し、シミュレータを起動する。

以下は、headlessモードで実行したときのargs_cliの中身である。

Namespace(headless=True, livestream=-1, enable_cameras=False, device='cuda:0', cpu=False, verbose=False, info=False, experience='', kit_args='')

各引数の役割はこちらを参照。

ステップ2. Isaac Simからモジュールをインポート

コードは以下。

from isaaclab.sim import SimulationCfg, SimulationContext

Isaac Simに関連するモジュールは、シミュレータを起動してからでないとインポートできない

ので注意。

ステップ3. シミュレーションコンテキストの設定

コードは以下。

sim_cfg = SimulationCfg(dt=0.01)
sim = SimulationContext(sim_cfg)

シミュレーションコンテキストは、シミュレータの再生、一時停止、ステップ実行を制御する。

例えば上のコードにおいて、SimulationCfg(dt=0.01)に設定されているが、これは、物理とレンダリングの時間ステップを0.01秒に設定している。

もう少し詳細に記載すると、以下のように理解した。
この理解が正しいかどうかは、今後さらに詳細に検証していきたい。

物理とレンダリングのステップを合わせるとは?

具体例を用いて説明する。

今、whileループを使って、立方体を空中(高さy_0)から、地面に対し

初速度v_0 = 0
重力加速度g=9.8[m/s^2]
で落とすシミュレーションを行うとする。

この時、立方体の高さyは、

y = y_0 - \frac{gt^2}{2}
で計算される。

whileループの1ステップ目では、t=0.01なので、シミュレータは初期位置より約0.00098m(0.098cm)下の位置に立方体をレンダリングする。

次のステップ(t=0.02)でも同様に力が加わり、立方体の位置が時間とともに更新されていく。

もし1秒のシミュレーションを行う場合、100ステップ必要となる。

ステップ4. ビューポートを映すカメラの位置・注視点を設定

コードは以下。

sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])

ビューポート(ユーザーが見ている画面のこと。下図赤枠部分。)を設定している。

引数の一つ目([2.5, 2.5, 2.5])は、ビューポートを映すカメラ(eye)の位置である。
引数の二つ目([0, 0, 0])は、カメラの注視点(target)である。

このスクリプトの場合、X, Y, Z=[2.5, 2.5, 2.5]から、X, Y, Z=[0, 0, 0]を注目するような、ビューポートが設定される。

ステップ5. シミュレーションの実行

以下のコードが該当する。

sim.reset()
while simulation_app.is_running():
    sim.step()

sim.reset()は、シミュレータを初期化する。
sim.step()でシミュレーションを1ステップ進める。

シミュレーションステップを実行する前は、初期化する。

ステップ6. シミュレーションを終了

以下のコードが該当する。

simulation_app.close()

シミュレーションの最後に、実行する。

ネクストアクション

今回で、空のシーンを表示するPythonコードが、何を行なっているかを把握できた。
今後は、シミュレータ内にオブジェクトを配置することや、カメラを操作することなどを試してみたい。

Discussion