StableIDMap for LidarRTX has missing object_ids

6.0.0
5.1.0
5.0.0
4.5.0
4.2.0
4.1.0
4.0.0
4.5.0
2023.1.1
2023.1.0-hotfix.1
Other (please specify):

Operating System

Ubuntu 24.04
Ubuntu 22.04
Ubuntu 20.04
Windows 11
Windows 10
Other (please specify):

GPU Information

  • Model: 6000 ADA
  • Driver Version: 580.126.09

Topic Description

Detailed Description

When Recording Scenes with the LidarRTX for some assets I get object IDs that are not in the StableIDMap. Therefore, I cant map to which prim they belong. I have seen this for different objects from the nvidia isaac sim library but it is very prevelant in the conveyors.

Steps to Reproduce

  1. Copy into run.sh

    #!/bin/bash
    
    # Get the path to the workspace directory
    SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
    PATH_WS=$(realpath "$SCRIPT_DIR/")
    
    set -e
    
    IMAGE_NAME="nvcr.io/nvidia/isaac-sim:5.1.0"
    
    # run container
    echo "Starting docker image"
    xhost +
    docker run --rm -it \
         --name synthetic-data-generator --runtime=nvidia --gpus all  --network=host \
         --entrypoint bash \
         -e "ACCEPT_EULA=Y" \
         -e "PRIVACY_CONSENT=Y" \
         -e DISPLAY=$DISPLAY \
         -e ISAAC_SIM_EXTENSION_PATH="$ISAAC_SIM_EXTENSION_PATH:/workspace" \
         -e "OMNI_USER=admin" \
         -e "OMNI_PASS=admin" \
         -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
         -v $HOME/.Xauthority:/home/admin/.Xauthority:rw \
         -v ~/docker/isaac-sim/cache/kit:/isaac-sim/kit/cache:rw \
         -v ~/docker/isaac-sim/cache/ov:/root/.cache/ov:rw \
         -v ~/docker/isaac-sim/cache/pip:/root/.cache/pip:rw \
         -v ~/docker/isaac-sim/cache/glcache:/root/.cache/nvidia/GLCache:rw \
         -v ~/docker/isaac-sim/cache/computecache:/root/.nv/ComputeCache:rw \
         -v ~/docker/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw \
         -v ~/docker/isaac-sim/data:/root/.local/share/ov/data:rw \
         -v ~/docker/isaac-sim/documents:/root/Documents:rw \
         -v $PATH_WS:/workspace:rw \
         -w /workspace \
         $IMAGE_NAME \
         /isaac-sim/python.sh /workspace/minimal_recorder.py -c "$CONFIG"
    
  2. Copy into minimal_recorder.py in same directory.

    import numpy as np
    
    from isaacsim.simulation_app import SimulationApp
    
    launch_config = {
    "width": 1920,
    "height": 1080,
    "headless": False,
    }
    simulation_app = SimulationApp(launch_config=launch_config)
    
    # Enable stable IDs for object ID tracking
    import carb
    settings = carb.settings.get_settings()
    settings.set("/rtx-transient/stableIds/enabled", True)
    print("Enabled /rtx-transient/stableIds/enabled=true")
    
    warehouse_file_path = "/workspace/FlattendComposedWarehouse.usd"
    
    
    from isaacsim.sensors.rtx import LidarRtx, get_gmo_data
    import omni
    
    # -- Load the stage
    from isaacsim.core.utils.stage import open_stage
    open_stage(warehouse_file_path)
    
    # -- Initialize the LidarRtx
    additional_attrs = {"omni:sensor:Core:auxOutputType": "FULL",
                            "omni:sensor:Core:elementsCoordsType": "CARTESIAN",
                            "omni:sensor:Core:outputFrameOfReference": "WORLD",
                            "omni:sensor:Core:scanType": "ROTARY",
                            "omni:sensor:Core:scanRateBaseHz": 60,
                            # "omni:sensor:Core:numberOfChannels": 128,
                            "omni:sensor:Core:intensityProcessing": "NORMALIZATION",
                            "omni:sensor:Core:farRangeM": 200,
                            "omni:sensor:Core:nearRangeM": 0.3,
                            "omni:sensor:Core:rangeAccuracyM": 0.01,
                            }
    
    lidar = LidarRtx(
        prim_path=f"/lidar_1",
        name="lidar_1",
        position=(0, 0, 0.8),
        **additional_attrs,
    )
    lidar.initialize()
    lidar.attach_annotator("GenericModelOutput")
    lidar.attach_annotator("StableIdMap")
    
    timeline = omni.timeline.get_timeline_interface()
    if not timeline.is_playing():
        timeline.play()
    
    settle_frames = 64
    print(f"Warming up rendering pipeline ({settle_frames} frames)...")
    for _ in range(settle_frames):
        omni.kit.app.get_app().update()
    
    frame = lidar.get_current_frame()
    
    # Read out the frame data
    gmo_buffer = frame.get("GenericModelOutput")
    gmo_data = get_gmo_data(gmo_buffer)
    
    # Read out object IDs
    obj_ids = np.array(LidarRtx.get_object_ids(gmo_data.objId))
    unique_obj_ids = np.unique(obj_ids)
    print(f"Unique Object IDs in the frame: {unique_obj_ids}")
    
    stable_id_map_buffer = lidar.get_current_frame()["StableIdMap"]
    stable_id_map = LidarRtx.decode_stable_id_mapping(stable_id_map_buffer.tobytes())
    # print(f"Stable ID Map: {stable_id_map}")
    
    total_affected_points = 0
    for id in unique_obj_ids:
        if id != 0 and id not in stable_id_map:
            print(f"Object ID {id} not found in stable ID map affecting {np.sum(obj_ids == id)} points.")
            total_affected_points += np.sum(obj_ids == id)
    
    print(f"Total points affected by missing stable ID mapping: {total_affected_points}/{np.sum(obj_ids != 0)}")
    
    while True:
        omni.kit.app.get_app().update()
    
    # Close SimulationApp gracefully
    simulation_app.close()
    
  3. pull nvcr.io/nvidia/isaac-sim:5.1.0

  4. Download the simple Scene and save to FlattendComposedWarehouse in same directory as the scripts:
    FlattendComposedWarehouse.zip (16.0 MB)

Output:

Thanks for raising this issue. I am able to replicate this issue with the provided files.

Total LiDAR points: 153,600
Points with object ID: 72,192
Unique Object IDs in frame: 26
StableIdMap entries: 19

IDs in StableIdMap: 18
IDs MISSING from StableIdMap: 7
Affected points: 572/72,192 (0.8%)

7 object IDs returned by the LiDAR have no corresponding entry in the StableIdMap.

By comparing the StableIdMap entries against all USD Mesh prims in the scene:
• 18 mesh prims in the flattened scene (15 floor tiles + 3 conveyor sub-meshes)
• 19 StableIdMap entries (all 18 meshes + the conveyor parent Xform)
• 0 mesh prims are missing from the StableIdMap

Every USD prim in the scene IS mapped. However, the LiDAR still returns 7 object IDs that don’t correspond to any USD prim. These are phantom IDs created by the RTX renderer’s internal geometry processing.

The RTX ray-tracing engine internally subdivides meshes into sub-geometry for its acceleration structures (BVH leaf nodes, mesh sections). These internal subdivisions receive their own stable IDs, but those IDs are never registered in the StableIdMap because they don’t correspond to USD prims. When LiDAR rays hit these internal geometry pieces, they return IDs that have no mapping.

This is more prevalent with complex geometry like conveyors (belts, rollers, decals) where the renderer creates more internal subdivisions.

Workaround
For affected points, you can map unknown IDs to the spatially nearest known prim.
Alternatively, treat unmapped IDs as “unknown” and filter them out if your pipeline requires prim association.

I will also raise this up internally and see if we can provide a better fix.

Hello Zhengwang,

thank you for your response and taking the time to look into it. Using your suggested workaround, I can make it work, but it might lead to a few points being wrongly associated which is acceptable for the short term.

I would appreciate getting updates on any new developments.

Thanks,

Sven

1 Like

I will let you know if this issue is fixed. Thanks for your patience!

1 Like