🎉

【Isaac Sim × Isaac Lab入門】#3 PythonでIsaac Sim内のオブジェクトの座標を取得する

に公開

以下の記事にて、Isaac Simに直方体を配置し、Rigid Bodyと重力を設定できた。
https://zenn.dev/kprn/articles/8c1d9b191e0775

今回はPart3として、公式チュートリアルを参考に、

  • 直方体の位置を取得して表示する

ことを試してみる。

この記事の内容を実施すると、以下のように

  • 落下中の直方体の、ワールド座標を取得する

ことができる。

手順

手順1. Pythonスクリプトの作成

前回までの手順と同様に、C:\Users\{ユーザ名}\work\python_scriptsディレクトリの中に、get_object_transform.pyというPythonスクリプトを作成する。

C:\Users\{ユーザ名}\work\
├─ IsaacLab
└─ python_scripts
   └─ create_empty_scene.py
   └─ create_object.py
   └─ get_object_transform.py 

そしてget_object_transform.pyの中に、以下のコードを貼り付ける。

今回のコード
get_object_transform.py
import argparse
from isaaclab.app import AppLauncher


# ステップ0. 引数を受け取る
parser = argparse.ArgumentParser(description="Get Object Position")
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やその他のモジュールをインポート
import isaacsim.core.utils.prims as prim_utils

import isaaclab.sim as sim_utils
from isaaclab.assets import RigidObject, RigidObjectCfg


def create_scene():
    """環境の準備"""

    # 地面を配置
    cfg_ground = sim_utils.GroundPlaneCfg()
    cfg_ground.func("/World/defaultGroundPlane", cfg_ground)

    # ライトを配置
    cfg_light_distant = sim_utils.DistantLightCfg(
        intensity=3000.0,
        color=(0.75, 0.75, 0.75),
    )
    cfg_light_distant.func("/World/lightDistant", cfg_light_distant, translation=(1, 0, 10))

    # Rigid Bodyの位置情報を格納する用の、Xformオブジェクトを作成
    origin = [[0, 0, 2]]
    prim_utils.create_prim(f"/World/Origin", "Xform", translation=origin)

    # Xformオブジェクトの配下に、Rigid Bodyを付与した直方体を配置
    cuboid_cfg = RigidObjectCfg(
        prim_path="/World/Origin/Cuboid",
        spawn=sim_utils.CuboidCfg(
            size=(0.5, 0.5, 0.5),
            rigid_props=sim_utils.RigidBodyPropertiesCfg(rigid_body_enabled=True),
            mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
            collision_props=sim_utils.CollisionPropertiesCfg(),
            visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
        ),
        init_state=RigidObjectCfg.InitialStateCfg(),
    )
    cuboid_object = RigidObject(cfg=cuboid_cfg)

    return cuboid_object


def run_simulator(obj: RigidObject):
    """シミュレーションの実行"""

    # シミュレーションの時間間隔(今回はdt=0.01)を取得
    sim_dt = sim.get_physics_dt()
    num_step = 0

    # オブジェクトの現在位置を表示
    while simulation_app.is_running():

        # 250ステップ経過したら終了
        if num_step > 250:
            break

        # オブジェクトの現在位置を表示
        print(f"cuboid position: {obj.data.root_state_w[:, :3]}")

        # シミュレーションを1ステップ進める
        sim.step()

        # オブジェクトの位置を、1ステップ(=0.01秒)進めた後の値に更新
        obj.update(sim_dt)

        num_step += 1


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

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

# ステップ5. 地面、ライト、直方体をシーンに配置
cuboid_object = create_scene()

# ステップ6. シミュレーションの実行
sim.reset()
run_simulator(obj=cuboid_object)

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

このコードは、公式のコードを参考に、ステップが分かりやすくなるように整理したものである。

コードのポイントは以下。

コードのポイント

create_scene()の以下の部分で、Xformオブジェクトを作成し、その配下に直方体オブジェクトを配置している。

    # Rigid Bodyの位置情報を格納する用の、Xformオブジェクトを作成
    origin = [[0, 0, 2]]
    prim_utils.create_prim(f"/World/Origin", "Xform", translation=origin)

    # Xformオブジェクトの配下に、Rigid Bodyを付与した直方体を配置
    cuboid_cfg = RigidObjectCfg(
        prim_path="/World/Origin/Cuboid",
        spawn=sim_utils.CuboidCfg(
            size=(0.5, 0.5, 0.5),
            rigid_props=sim_utils.RigidBodyPropertiesCfg(rigid_body_enabled=True),
            mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
            collision_props=sim_utils.CollisionPropertiesCfg(),
            visual_material=sim_utils.PreviewSurfaceCfg(diffuse_color=(0.0, 1.0, 0.0)),
        ),
        init_state=RigidObjectCfg.InitialStateCfg(),
    )
    cuboid_object = RigidObject(cfg=cuboid_cfg)
  • Xformオブジェクトは、「オブジェクトの位置、回転、スケール」を制御するための概念(参考)。

  • Xformを/World/Originに作成し、その配下に/World/Origin/Cuboidのように直方体オブジェクトを作成することで、「Xformの位置=直方体オブジェクト」の位置として、位置を取得している。

  • 実際に位置を取得している部分は、run_simulatorの以下の部分。

print(f"cuboid position: {obj.data.root_state_w[:, :3]}")

objにはcreate_scene()で定義したcuboid_objectが格納されており、obj.data.root_state_w[:, :3]で位置を取得することができる。

手順2. 実行前の事前準備

Isaac SimとIsaac Labを実行する事前作業として、パスを通す。

コマンドプロンプト上で、以下を実行する。

cd C:\Users\{ユーザ名}\work\IsaacLab
set ISAACSIM_PATH="C:/isaacsim"
set ISAACSIM_PYTHON_EXE="%ISAACSIM_PATH:"=%\python.bat"
isaaclab.bat --install

手順3. 実行

コマンドプロンプト上で、以下を実行する。

isaaclab.bat -p ..\python_scripts\get_object_transform.py

実行が成功すると、Isaac Simが起動し、重力に従って落下する緑色の直方体が表示され、コマンドプロンプト上に直方体のワールド座標が表示される。

X, Y, Zの順番で値が格納されている。
例えば

tensor([[0.0000, 0.0000, 1.9971]], device='cuda:0')

は、X座標0, Y座標0, Z座標1.9971にオブジェクトが存在することが分かる。
なお、単位はm(メートル)

シミュレーションを終了するときは、

  • コマンドプロンプトで「Ctrl+C」を押す
  • シミュレータ画面を「×ボタン」で消す

のどちらかを実行する。

Next Action

今回はPythonスクリプトによって、オブジェクトのワールド座標を取得することができた。

今後の記事では、カメラを操作して機械学習用のデータ撮影する方法などを検討する。

Discussion