見出し画像

Isaac Sim 入門 (4) - ロボットの基本チュートリアル

「Isaac Sim」のロボットの基本チュートリアルの手順をまとめました。

Basic Robot Tutorial


前回

1. ロボットの基本チュートリアル

ロボット基本のチュートリアルでは、ロボットをステージに追加し、移動させ、検査する方法について説明します。

2. GUI

2-1. ステージにロボットを追加

(1) 「File → New」を選択。

(2) 「Create → Robots → Franka Emika Panda Arm」を選択。

2-2. ロボットの確認

「Physics Inspector」を使用して、ロボットの関節プロパティを確認します。

(1) 「Tools → Physics → Physics Inspector」を選択。
右側にウィンドウが開きます。

(2) 「Stage」の「Franka」を選択。

(3) 「Physics Inspector」の「更新」アイコンをクリック
ウィンドウには、関節の上限値と下限値、デフォルトの位置などの情報が表示されます。

(4) 右上のハンバーガーアイコンをクリック。
関節の剛性や減衰などのその他のオプションが表示されます。

(5) 必要に応じて値を変更し、それに応じてステージ上でロボットが動くことを確認。
緑色のチェックマークが表示されます。

(5) 変更をロボットの新しいデフォルト値として確定するには、緑色のチェックマークをクリック。

2-3. ロボットの制御

GUIベースのロボットコントローラは、Omniverseビジュアルプログラミングツール「OmniGraphs」に含まれています。「OmniGraph」に関するより詳しいチュートリアルは、こちらを参照してください。今回は、ショートカットツールを使用してグラフを生成し、「OmniGraph Editor」でグラフを確認します。

(1) 「Tools → Robotics → Omnigraph Controllers → Joint Position」を選択。
「Graph Generator」を開きます。

(2) 新しく表示された「Articulation Position Controller Inputs」ポップアップウィンドウで、「Robot Prim」フィールドの「Add」をクリック。

(3) ターゲットとして「Franka」を選択。

(4) 「OK」をクリック。
グラフを生成します。

ロボットを動かすには、次のとおりです。

(1) 「Stage」で、「Graph → Position_Controller → JointCommandArray」を選択。

(2) 「Property」で、ジョイントコマンドの値を確認。
「Construct Array」ノードの「Inputs」は、ベースジョイントから始まるロボットの各ジョイントに対応しています。

(3) 様々な値フィールドをクリックして押したままドラッグするか、異なる値を入力して、ロボットアームの位置が変化するのを確認。

(4) 「Play」を押してシミュレーションを開始。

生成されたグラフを視覚化には、次のとおりです。

(1) 「Window > Graph Editors > Action Graph」を選択。
エディタウィンドウは、ロボットを含む「Viewport」タブの下のタブに開きます。

(2) 新しく開いたブラウザタブを表示。

(3) 「Graph Editor」の中央にある「Edit Action Graph」をクリック。

(4) リストに表示されているグラフを1つだけ選択。

(5) 配列を選択し、「Stage」タブと「Property」タブで、各配列ノードに関連付けられた値を確認。

グラフ内の「Articulation Controller」オブジェクトを選択して、そのプロパティを確認。

3. Extensions

3-1. ステージにロボットを追加

(1) 「Script Editor」で「Tab → Add Tab」。
(2) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

import carb
from isaacsim.core.prims import Articulation
from isaacsim.core.utils.stage import add_reference_to_stage
from isaacsim.storage.native import get_assets_root_path
import numpy as np

assets_root_path = get_assets_root_path()
if assets_root_path is None:
    carb.log_error("Could not find Isaac Sim assets folder")
usd_path = assets_root_path + "/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd"
prim_path = "/World/Arm"

add_reference_to_stage(usd_path=usd_path, prim_path=prim_path)
arm_handle = Articulation(prim_paths_expr=prim_path, name="Arm")
arm_handle.set_world_poses(positions=np.array([[0, -1, 0]]))

3-2. ロボットの確認

「Isaac Sim Core API」には、ロボットに関する情報を取得するための関数呼び出しが多数あります。以下に、ジョイントの数と名前、各種ジョイントプロパティ、そしてジョイント状態を取得する例をいくつか示します。

(1) 「Play」ボタンをクリック。
以降のコマンドを実行するには、物理​​演算が実行中である必要があります。

(2) 「Script Editor」で「Tab → Add Tab」。
(3) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

# 関節数の取得
num_joints = arm_handle.num_joints
print("Number of joints: ", num_joints)

# 感説明の取得
joint_names = arm_handle.joint_names
print("Joint names: ", joint_names)

# 関節制限の取得
joint_limits = arm_handle.get_dof_limits()
print("Joint limits: ", joint_limits)

# 関節位置の取得
joint_positions = arm_handle.get_joint_positions()
print("Joint positions: ", joint_positions)

「Play」ボタンを押すと、シミュレーション実行中でも状態が一度しか出力されないことに注意してください。より最近の状態を確認したい場合は、「Play」ボタンを押し続けてください。物理ステップごとに出力される情報を確認したい場合は、各物理ステップで実行される物理コールバックにこれらのコマンドを挿入する必要があります。

3-3. 物理コールバックにコマンドを挿入

(1) 「Script Editor」で「Tab → Add Tab」。
(2) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

import asyncio
from isaacsim.core.api.simulation_context import SimulationContext

async def test():
    def print_state(dt):
        joint_positions = arm_handle.get_joint_positions()
        print("Joint positions: ", joint_positions)
    simulation_context = SimulationContext()
    await simulation_context.initialize_simulation_context_async()
    await simulation_context.reset_async()
    simulation_context.add_physics_callback("printing_state", print_state)

asyncio.ensure_future(test())

物理ステップごとにターミナルに情報が表示されます。

物理ステップごとの出力が不要になった場合は、以下のコードを実行して物理コールバックを削除できます。

(3) 「Script Editor」で「Tab → Add Tab」。
(4) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

simulation_context = SimulationContext()
simulation_context.remove_physics_callback("printing_state")

3-4. ロボットの制御

「Isaac Sim」では、ロボットを制御する方法が数多くあります。最も基本的な方法は、位置、速度、および力を設定するための直接ジョイントコマンドを送信することです。以下は、関節レベルで「Articulation API」を使用してロボットを制御する方法の例です。

「Script Editor」で新しいタブを開き、以下のコードをコピー&ペーストしてください。これは、arm_handle が既に設定されている、ロボットを追加する前のステップの後でのみ実行できます。コードを実行する前に「Play」ボタンを押してください。これらのコマンドが機能するには、物理​​演算が実行されている必要があります。切り替え可能な2つのポジションが用意されています。上記のプリント状態コードを各物理演算ステップに追加した場合、ロボットの動きに合わせてプリントされたジョイント番号が変化するのを確認できます。

(1) 「Script Editor」で「Tab → Add Tab」。
(2) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

# すべての関節位置にランダムを設定
arm_handle.set_joint_positions([[-1.5, 0.0, 0.0, -1.5, 0.0, 1.5, 0.5, 0.04, 0.04]])

(3) 「Script Editor」で「Tab → Add Tab」。
(4) 「Script Editor」に以下のコードをコピー&ペーストし、「Run」ボタンをクリック。

# すべての関節位置に0を設定
arm_handle.set_joint_positions([[0.0, 0.0, 0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])

上記の get_joint_positions 関数と同様に、ここでの set_joint_positions 関数は「Play」が押されたときに一度だけ実行されます。物理ステップごとにコマンドを送信したい場合は、これらのコマンドを各物理ステップで実行される物理コールバックに挿入する必要があります。

4. Standalone Python

4-1. 起動

スクリプトは「standalone_examples/tutorials/getting_started_robot.py」にあります。

(1) スクリプトの実行。

・Linux

./python.sh standalone_examples/tutorials/getting_started_robot.py

・Windows

python.bat standalone_examples\tutorials\getting_started_robot.py

4-2. コードの説明

「getting_started_robot.py」の14行目から50行目は、シーンをセットアップし、ロボットをステージに追加します。スクリプトは、まず必要なモジュールをインポートし、地面を追加し、カメラアングルを設定し、2つのロボット (アームとモバイル) をシーンに追加します。これらの追加には、Extensionsワークフローで使用されるのと同じAPIを使用します。

以降では、ExtensionsワークフローのPythonとStandalone Pythonの主な違いについて説明します。

・トップからのシミュレータの起動

    from isaacsim import SimulationApp
    simulation_app = SimulationApp({"headless": False})  # GUIを開いた状態でシミュレーションアプリを起動

・World オブジェクトの使用

    my_world = World(stage_units_in_meters=1.0)

World オブジェクトについては、「Core API」の概要で詳しく説明します。今のところは、物理演算やレンダリングのステップ、オブジェクトハンドルの保持など、仮想世界に関するあらゆる制御を行うオブジェクトと考えてください。

・シミュレーションを明示的にステップ実行
スクリプトの下部にはループがあり、ステップ関数 my_world.step() がイテレーションごとに呼び出されます。このステップ関数内で、レンダリングと物理演算が一定回数分進められます。

スクリプトは4サイクル実行され、各サイクルでアームと車が移動または停止します。車の関節位置は、最後のサイクルの各物理演算ステップで出力されます。

    for i in range(4):
        print("running cycle: ", i)
        if i == 1 or i == 3:
            print("moving")
            # move the arm
            arm.set_joint_positions([[-1.5, 0.0, 0.0, -1.5, 0.0, 1.5, 0.5, 0.04, 0.04]])
            # move the car
            car.set_joint_velocities([[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]])
        if i == 2:
            print("stopping")
            # reset the arm
            arm.set_joint_positions([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
            # stop the car
            car.set_joint_velocities([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])

        for j in range(100):
            # step the simulation, both rendering and physics
            my_world.step(render=True)
            # print the joint positions of the car at every physics step
            if i == 3:
                car_joint_positions = car.get_joint_positions()
                print("car joint positions:", car_joint_positions)

get_joint_positions 関数と set_joint_positions 関数は、Extension ワークフローで使用されるものと同じですが、ステップ実行が明示的であるため、これらのコマンドはループの一部として存在し、デフォルトで物理演算ステップごとに実行されます。これが、Extension ワークフローと Standalone Python ワークフローの主な違いです。

【おまけ】チュートリアル参照表

「Isaac Sim」では次のチュートリアルが利用可能です。

Core API Tutorial Series
「Isaac Sim Core Python API」を使用してシミュレーション環境を操作し、ロボットを制御するための入門チュートリアル。

Robot Setup Tutorials Series
「Isaac Sim」でのロボットの組み立てとアセットの最適化に関する入門チュートリアル

Importer and Exporter Tutorial Series
「Isaac Sim」で URDF、USD、CAD インポーターと URDF エクスポーターを使いアセットをインポートおよびエクスポートするためのチュートリアル

Isaac Lab Tutorials
「Isaac Sim」の強化学習チュートリアル

ROS Tutorial Series
「Isaac Sim」によるROS 2ブリッジと統合のチュートリアル

Synthetic Data Generation Tutorials
「Isaac Sim」による合成データ生成チュートリアル

Sensor Tutorials
「Isaac Sim」で「RTX」と「PhysX センサー」を使用するためのチュートリアル

Motion Generation Tutorial Series
「Isaac Sim」でモーション生成を使用するためのチュートリアル

Omnigraph Tutorials
「Omnigr」の使い方チュートリアル

次回



いいなと思ったら応援しよう!