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. 02配置 RTX 激光雷达、雷达和声学传感器
  3. 03添加 IMU、接触等物理传感器
  4. 04应用 Replicator 域随机化
  5. 05使用 Writer 接收传感器输出

适用场景

  1. 01采集相机 RGB、深度和分割数据
  2. 02将厂商激光雷达和 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 中的 Shell 环境变量约定:$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.py将 RTX Ouster LiDAR 和物理 IMU 安装到机器人底盘上参见脚本 --help
scripts/create_camera_sensor.py为 Isaac Sim Replicator 创建摄像头传感器并附加标注器参见脚本 --help
scripts/lidar_gmo_writer.pyIsaac Sim 的 RTX LiDAR GMO(GenericModelOutput)写入器模式参见脚本 --help

运行脚本

对于提供技能执行辅助工具的 Agent 运行时,请使用 run_script() 调用辅助工具:

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

在已构建的 Isaac Sim 目录中,从 _build/*/release 使用 ./python.sh(Linux)或 python.bat(Windows)运行同一文件;对于不需要模拟器的脚本,也可以直接运行 Shell 辅助工具。

相关技能

  • 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 是厂商激光雷达/雷达/声学 USD 资产的权威注册表。键是 get_assets_root_path() + "/Isaac/Sensors/..." 下的资产路径;值要么是针对 "sensor" 变体集的扁平变体名称 set,要么是显式 {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/128 通道,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 是去掉路径/扩展名后的注册表键;对于公开多个变体的资产(Ouster OS*、Hesai Pandar 等),必须指定 variant。

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 prim。每束光由一个方位角、仰角和发射时间条目描述;固态激光雷达的数组可能达到数万个条目。

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 封装自定义 prim,请调用 Lidar("/World/.../my_lidar")(不传入 config= 参数);构造函数会封装现有 prim,而不是创建一个新 prim。

1. 摄像头(多 AOV 捕获)

RtxCamera + CameraSensor 是摄像头创建/捕获路径(不支持非 RTX 创建路径)。完整功能说明请参阅 isaac-camera。

create_camera_sensor(path, focal_length, resolution, annotators=None) — 创建 RtxCamera,通过 .camera 封装器设置其光学参数,并返回 CameraSensor(同时创建其渲染产品,并附加标准 RGB/深度/分割/边界框/法线/运动矢量标注器)。attach_annotators(sensor, annotators) — 对 CameraSensor.attach_annotators 的轻量封装,用于向现有传感器添加更多 AOV。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。每个 tick 都轮询 sensor.get_data("generic-model-output") 会导致帧丢失或重复。

使用 Writer 处理 GMO。 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 annotator 的 GmoInspectWriter,注册该 Writer,然后运行更新循环。

请参阅 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。

如需发布 ROS 2 lidar 扫描数据,请参阅 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=[])

附加一个 Writer 来消费 GMO——请参阅第 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=[])

附加一个 Writer 来消费 GMO——请参阅第 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
Episode 录制 + 回放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 传感器(激光雷达、雷达、声学):使用 Writer,而非 get_data。 在 multitick 模式下,传感器调度器会异步于 simulation_app.update() 发出 GMO 帧;轮询 sensor.get_data("generic-model-output") 会丢帧或重复帧。attach_writer 由事件驱动,能够获取每个输出。对于 CameraSensor 的相机 AOV(rgb、distance_to_image_plane 等)以及物理传感器(IMU、Contact、Effort、JointState),sensor.get_data(...) 仍是文档规定的接口。
  • 对于公开多个传感器变体的资源,Lidar.create(config=..., variant=...) 必须指定变体;注册表值会告知可用的变体集合。
  • aux_output_level 的级别因模态而异:激光雷达支持 NONE/BASIC/EXTRA/FULL;雷达 / 声学仅支持 NONE/BASIC;RtxCamera 仅支持 NONE。
  • 高 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;无需手动启用。
  • 物理传感器需要先调用 app_utils.play(commit=True)(或 timeline.play()),再调用 get_data()。时间轴暂停时,传感器不会持续输出数据。
  • 随机化触发器会累积;使用 rep.new_layer() 隔离每次处理。
  • 现代函数式 API 使用 rep.functional.modify.semantics(prim, {"class": "..."}, mode="add");旧版 prims.create_prim(semantic_label=...) 路径仍受支持,但不是当前文档推荐的路径。

评论

支持 Markdown