mcpField
I
isaac-sim-sensor

isaac-sim-sensor

github.com/isaac-simその他4.4k40 回インストール5 日前に更新
リポジトリ

isaac-sim-sensor について

isaac-sim-sensor は、Isaac Sim 6 / Kit 110 でセンサーや合成データのパイプラインを構築する技術スキルです。RTX・物理センサー、Replicator のワークフロー、ベンダー設定、データ Writer を扱います。

主な機能

  1. 01カメラセンサーとアノテーターの作成
  2. 02RTX LiDAR、レーダー、音響センサーの設定
  3. 03IMUや接触などの物理センサー追加
  4. 04Replicatorによるドメインランダム化
  5. 05Writerによるセンサー出力の取得

活用シーン

  1. 01カメラのRGB、深度、セグメンテーションの取得
  2. 02ベンダー製LiDARとIMUのロボットへの取り付け
  3. 03フレーム欠落を避けたレーダーや音響データの収集
  4. 04ランダム化した合成センサーデータの生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/isaac-sim/isaacsim --skill isaac-sim-sensor

インストール後、Claude Code で/isaac-sim-sensorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
attach_lidar_imu.py
create_camera_sensor.py
lidar_gmo_writer.py

詳細

Omniverse センサーシミュレーション

目的

Replicator と実験的なセンサー API を使って、RTX カメラ、LiDAR、レーダー、音響センサー、物理センサーをシミュレートします。ベンダー設定とマウントへの取り付けにも対応します。

前提条件

  • Isaac Sim をビルド済み($ISAAC_SIM_DIR または _build/linux-x86_64/release)。
  • NVIDIA GPU と最新のドライバー(nvidia-smi)。
  • isaac-sim-orchestrator のシェル環境変数の契約:$ISAAC_SIM_DIR、$ISAAC_LAB_DIR、$WORKSPACE_DIR。

制限事項

  • 別途記載がない限り、Isaac Sim 6 / Kit 110 を対象とします。
  • サポート対象外のエッジケースについては、NVIDIA の公式ドキュメントに代わるものではありません。

トラブルシューティング

エラー/症状原因解決策
拡張機能またはインポートが見つからない$ISAAC_SIM_DIR の誤り、または古いビルド環境変数を _build/linux-x86_64/release に設定するか、再ビルドしてください
フレームが黒い、または空ライトがない、または RTX 以外のレンダリングモードドームライト/キーライトを追加し、RTX/PathTracing の設定を確認してください
ステージの読み込み時または初回レンダリング時にハングするMDL のコンパイル、またはステージが大きすぎるisaac-sim-troubleshooting の切り分け手順に従ってください

カメラ(RGB/深度/セグメンテーション/バウンディングボックス)、LiDAR/レーダー/音響センサー、IMU/接触/力センサー、および Replicator によるドメインランダム化に対応します。Isaac Sim 6 / Kit 110 を対象とします。

新しいコードでは、最新の名前空間を使用してください。

ファミリーモジュール
RTX センサー(LiDAR、レーダー、音響センサー、RTX カメラ)isaacsim.sensors.experimental.rtx
物理センサー(接触、IMU、力、関節状態、レイキャスト)isaacsim.sensors.experimental.physics
Replicator コアomni.replicator.core as rep
Replicator の例/SDGisaacsim.replicator.examples
移動ロボット向け SDGisaacsim.replicator.mobility_gen
把持向け SDGisaacsim.replicator.grasping
エピソードの記録/再生isaacsim.replicator.episode_recorder
テレオペレーションの記録/再生isaacsim.replicator.teleop
ドメインランダム化ヘルパーisaacsim.replicator.domain_randomization

従来の isaacsim.sensors.physics.* クラスと isaacsim.sensors.camera.Camera クラスも引き続き読み込めますが、実装は experimental.* 拡張機能に移行しています。新しい開発ではそちらを優先してください。

移行: ファミリーごとの移行ガイドに従ってスクリプトを更新してください。物理センサー、カメラセンサー、RTX センサー(LiDAR/レーダー/音響センサー)。

利用可能なスクリプト

スクリプト目的引数
scripts/attach_lidar_imu.pyRTX Ouster LiDAR と物理 IMU をロボットのシャーシに取り付けますスクリプトの --help を参照
scripts/create_camera_sensor.pyIsaac Sim Replicator でカメラセンサーを作成し、アノテーターを取り付けますスクリプトの --help を参照
scripts/lidar_gmo_writer.pyIsaac Sim 向け RTX Lidar GMO(GenericModelOutput)ライターのパターンスクリプトの --help を参照

スクリプトの実行

スキル実行ヘルパーを利用できるエージェントランタイムからは、run_script() でヘルパーを呼び出してください。

run_script("scripts/create_camera_sensor.py", args=["--help"])

ビルド済みの Isaac Sim ツリーからは、_build/*/release にある ./python.sh(Linux)または python.bat(Windows)を使って同じファイルを実行してください。シミュレーターを必要としない場合は、シェルヘルパーを直接実行することもできます。

関連スキル

  • isaac-camera:RtxCamera/CameraSensor、キャリブレーション、歪みについて詳しく説明します。
  • isaac-sim-rendering:ヘッドレスキャプチャパイプライン、RT2、ACES トーンマップ。
  • physics-simulation:シーン設定と物理センサー(Contact、IMU など)。
  • data-collection-sim:静的シーンの SDG ライターパイプライン。
  • mobility-gen:移動ロボット向けの軌道駆動型 SDG。

0. ベンダーセンサーカタログ(SUPPORTED_LIDAR_CONFIGS)

isaacsim.sensors.experimental.rtx.SUPPORTED_LIDAR_CONFIGS は、ベンダー製の LiDAR/レーダー/音響 USD アセットの正式なレジストリです。キーは get_assets_root_path() + "/Isaac/Sensors/..." 以下のアセットパスで、値はフラットなバリアント名の set("sensor" バリアントセットに対するもの)または明示的な {variant_set: value} 辞書のリストです。関連する定数 SUPPORTED_LIDAR_VARIANT_SET_NAME = "sensor" は、デフォルトのバリアントセット名を示します。

メーカーモデル(/Isaac/Sensors/ 以下のアセットパス)
NVIDIANVIDIA/Example_Rotary.usda、Example_Rotary_2D.usda、Example_Solid_State.usda、Simple_Example_Solid_State.usda
OusterOuster/OS0/OS0.usd、OS1/OS1.usd、OS2/OS2.usd、VLS_128/Ouster_VLS_128.usd(rev6/rev7 バリアント、32/128ch、10/20 Hz、512/1024/2048 解像度)
HesaiHESAI/XT32_SD10/HESAI_XT32_SD10.usd(追加アセットを通じて Pandar シリーズも利用できます)
VelodyneVLP/HDL シリーズ(Velodyne/ 以下)
Robosense、SICK、Zvision、その他レジストリ/ベンダーフォルダーを参照してください

深度カメラ/ステレオカメラ(Intel RealSense D415/D435/D455/L515、Stereolabs ZED 2/2i/Mini/X)には、カメラスタイルの RtxCamera ラッパーと SingleViewDepthCameraSensor を使用してください。詳細は isaac-camera を参照してください。

Lidar.create(config=, variant=) は短縮形です。config はパスと拡張子を除いたレジストリキーで、variant は複数のバリアントを公開するアセット(Ouster OS*、Hesai Pandar など)で必須です。

0.1 ロボットマウントへのベンダーセンサーの取り付け

USDA(ルートシーン)
over "Robot" {
    def Xform "sensor_mount" {
        double3 xformOp:translate = (0.0, 0.0, 0.35)
        uniform token[] xformOpOrder = ["xformOp:translate"]

        def "lidar" (
            prepend references = @${assetsRoot}/Isaac/Sensors/Ouster/OS1/OS1.usd@
            variants = { string sensor = "OS1_REV6_32ch20hz512res" }
        ) {}
    }
}
Python
from pxr import UsdGeom, Gf
from isaacsim.storage.native import get_assets_root_path

assets_root = get_assets_root_path()
mount = UsdGeom.Xform.Define(stage, "/World/Robot/sensor_mount")
UsdGeom.Xformable(mount.GetPrim()).AddTranslateOp().Set(Gf.Vec3d(0, 0, 0.35))

sensor_prim = stage.DefinePrim("/World/Robot/sensor_mount/lidar")
sensor_prim.GetReferences().AddReference(
    assets_root + "/Isaac/Sensors/Ouster/OS1/OS1.usd"
)
vset = sensor_prim.GetVariantSets().GetVariantSet("sensor")
vset.SetVariantSelection("OS1_REV6_32ch20hz512res")

# Or use Lidar.create() at the mount path — it does both for you and
# returns the wrapper for runtime usage.

0.2 カスタムスキャンパターン(USDA エミッターステート配列)

SUPPORTED_LIDAR_CONFIGS にないカスタムセンサーの場合は、OmniSensorGenericLidarCoreAPI とエミッターステート配列を使って USDA プリムを定義します。各ビームは方位角、仰角、発射時刻のエントリーで記述されます。ソリッドステート LiDAR では、配列の要素数が数万に達することがあります。

def Xform "Lidar" (
    prepend apiSchemas = ["OmniSensorGenericLidarCoreAPI"]
)
{
    float minRange = 0.1
    float maxRange = 120.0
    float horizontalFov = 360.0
    float horizontalResolution = 0.1
    float verticalFov = 45.0
    float verticalResolution = 1.0

    # Emitter state arrays define exact beam directions and timing.
    float[] omni:sensor:Core:emitterState:s001:azimuthDeg   = [0.0, 0.1, 0.2, ...]
    float[] omni:sensor:Core:emitterState:s001:elevationDeg = [-22.5, -20.0, ...]
    int[]   omni:sensor:Core:emitterState:s001:fireTimeNs   = [0, 55, 110, ...]

    bool highLod    = true
    bool drawPoints = false
}

Python からカスタムプリムをラップするには、Lidar("/World/.../my_lidar")(config= 引数なし)を呼び出します。コンストラクターはプリムを新規作成するのではなく、既存のプリムをラップします。

1. カメラ(複数 AOV のキャプチャ)

RtxCamera と CameraSensor は、カメラの作成/キャプチャに使用する方法です(RTX 以外での作成方法はサポートされていません)。全機能については isaac-camera を参照してください。

create_camera_sensor(path, focal_length, resolution, annotators=None) — RtxCamera を作成し、.camera ラッパー経由で光学パラメーターを設定して、CameraSensor を返します(レンダープロダクトが構築され、標準の RGB/深度/セグメンテーション/バウンディングボックス/法線/モーションベクターのアノテーターがアタッチされます)。attach_annotators(sensor, annotators) — 既存のセンサーに AOV を追加するための、CameraSensor.attach_annotators の薄いラッパーです。resolution は OpenCV/NumPy の (height, width) 規約に従います。

scripts/create_camera_sensor.py を参照してください。

タイル状のマルチビュー/ステレオ/レンズ歪みには、isaacsim.sensors.experimental.rtx.{TiledCameraSensor, SingleViewDepthCameraSensor, RtxCamera} を使用してください。

2. Lidar(RTX)— Writer ベースの GMO 消費

RTX センサー(Lidar、Radar、Acoustic)はすべて GenericModelOutput(GMO)バッファーを生成します。このバッファーはセンサースケジューラーによって、マルチティック中に非同期で出力されます。連続する simulation_app.update() / app_utils.update() の呼び出しの間に、GMO フレームが 0 個または複数届く場合があります。毎ティック sensor.get_data("generic-model-output") をポーリングすると、フレームが欠落したり重複したりします。

GMO には Writer を使用してください。 Replicator スケジューラーは、生成されたレンダープロダクトごとに Writer.write を呼び出すため、コンシューマーはイベントを漏れなく受け取れます。このパターンは、すべての標準的な source/standalone_examples/api/isaacsim.sensors.experimental.rtx/* の例(inspect_lidar_gmo.py、inspect_radar_gmo.py、inspect_acoustic_gmo.py、lidar_robot_integration.py、resolve_lidar_object_ids.py、apply_nonvisual_materials.py)で使用されています。以下のパターンは、Radar / RadarSensor(セクション 3)と Acoustic / AcousticSensor(セクション 4)にもそのまま適用できます。

create_lidar_with_gmo_writer(path, config, variant, simulation_app) — RTX lidar を作成し、GenericModelOutput アノテーターをアタッチする GmoInspectWriter を定義して登録し、更新ループを実行します。

scripts/lidar_gmo_writer.py を参照してください。

データ取得ではなく、ビューポートでリアルタイムに可視化する場合は、組み込みの draw-point-cloud writer を代わりにアタッチしてください。

sensor.attach_writer("draw-point-cloud", size=0.05, color=[0, 1, 0.5, 1.0])

isaacsim.sensors.experimental.rtx の GMO デコード用ヘルパー:parse_generic_model_output_data、parse_stable_id_map_data、parse_object_ids、draw_annotator_data_to_image。

lidar スキャンの ROS 2 パブリッシュについては、isaac-sim-ros2-bridge(ROS2PublishLaserScan、ROS2PublishPointCloud)を参照してください。

3. Radar(RTX)

from isaacsim.sensors.experimental.rtx import Radar, RadarSensor
radar  = Radar("/World/radar", tick_rate=20.0, aux_output_level="BASIC")
sensor = RadarSensor(radar, annotators=[])

GMO を消費するには Writer をアタッチしてください(セクション 2 を参照)。Motion BVH を有効にする必要があります(SimulationApp の初期化時に enable_motion_bvh=True を指定するか、/renderer/raytracingMotion/enabled=true を設定します)。

4. Acoustic(RTX、超音波)

from isaacsim.sensors.experimental.rtx import Acoustic, AcousticSensor

acoustic = Acoustic(
    "/World/acoustic",
    tick_rate=30.0,
    aux_output_level="BASIC",
    attributes={
        "omni:sensor:WpmAcoustic:centerFrequency": 51200.0,
        "omni:sensor:WpmAcoustic:sensorMount:m001:position": (0.0, 0.0, 0.0),
    },
)
sensor = AcousticSensor(acoustic, annotators=[])

GMO を消費するには Writer をアタッチしてください(セクション 2 を参照)。Acoustic GMO はシグナルの経路を次のようにエンコードします。gmo.x は送信機マウント ID、gmo.y は受信機マウント ID、gmo.z はチャネル ID、gmo.scalar は振幅です。

5. IMU(物理)

from isaacsim.sensors.experimental.physics import IMU, IMUSensor
import isaacsim.core.experimental.utils.app as app_utils

imu = IMU.create(path="/World/Robot/imu", tick_rate=200.0)
sensor = IMUSensor(imu, annotators=["linear_acceleration",
                                    "angular_velocity",
                                    "orientation"])
app_utils.play(commit=True)
frame = sensor.get_data()                # IMUSensorReading

6. 接触/力(物理)

from isaacsim.sensors.experimental.physics import Contact, ContactSensor
contact = Contact.create(
    path="/World/Robot/foot/contact",
    min_threshold=0.0, max_threshold=1e6, radius=-1,   # -1 = collision shape
)
sensor = ContactSensor(contact)
frame = sensor.get_data()

EffortSensor と JointStateSensor(同じモジュール)は実行時専用です。既存のジョイント prim をパスでラップし、app_utils.play(commit=True) の後に get_data() を呼び出してください。これらには個別のオーサリングクラスはありません。ジョイントは URDF/MJCF のインポート時にすでに作成されています。

from isaacsim.sensors.experimental.physics import EffortSensor, JointStateSensor

effort = EffortSensor("/World/Robot/joint_arm_1")
joint  = JointStateSensor("/World/Robot/joint_arm_1")

7. Replicator のドメインランダム化

rep.functional.modify.semantics(最新の関数型 API)または isaacsim.core.experimental.utils.semantics.add_labels による prim ごとの UsdSemantics スキーマを使って、prim をランダム化の対象として指定します。その後、rep.new_layer() トリガーでランダム化を実行します。

import omni.replicator.core as rep

with rep.new_layer():
    # Lights tagged with semantic ("type", "light")
    lights = rep.get.prims(semantics=[("type", "light")])
    with rep.trigger.on_frame(num_frames=100):
        with lights:
            rep.modify.attribute("intensity",
                                 rep.distribution.uniform(500, 5000))
            rep.modify.attribute("color",
                                 rep.distribution.uniform((0.8,)*3, (1.0,)*3))

    # Material swap on objects tagged ("class", "box")
    objects = rep.get.prims(semantics=[("class", "box")])
    with rep.trigger.on_frame():
        with objects:
            rep.randomizer.materials(rep.get.material("OmniPBR.*"))

rep.orchestrator.run()

あらかじめ用意されたランダム化動作(散布、ジッター、環境の切り替え)については、isaacsim.replicator.domain_randomization と isaacsim.replicator.examples のスタンドアロン例を参照してください。

8. Writers

omni.replicator.core には BasicWriter、KittiWriter、CosmosWriter が含まれています。isaacsim.replicator.writers には PoseWriter と DataVisualizationWriter が追加されています。非推奨:DOPEWriter、YCBVideoWriter、PytorchWriter。

import omni.replicator.core as rep

writer = rep.WriterRegistry.get("KittiWriter")
writer.initialize(
    output_dir="/output/synthetic_dataset",
    semantic_types=["class"],
    write_binary_pointcloud=False,
    mapping={"box": "Car", "pallet": "Misc"},
)
writer.attach([render_product])

9. ワークフロー

ワークフローモジュール/例
ランダム化を使用した静的シーンのSDGdata-collection-sim スキル + isaacsim.replicator.examples(sdg_getting_started_0[1-5].py、sdg_workflow_0[12].py)
モバイルロボットの軌道の記録と再生mobility-gen スキル + isaacsim.replicator.mobility_gen
把持データセットの生成isaacsim.replicator.grasping(GraspingManager、GraspPhase) — source/standalone_examples/api/isaacsim.replicator.grasping/grasping_workflow_sdg.py を参照
エピソードの記録と再生isaacsim.replicator.episode_recorder
テレオペレーションの記録と再生isaacsim.replicator.teleop
Cosmos 倉庫のレンダリングisaacsim.replicator.examples/cosmos_writer_simple.py および source/standalone_examples/replicator/cosmos_writer_warehouse.py

注意点

  • RTX-GMO センサー(lidar、radar、acoustic)では、get_data ではなく Writer を使用します。 マルチティック時、センサースケジューラーは simulation_app.update() とは非同期に GMO フレームを出力します。sensor.get_data("generic-model-output") をポーリングすると、フレームが欠落したり重複したりします。attach_writer はイベント駆動型で、すべての出力を受け取ります。sensor.get_data(...) は、CameraSensor のカメラ AOV(rgb、distance_to_image_plane、...)および物理センサー(IMU、Contact、Effort、JointState)で引き続き、ドキュメントに記載された方法として使用できます。
  • Lidar.create(config=..., variant=...) は、複数のセンサーバリアントを公開するアセットでは、バリアントの指定が必要です。レジストリ値から、使用可能なバリアントのセットを確認できます。
  • aux_output_level のレベルはモダリティごとに異なります。lidar は NONE/BASIC/EXTRA/FULL に対応し、radar と acoustic は NONE/BASIC のみ、RtxCamera は NONE のみに対応します。
  • High-LOD(highLod=true)モードでは点群が増えますが、処理が遅くなります。ヘッドレスモードでパフォーマンスを向上させるには、drawPoints=false を設定してください。
  • aux_output_level が設定されていると、「無害な」usdrt.population.plugin Unhandled attribute type VtArray<std::string> ログメッセージが表示されますが、これは想定どおりです。Replicator パイプラインは引き続きこの属性を取得します。
  • rep.orchestrator.run() を呼び出す前に、Replicator のアノテーターをアタッチしてください。
  • isaacsim.sensors.experimental.rtx を読み込むと RTX センサーによって omni.sensors.nv.lidar/.nv.radar/.nv.acoustic が自動的に有効になります。手動で有効にする必要はありません。
  • 物理センサーで get_data() を呼び出す前に、app_utils.play(commit=True)(または timeline.play())が必要です。タイムラインが一時停止している間、センサーはデータをストリーミングしません。
  • ランダム化トリガーは蓄積されます。各パスを分離するには rep.new_layer() を使用してください。
  • 最新の関数型 API では rep.functional.modify.semantics(prim, {"class": "..."}, mode="add") を使用してください。prims.create_prim(semantic_label=...) を使用する旧来の方法も引き続き許容されますが、現行のドキュメントで推奨されている方法ではありません。

コメント