Isaac Simをスタンドアローンで動作させるpythonスクリプトを書いてみる


Pythonによるスタンドアローン起動

"Isaac Sim"はpythonスクリプトからスタンドアローンで起動することができます。Omniverse内の"Isaac Sim"ディレクトリに起動用のスクリプトが置いてありますので、以下のように対象とするpythonスクリプトを引数として実行するとスタンドアローンで"Isaac Sim"が起動します。

$ ./python.sh <path>/python.py

例えば、サンプルとして用意されている"franka"というマニュピレーションロボットのデモを起動するコマンドは以下のようになります。

$ cd ~/.local/share/ov/pkg/isaac_sim-2021.2.1
$ ./python.sh standalone_examples/api/omni.isaac.franka/follow_target.py


起動するまでにかなり時間がかかる

これはTargetCubeを追いかけるデモです。終了するときは"Isaac Sim"を閉じるか、起動ターミナルで<CTRL+C>を押します。

Pythonスクリプトを書いてみる

ここでは以下の内容をPythonスクリプトで実現してみます。

  1. オブジェクトを配置する
  2. キーボードで動くjetbotを配置する

オブジェクトを配置する

ここではomni.isaac.core.objectsモジュールを使用してオブジェクトを配置するスクリプトを作成します。omni.isaac.core.objectsモジュールには以下の関数が含まれます。

  • DynamicCuboid
  • DynamicCapsule
  • DynamicCone
  • DynamicCylinder
  • DynamicSphere
  • VisualCuboid
  • VisualCapsule
  • VisualCone
  • VisualCylinder
  • VisualSphere
  • FixedCuboid

これらの関数で立方体、カプセル体、円錐、円柱、球が配置できます。Dynamicがつくものは物理演算が適用されます。そのため空中に配置すると落下します。Visualがつくものは見かけ上のオブジェクトを配置します。これは空中に配置しても落下せず衝突判定もないので他のオブジェクトが素通りします。Fixedが付いたものが何故か立方体のみありますが、これは空間に固定された立方体が配置できます。

サンプルスクリプトは以下の通りです。

object_place.py
from omni.isaac.kit import SimulationApp
import numpy as np

simulation_app = SimulationApp({"headless": False})

from omni.isaac.core import World
from omni.isaac.core.objects import DynamicCuboid, DynamicCapsule, DynamicCone
from omni.isaac.core.objects import DynamicCylinder, DynamicSphere, FixedCuboid

my_world = World(stage_units_in_meters=0.01)

d_cube = my_world.scene.add(
    DynamicCuboid(
        prim_path="/dynamic_cube",
        name="dynamic_cube",
        position=np.array([0, 0, 0.5]) * 100,
        size=np.array([0.1, 0.1, 0.1]) * 100,
        color=np.array([255, 255, 255]),
    )
)

d_cap = my_world.scene.add(
    DynamicCapsule(
        prim_path="/dynamic_capsule",
        name="dynamic_capsule",
        position=np.array([0.5, 0, 0.5]) * 100,
        radius=0.05 * 100,
        height=0.05 * 100,
        color=np.array([255, 0, 0]),
    )
)

d_cone = my_world.scene.add(
    DynamicCone(
        prim_path="/dynamic_cone",
        name="dynamic_cone",
        position=np.array([-0.5, 0, 0.5]) * 100,
        radius=0.05 * 100,
        height=0.05 * 100,
        color=np.array([0, 0, 255]),
    )
)

d_cyl = my_world.scene.add(
    DynamicCylinder(
        prim_path="/dynamic_cylinder",
        name="dynamic_cylinder",
        position=np.array([0, 0.5, 0.5]) * 100,
        radius=0.05 * 100,
        height=0.05 * 100,
        color=np.array([0, 255, 0]),
    )
)

d_sph = my_world.scene.add(
    DynamicSphere(
        prim_path="/dynamic_sphere",
        name="dynamic_sphere",
        position=np.array([0.5, 0.5, 0.5]) * 100,
        radius=0.05 * 100,
        color=np.array([255, 0, 255]),
    )
)

f_cube = my_world.scene.add(
    FixedCuboid(
        prim_path="/fixed_cube",
        name="fixed_cube",
        position=np.array([-0.5, 0.5, 0.5]) * 100,
        size=np.array([0.1, 0.1, 0.1]) * 100,
        color=np.array([255, 255, 255]),
    )
)

my_world.scene.add_default_ground_plane()

my_world.reset()

while simulation_app.is_running():
    my_world.step(render=True)

simulation_app.close()

実行例は以下のようになります。


実行する6種類のオブジェクトが生成されます

キーボードで動くjetbotを配置する

ここではキーボードを使用してロボットを動かします。ロボットはjetbotを使用します。
サンプルは以下の通りです。

jetbot_keyboard.py
from omni.isaac.kit import SimulationApp
import numpy as np
import carb
import omni.appwindow

simulation_app = SimulationApp({"headless": False})

from omni.isaac.jetbot import Jetbot
from omni.isaac.jetbot.controllers import DifferentialController

from omni.isaac.core import World

my_world = World(stage_units_in_meters=0.01)

my_jetbot = my_world.scene.add(
    Jetbot(
        prim_path="/World/Jetbot",
        name="my_jetbot",
        position=np.array([0, 0.0, 2.0])
    ) 
) 

my_controller = DifferentialController(name="simple_control")

my_world.scene.add_default_ground_plane()

command_ = [0.0, 0.0]
def sub_keyboard_event(event, *args, **kwargs):
    """Handle keyboard events
    w,s,a,d as arrow keys for jetbot movement

    Args:
        event (int): keyboard event type
    """
    global command_
    if(
        event.type == carb.input.KeyboardEventType.KEY_PRESS
        or event.type == carb.input.KeyboardEventType.KEY_REPEAT
    ):
        if event.input == carb.input.KeyboardInput.W:
            command_ = [20, 0.0]
        if event.input == carb.input.KeyboardInput.S:
            command_ = [-20, 0.0]
        if event.input == carb.input.KeyboardInput.A:
            command_ = [0.0, np.pi / 5]
        if event.input == carb.input.KeyboardInput.D:
            command_ = [0.0, -np.pi / 5]
    if(event.type == carb.input.KeyboardEventType.KEY_RELEASE):
        command_ = [0.0, 0.0]

    return True

appwindow_ = omni.appwindow.get_default_app_window()
input_ = carb.input.acquire_input_interface()
keyboard_ = appwindow_.get_keyboard()
sub_keyboard_ = input_.subscribe_to_keyboard_events(keyboard_,sub_keyboard_event)

my_world.reset()

while simulation_app.is_running():
    my_world.step(render=True)
    if my_world.is_playing():
        my_jetbot.apply_wheel_actions(my_controller.forward(command=command_))

simulation_app.close()


起動するとjetbotが配置されます

上記のサンプル起動後、"Isaac Sim"上で以下のキーを使用してjetbotを動かすことができます。

  • "w":前進
  • "s":後進(バック)
  • "a":左旋回
  • "d":右旋回

キーボードのイベントコールバックでグローバル変数に操作情報を格納して動かすということをやっています。