isaac-sim-sensor について
isaac-sim-sensor は、Isaac Sim 6 / Kit 110 でセンサーや合成データのパイプラインを構築する技術スキルです。RTX・物理センサー、Replicator のワークフロー、ベンダー設定、データ Writer を扱います。
主な機能
- 01カメラセンサーとアノテーターの作成
- 02RTX LiDAR、レーダー、音響センサーの設定
- 03IMUや接触などの物理センサー追加
- 04Replicatorによるドメインランダム化
- 05Writerによるセンサー出力の取得
活用シーン
- 01カメラのRGB、深度、セグメンテーションの取得
- 02ベンダー製LiDARとIMUのロボットへの取り付け
- 03フレーム欠落を避けたレーダーや音響データの収集
- 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.pycreate_camera_sensor.pylidar_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 の例/SDG | isaacsim.replicator.examples |
| 移動ロボット向け SDG | isaacsim.replicator.mobility_gen |
| 把持向け SDG | isaacsim.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.py | RTX Ouster LiDAR と物理 IMU をロボットのシャーシに取り付けます | スクリプトの --help を参照 |
scripts/create_camera_sensor.py | Isaac Sim Replicator でカメラセンサーを作成し、アノテーターを取り付けます | スクリプトの --help を参照 |
scripts/lidar_gmo_writer.py | Isaac 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/ 以下のアセットパス) |
|---|---|
| NVIDIA | NVIDIA/Example_Rotary.usda、Example_Rotary_2D.usda、Example_Solid_State.usda、Simple_Example_Solid_State.usda |
| Ouster | Ouster/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 解像度) |
| Hesai | HESAI/XT32_SD10/HESAI_XT32_SD10.usd(追加アセットを通じて Pandar シリーズも利用できます) |
| Velodyne | VLP/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. ワークフロー
| ワークフロー | モジュール/例 |
|---|---|
| ランダム化を使用した静的シーンのSDG | data-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=...)を使用する旧来の方法も引き続き許容されますが、現行のドキュメントで推奨されている方法ではありません。