Randomizing the color of floor in a stage usd inside offline_generation.py

We have parts of this code in offline_generation.py and I want to be able to traverse all the childrens (aka USDs that define the stage so that I can find the floor USD and randomize its color.

I saw the GetAllChildren for traversing through children of a USD but I am not sure how to do this for a Stage.

    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME) # mona score is not used anywhere!!!


    print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
    print("type of stage: ", type(stage))
    print("stage is: ", stage)
    print("type of scope: ", type(scope))
    print("scope is: ", scope)

    print('dir(stage): ', dir(stage))
    print("TraverseAll ", stage.TraverseAll())
    print("Traverse ", stage.Traverse())
    # for child_prim in stage.GetAllChildren():
    #     print(child_prim.GetName())
    #     if 'floor' in child_prim.GetName().lower():
    #         print("floor child name is: ", child_prim.GetName())
    # Spawn a new forklift at a random pose

Here’s the output:

type of stage:  <class 'pxr.Usd.Stage'>
stage is:  Usd.Stage.Open(rootLayer=Sdf.Find('omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd'), sessionLayer=Sdf.Find('anon:0x1a09ba40'), pathResolverContext=None)
type of scope:  <class 'pxr.UsdGeom.Scope'>
scope is:  UsdGeom.Scope(Usd.Prim(</MyScope>))
dir(stage):  ['ClearDefaultPrim', 'ClearMetadata', 'ClearMetadataByDictKey', 'CreateClassPrim', 'CreateInMemory', 'CreateNew', 'DefinePrim', 'ExpandPopulationMask', 'Export', 'ExportToString', 'FindLoadable', 'Flatten', 'GetAttributeAtPath', 'GetColorConfigFallbacks', 'GetColorConfiguration', 'GetColorManagementSystem', 'GetDefaultPrim', 'GetEditTarget', 'GetEditTargetForLocalLayer', 'GetEndTimeCode', 'GetFramesPerSecond', 'GetGlobalVariantFallbacks', 'GetInterpolationType', 'GetLayerStack', 'GetLoadRules', 'GetLoadSet', 'GetMasters', 'GetMetadata', 'GetMetadataByDictKey', 'GetMutedLayers', 'GetObjectAtPath', 'GetPathResolverContext', 'GetPopulationMask', 'GetPrimAtPath', 'GetPropertyAtPath', 'GetPseudoRoot', 'GetRelationshipAtPath', 'GetRootLayer', 'GetSessionLayer', 'GetStartTimeCode', 'GetTimeCodesPerSecond', 'GetUsedLayers', 'HasAuthoredMetadata', 'HasAuthoredMetadataDictKey', 'HasAuthoredTimeCodeRange', 'HasDefaultPrim', 'HasLocalLayer', 'HasMetadata', 'HasMetadataDictKey', 'InitialLoadSet', 'IsLayerMuted', 'IsSupportedFile', 'Load', 'LoadAll', 'LoadAndUnload', 'LoadNone', 'MuteAndUnmuteLayers', 'MuteLayer', 'Open', 'OpenMasked', 'OverridePrim', 'Reload', 'RemovePrim', 'ResolveIdentifierToEditTarget', 'Save', 'SaveSessionLayers', 'SetColorConfigFallbacks', 'SetColorConfiguration', 'SetColorManagementSystem', 'SetDefaultPrim', 'SetEditTarget', 'SetEndTimeCode', 'SetFramesPerSecond', 'SetGlobalVariantFallbacks', 'SetInterpolationType', 'SetLoadRules', 'SetMetadata', 'SetMetadataByDictKey', 'SetPopulationMask', 'SetStartTimeCode', 'SetTimeCodesPerSecond', 'Traverse', 'TraverseAll', 'Unload', 'UnmuteLayer', 'WriteFallbackPrimTypes', '_GetPcpCache', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'expired']
TraverseAll  <pxr.Usd.PrimRange object at 0x7fd3287cf5d0>
Traverse  <pxr.Usd.PrimRange object at 0x7fd3287cf5d0>

As you see, I was able to find Traverse and TraverseAll methods for stage however not sure how I could use these for randomizing the floor color.

You can consider either of these as a stage in offline_generation.py:

#ENV_URL = "/Isaac/Environments/Simple_Warehouse/full_warehouse.usd"
ENV_URL = "/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"

you can use child_prim.GetPath() and check if the name/path is the one you are looking for. If you already know the path of the prim you can access it using

stage = get_current_stage()
my_prim = stage.GetPrimAtPath("/Path/To/My/Prim")

# wrap your prim to a OG node for OG randomization
my_prim_node = rep.get.prim_at_path(str(my_prim.GetPath()))

def randomize_textures():
    with my_prim_node:
        rep.randomizer.texture(
            textures=[
                "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
            ],
            texture_rotate=rep.distribution.uniform(80, 95),
        )
    return my_prim_node.node

rep.randomizer.register(randomize_textures)

with rep.trigger.on_frame(interval=2, rt_subframes=16):
    rep.randomizer.randomize_textures()

Thanks a lot for your response.

I used this code:

def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)

and have:

    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
        rep.randomizer.randomize_floor_textures()

and I get this error:

Traceback (most recent call last):
  File "/home/mona/omniverse-sdg/offline_generation.py", line 709, in <module>
    rep.randomizer.randomize_floor_textures()
AttributeError: module 'omni.replicator.core.scripts.randomizer' has no attribute 'randomize_floor_textures'
2023-02-20 15:43:19 [23,189ms] [Warning] [carb.audio.context] 1 contexts were leaked
./python.sh: line 41: 37335 Segmentation fault      (core dumped) $python_exe "$@" $args
There was an error running python

Also, how can I select all of the floor tiles? Somehow the tiles are in set of 4 and when I click on a part of floor it selects a group of 4 adjacent tiles. I am interested in changing all of the floor tiles color not just the one selected as in the photo below.

I also changed where I am calling the randomize_floor_textures from

    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
        # rep.randomizer.randomize_floor_textures()

to


with rep.trigger.on_frame(interval=2, rt_subframes=16):
    rep.randomizer.randomize_floor_textures()
def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)

And I still get the same error:

Traceback (most recent call last):
  File "/home/mona/omniverse-sdg/offline_generation.py", line 533, in <module>
    rep.randomizer.randomize_floor_textures()
AttributeError: module 'omni.replicator.core.scripts.randomizer' has no attribute 'randomize_floor_textures'
2023-02-20 15:53:12 [11,660ms] [Warning] [carb.audio.context] 1 contexts were leaked
./python.sh: line 41: 38519 Segmentation fault      (core dumped) $python_exe "$@" $args
There was an error running python

Can you share your the whole script so I can quickly run it? The error says the it does not see the randomize_floor_textures function, which seems to be registered though. Sharing the whole script will make things clearer.

For selecting all tiles you can use also use rep.get.prim_at_path on lists.

For example:

floor_tiles = ["path_1", "path_2"]
floor_tiles_node = rep.get.prim_at_path(floor_tiles)

def randomize_floor_textures():
    with floor_tiles_node:
        rep.randomizer.texture([..])
    return floor_tiles_node.node
rep.randomizer.register(randomize_floor_textures)
1 Like

Thanks a lot for your response. I simplified the script and have it here:

# Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

"""Generate offline synthetic dataset
"""
from omni.isaac.kit import SimulationApp
import os
import glob
import shutil
import traceback

# Set rendering parameters and create an instance of kit
CONFIG = {"renderer": "RayTracedLighting", "headless": True, "width": 1024, "height": 1024, "num_frames": 10}
simulation_app = SimulationApp(launch_config=CONFIG)

ENV_URL = "/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"
FORKLIFT_URL = "/Isaac/Props/Forklift/forklift.usd"
PALLET_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_01.usd"
PALLET_2_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_02.usd"
CARDBOX_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd"
CONE_URL = "/Isaac/Environments/Simple_Warehouse/Props/S_TrafficCone.usd"
SCOPE_NAME = "/MyScope"


import carb
import random
import math
import numpy as np
from pxr import UsdGeom, Usd, Gf, UsdPhysics, PhysxSchema

import inspect

import omni.usd
from omni.isaac.core import World
from omni.isaac.core.utils import prims
from omni.isaac.core.prims import RigidPrim
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.utils.stage import get_current_stage, open_stage
from omni.isaac.core.utils.rotations import euler_angles_to_quat, quat_to_euler_angles, lookat_to_quatf
from omni.isaac.core.utils.bounds import compute_combined_aabb, create_bbox_cache
from omni.isaac.core.utils.random import get_random_world_pose_in_view
from omni.replicator.isaac.scripts.writers import DOPEWriter
from omni.syntheticdata import SyntheticData
from omni.isaac.core.prims import XFormPrim


from flying_distractors.collision_box import CollisionBox
from flying_distractors.dynamic_shape_set import DynamicShapeSet
from flying_distractors.dynamic_object import DynamicObject
from flying_distractors.dynamic_object_set import DynamicObjectSet
from flying_distractors.flying_distractors import FlyingDistractors


import omni.replicator.core as rep





# Helper function to find the assets server
def prefix_with_isaac_asset_server(relative_path):
    assets_root_path = get_assets_root_path()
    if assets_root_path is None:
        raise Exception("Nucleus server not found, could not access Isaac Sim assets folder")
    return assets_root_path + relative_path


# Increase subframes if shadows/ghosting appears of moving objects
# See known issues: https://docs.omniverse.nvidia.com/prod_extensions/prod_extensions/ext_replicator.html#known-issues
rep.settings.carb_settings("/omni/replicator/RTSubframes", 2)


world = World()
world.reset()


print("URL cardbox: ", prefix_with_isaac_asset_server(CARDBOX_URL))



# Randomize boxes materials and their location on the surface of the given prim
def register_scatter_boxes(prim):
    # Calculate the bounds of the prim to create a scatter plane of its size
    bb_cache = create_bbox_cache()
    bbox3d_gf = bb_cache.ComputeLocalBound(prim)
    prim_tf_gf = omni.usd.get_world_transform_matrix(prim)

    # Calculate the bounds of the prim
    bbox3d_gf.Transform(prim_tf_gf)
    range_size = bbox3d_gf.GetRange().GetSize()

    # Get the quaterion of the prim in xyzw format from usd
    prim_quat_gf = prim_tf_gf.ExtractRotation().GetQuaternion()
    prim_quat_xyzw = (prim_quat_gf.GetReal(), *prim_quat_gf.GetImaginary())

    # Create a plane on the pallet to scatter the boxes on
    plane_scale = (range_size[0] * 0.8, range_size[1] * 0.8, 1)
    plane_pos_gf = prim_tf_gf.ExtractTranslation() + Gf.Vec3d(0, 0, range_size[2])
    plane_rot_euler_deg = quat_to_euler_angles(np.array(prim_quat_xyzw), degrees=True)
    scatter_plane = rep.create.plane(
        scale=plane_scale, position=plane_pos_gf, rotation=plane_rot_euler_deg, visible=False
    )

    cardbox_mats = [
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_PaperNotes_01.mdl"),
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_CardBoxB_05.mdl"),
    ]

    def scatter_boxes():
        cardboxes = rep.create.from_usd(
            prefix_with_isaac_asset_server(CARDBOX_URL), semantics=[("class", "Cardbox")], count=30
        )
        # type of cardboxes:  <class 'omni.replicator.core.scripts.utils.utils.ReplicatorItem'>
        with cardboxes:
            rep.randomizer.scatter_2d(scatter_plane, check_for_collisions=True)
            rep.randomizer.materials(cardbox_mats)
        return cardboxes.node

    rep.randomizer.register(scatter_boxes)
    


# Randomize lights around the scene
def register_lights_placement(forklift_prim, pallet_prim):
    bb_cache = create_bbox_cache()
    combined_range_arr = compute_combined_aabb(bb_cache, [forklift_prim.GetPrimPath(), pallet_prim.GetPrimPath()])
    pos_min = (combined_range_arr[0], combined_range_arr[1], 6)
    pos_max = (combined_range_arr[3], combined_range_arr[4], 7)

    def randomize_lights():
        lights = rep.create.light(
            light_type="Sphere",
            color=rep.distribution.uniform((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)),
            intensity=rep.distribution.uniform(500, 3000),
            position=rep.distribution.uniform(pos_min, pos_max),
            scale=rep.distribution.uniform(1, 20),
            count=5,
        )
        return lights.node

    rep.randomizer.register(randomize_lights)


def simulate_falling_objects(prim, num_sim_steps=250, num_boxes=50):
    # Create a simulation ready world
    world = World(physics_dt=1.0 / 90.0, stage_units_in_meters=1.0)

    # Choose a random spawn offset relative to the given prim
    prim_tf = omni.usd.get_world_transform_matrix(prim)
    spawn_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(random.uniform(-0.5, 0.5), random.uniform(3, 3.5), 0))
    spawn_pos_gf = (spawn_offset_tf * prim_tf).ExtractTranslation()

    # Spawn pallet prim
    pallet_prim_name = "SimulatedPallet"
    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/{pallet_prim_name}",
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Get the height of the pallet
    bb_cache = create_bbox_cache()
    curr_spawn_height = bb_cache.ComputeLocalBound(pallet_prim).GetRange().GetSize()[2] * 1.1

    # Wrap the pallet prim into a rigid prim to be able to simulate it
    pallet_rigid_prim = RigidPrim(
        prim_path=str(pallet_prim.GetPrimPath()),
        name=pallet_prim_name,
        position=spawn_pos_gf + Gf.Vec3d(0, 0, curr_spawn_height),
    )

    # Make sure physics are enabled on the rigid prim
    pallet_rigid_prim.enable_rigid_body_physics()


    # Register rigid prim with the scene
    world.scene.add(pallet_rigid_prim)

    # Spawn boxes falling on the pallet
    for i in range(num_boxes):
        # Spawn box prim
        cardbox_prim_name = f"SimulatedCardbox_{i}"
        box_prim = prims.create_prim(
            prim_path=f"{SCOPE_NAME}/{cardbox_prim_name}",
            usd_path=prefix_with_isaac_asset_server(CARDBOX_URL),
            semantic_label="Cardbox",
        )

        # Add the height of the box to the current spawn height
        curr_spawn_height += bb_cache.ComputeLocalBound(box_prim).GetRange().GetSize()[2] * 1.1

        # Wrap the cardbox prim into a rigid prim to be able to simulate it
        box_rigid_prim = RigidPrim(
            prim_path=str(box_prim.GetPrimPath()),
            name=cardbox_prim_name,
            position=spawn_pos_gf + Gf.Vec3d(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2), curr_spawn_height),
            orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        )

        # Make sure physics are enabled on the rigid prim
        box_rigid_prim.enable_rigid_body_physics()

        # Register rigid prim with the scene
        world.scene.add(box_rigid_prim)

    # Reset world after adding simulated assets for physics handles to be propagated properly
    world.reset()

    # Simulate the world for the given number of steps or until the highest box stops moving
    last_box = world.scene.get_object(f"SimulatedCardbox_{num_boxes - 1}")
    for i in range(num_sim_steps):
        world.step(render=False)
        if last_box and np.linalg.norm(last_box.get_linear_velocity()) < 0.001:
            print(f"Simulation stopped after {i} steps")
            break


# Starts replicator and waits until all data was successfully written
def run_orchestrator():
    rep.orchestrator.run()

    # Wait until started
    while not rep.orchestrator.get_is_started():
        simulation_app.update()

    # Wait until stopped
    while rep.orchestrator.get_is_started():
        simulation_app.update()

    rep.BackendDispatch.wait_until_done()
    rep.orchestrator.stop()





def register_color_randomizer(prim_path):
    prim = rep.get.prims(semantics=[('class', 'Forklift'), ('class', 'Pallet'), ('class', 'Cardbox')])
    print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
    print("-------------------------------------------------------------")
    print("inspect.signature(rep.create.material_omnipbr): ", inspect.signature(rep.create.material_omnipbr))
    print("-------------------------------------------------------------")
    print("dir(rep.create): ", dir(rep.create))
    print("-------------------------------------------------------------")
    print("list(rep.create.__dict__.keys()): ", list(rep.create.__dict__.keys()))
    print("-------------------------------------------------------------")
    def randomize_color():
        mats = rep.create.material_omnipbr(
            metallic=rep.distribution.uniform(0.0, 1.0),
            roughness=rep.distribution.uniform(0.0, 1.0),
            diffuse=rep.distribution.uniform((0, 0, 0), (1, 1, 1)),
            specular=rep.distribution.uniform(0.0, 1.0), 
            count=1000,
        )
        with prim:
            rep.randomizer.materials(mats)
        #rep.randomizer.materials(mats)
        # return prims.node
        return prim.node

    rep.randomizer.register(randomize_color)

def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)



with rep.trigger.on_frame(interval=2, rt_subframes=16):
    # rep.randomizer.randomize_floor_textures()
    # Spawn a new forklift at a random pose
    forklift_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Forklift",
        position=(random.uniform(-20, -2), random.uniform(-1, 3), 0),
        orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        usd_path=prefix_with_isaac_asset_server(FORKLIFT_URL),
        semantic_label="Forklift",
    )
    
    # forklift_prim type:  <class 'pxr.Usd.Prim'>
    
    
    forklift_textures = [ 'omniverse://localhost/Mona/textures/dtd/studded/studded_0118.jpg',
                          'omniverse://localhost/Mona/textures/dtd/studded/studded_0170.jpg',
                          'omniverse://localhost/Mona/textures/dtd/marbled/marbled_0095.jpg',
                          'omniverse://localhost/Mona/textures/dtd/marbled/marbled_0193.jpg',
                          'omniverse://localhost/Mona/textures/dtd/knitted/knitted_0196.jpg',
                          'omniverse://localhost/Mona/textures/dtd/knitted/knitted_0150.jpg',
                          'omniverse://localhost/Mona/textures/dtd/knitted/knitted_0096.jpg',
                          'omniverse://localhost/Mona/textures/dtd/perforated/perforated_0057.jpg',
                          'omniverse://localhost/Mona/textures/dtd/perforated/perforated_0079.jpg',
                          'omniverse://localhost/Mona/textures/dtd/waffled/waffled_0063.jpg',
                          'omniverse://localhost/Mona/textures/dtd/waffled/waffled_0172.jpg',
                          'omniverse://localhost/Mona/textures/dtd/waffled/waffled_0120.jpg'
    ]
    print("##########################################################")
    print('signature of create_prim: ', inspect.signature(prims.create_prim))
    
    # forklift_rep = rep.get.prims(forklift_prim)
    # with forklift_rep:
    #     rep.randomizer.texture(textures=forklift_textures)


    print("forklift prim: ", forklift_prim)
    # # Spawn a new cone at a random pose
    
   

    # Spawn the pallet in front of the forklift with a random offset on the Y axis
    forklift_tf = omni.usd.get_world_transform_matrix(forklift_prim)
    pallet_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(0, random.uniform(-1.2, -2.4), 0))
    pallet_pos_gf = (pallet_offset_tf * forklift_tf).ExtractTranslation()
    forklift_quat_gf = forklift_tf.ExtractRotation().GetQuaternion()
    forklift_quat_xyzw = (forklift_quat_gf.GetReal(), *forklift_quat_gf.GetImaginary())

    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Pallet",
        position=pallet_pos_gf,
        orientation=forklift_quat_xyzw,
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Simulate dropping objects on a pile behind the forklift
    simulate_falling_objects(forklift_prim)

    # Register randomizers

    register_scatter_boxes(pallet_prim)

    #register_cone_placement(forklift_prim, pallet_prim)
    #register_pallet2_placement(forklift_prim, pallet_prim)
    register_lights_placement(forklift_prim, pallet_prim)
    register_color_randomizer(pallet_prim)


    # Spawn a camera in the driver's location looking at the pallet
    foklift_pos_gf = forklift_tf.ExtractTranslation()
    driver_cam_pos_gf = foklift_pos_gf + Gf.Vec3d(0.0, 0.0, 1.9)
    rotate_180_on_y_quat_gf = Gf.Quatf(0, 0, 1, 0)
    look_at_pallet_quat_gf = lookat_to_quatf(driver_cam_pos_gf, pallet_pos_gf, (0, 0, 1)) * rotate_180_on_y_quat_gf
    look_at_pallet_xyzw = (look_at_pallet_quat_gf.GetReal(), *look_at_pallet_quat_gf.GetImaginary())

    driver_cam_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/DriverCamera",
        prim_type="Camera",
        position=driver_cam_pos_gf,
        orientation=look_at_pallet_xyzw,
        attributes={"focusDistance": 400, "focalLength": 24, "clippingRange": (0.1, 10000000)},
    )

    # Camera looking at the pallet
    pallet_cam = rep.create.camera()


    # Top View Camera 
    # Camera looking at the forklift from a top view with large min clipping to see the scene through the ceiling
    top_view_cam = rep.create.camera(clipping_range=(6.0, 1000000.0))

    # TODO: access the current frame number 
    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
    
        rep.randomizer.randomize_lights()
        rep.randomizer.randomize_color()
        # rep.randomizer.randomize_floor_textures()
        pos_min = (pallet_pos_gf[0] - 2, pallet_pos_gf[1] - 2, 2)
        pos_max = (pallet_pos_gf[0] + 2, pallet_pos_gf[1] + 2, 4)
        with pallet_cam:
            rep.modify.pose(position=rep.distribution.uniform(pos_min, pos_max), look_at=str(pallet_prim.GetPrimPath()))
        
        with top_view_cam:
            rep.modify.pose(
                position=rep.distribution.uniform(
                    (foklift_pos_gf[0], foklift_pos_gf[1], 9), (foklift_pos_gf[0], foklift_pos_gf[1], 11)
                ),
                rotation=rep.distribution.uniform((0, -90, 0), (0, -90, 180)),
            )


    if os.path.exists(os.getcwd() + '/_out_headless'):
        shutil.rmtree(os.getcwd() + '/_out_headless', ignore_errors=False, onerror=None)
    


    

    #Basic Writer
    # Initialize and attach writer
    writer = rep.WriterRegistry.get("BasicWriter")
    print("***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************")
    output_directory = os.getcwd() + "/_output_headless"
    print("Outputting data to ", output_directory)
    writer.initialize(
        output_dir=output_directory,
        rgb=True,
        bounding_box_2d_tight=True,
        semantic_segmentation=True,
        instance_segmentation=True,
        distance_to_image_plane=True,
        bounding_box_3d=True,
        occlusion=True,
        normals=True,
    )
  
    RESOLUTION = (CONFIG["width"], CONFIG["height"])
    driver_rp = rep.create.render_product(str(driver_cam_prim.GetPrimPath()), RESOLUTION)
    pallet_rp = rep.create.render_product(pallet_cam, RESOLUTION)
    forklift_rp = rep.create.render_product(top_view_cam, RESOLUTION)
    writer.attach([driver_rp, forklift_rp, pallet_rp])

    run_orchestrator()
    simulation_app.update()


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        carb.log_error(f"Exception: {e}")
        traceback.print_exc()
    finally:
        simulation_app.close()


I notice a weird problem, I set the num_frames to 10, it keeps dumping frames:

Here’s the output:

2023-02-20 16:08:06 [7,303ms] [Warning] [omni.client.plugin]  HTTP Client: provider_http: CC-493: Request through cache failed. Retrying without cache for https://omniverse-content-production.s3.us-west-2.amazonaws.com/.cloudfront.toml
2023-02-20 16:08:06 [7,303ms] [Warning] [omni.client.plugin]  HTTP Client: omniclient: CC-873: Bypassing cache until the application is restarted
[10.197s] app ready
[10.402s] RTX ready
[10.402s] RTX ready
[10.851s] Simulation App Startup Complete
URL cardbox:  omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd
##########################################################
signature of create_prim:  (prim_path: str, prim_type: str = 'Xform', position: Union[Sequence[float], NoneType] = None, translation: Union[Sequence[float], NoneType] = None, orientation: Union[Sequence[float], NoneType] = None, scale: Union[Sequence[float], NoneType] = None, usd_path: Union[str, NoneType] = None, semantic_label: Union[str, NoneType] = None, semantic_type: str = 'class', attributes: Union[dict, NoneType] = None) -> pxr.Usd.Prim
forklift prim:  Usd.Prim(</MyScope/Forklift>)
2023-02-20 16:08:13 [14,169ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedPallet/SM_PaletteA_01. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,169ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_0/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,169ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_1/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_2/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_3/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_4/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_5/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_6/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_7/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_8/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_9/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_10/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_11/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_12/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_13/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_14/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_15/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_16/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_17/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_18/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_19/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_20/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_21/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_22/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_23/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_24/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_25/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_26/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_27/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_28/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_29/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_30/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_31/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_32/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_33/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_34/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_35/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_36/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_37/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_38/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_39/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_40/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_41/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_42/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_43/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_44/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,170ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_45/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,171ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_46/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,171ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_47/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,171ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_48/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:08:13 [14,171ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_49/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
-------------------------------------------------------------
inspect.signature(rep.create.material_omnipbr):  (diffuse: Tuple[float] = None, diffuse_texture: str = None, roughness: float = None, roughness_texture: str = None, metallic: float = None, metallic_texture: str = None, specular: float = None, emissive_color: Tuple[float] = None, emissive_texture: str = None, emissive_intensity: float = 0.0, project_uvw: bool = False, semantics: List[Tuple[str, str]] = None, count: int = 1)
-------------------------------------------------------------
dir(rep.create):  ['Callable', 'Dict', 'LOOKS_PATH', 'List', 'REPLICATOR_SCOPE', 'ReplicatorItem', 'ReplicatorWrapper', 'Sdf', 'Tuple', 'Union', 'Usd', 'UsdGeom', 'UsdShade', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__license__', '__loader__', '__name__', '__package__', '__spec__', '_create_prim', '_set_attributes', '_set_targets', 'asyncio', 'camera', 'carb', 'cone', 'create_node', 'cube', 'cylinder', 'disk', 'from_dir', 'from_usd', 'get_node_targets', 'get_usd_files', 'group', 'light', 'material_omnipbr', 'modify', 'og', 'omni', 'os', 'plane', 'register', 'render_product', 'sphere', 'stereo_camera', 'sys', 'torus', 'utils', 'viewport_manager']
-------------------------------------------------------------
list(rep.create.__dict__.keys()):  ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', '__copyright__', '__license__', 'asyncio', 'os', 'sys', 'Callable', 'Dict', 'List', 'Tuple', 'Union', 'carb', 'og', 'omni', 'Sdf', 'Usd', 'UsdGeom', 'UsdShade', 'modify', 'ReplicatorItem', 'ReplicatorWrapper', 'create_node', 'get_node_targets', 'get_usd_files', 'utils', 'viewport_manager', 'REPLICATOR_SCOPE', 'LOOKS_PATH', '_set_targets', '_create_prim', '_set_attributes', 'register', 'sphere', 'torus', 'disk', 'plane', 'cube', 'cylinder', 'cone', 'camera', 'stereo_camera', 'light', 'render_product', 'from_usd', 'group', 'from_dir', 'material_omnipbr']
-------------------------------------------------------------
2023-02-20 16:08:14 [15,522ms] [Warning] [carb.flatcache.plugin] UsdRelationship /Replicator/SDGPipeline/OgnGroup_06.inputs:prims has multiple targets, which is not supported

***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
Outputting data to  /home/mona/.local/share/ov/pkg/isaac_sim-2022.2.0/_output_headless
2023-02-20 16:08:22 [23,734ms] [Warning] [carb.flatcache.plugin] PathToAttributesMap (0x19a28350) contains attributes with duplicate name "camera" with different types but same per-element size. Data may become corrupted during request to move elements between buckets!
2023-02-20 16:08:25 [26,594ms] [Error] [omni.graph.core.plugin] /Replicator/SDGPipeline/OgnScatter2D: Assertion raised in compute - Randomization timed out, cannot find a configuration to randomize prim locations and prevent collisions.
  File "/home/mona/.local/share/ov/pkg/isaac_sim-2022.2.0/extscache/omni.replicator.core-1.6.4+104.1.lx64.r.cp37/omni/replicator/core/ogn/python/_impl/nodes/OgnScatter2D.py", line 247, in compute
    "Randomization timed out, cannot find a configuration to randomize prim locations and prevent collisions."

Module omni.replicator.core.ogn.python._impl.nodes.OgnSemanticSegmentation load on device 'cuda:0' took 11.76 ms

It also seems the forklift is spawn outside of the warehouse despite using the correct coordinates (background is black).

I also don’t know how to find all of the floor (or floor tiles). Basically, I see these when I search for SM_floor however, it doesn’t seem it is sequential or anything. Is there a way to use patterns for finding all the tiles?

If I uncomment this line:

with rep.trigger.on_frame(interval=2, rt_subframes=16):
    rep.randomizer.randomize_floor_textures()

I get this error:

2023-02-20 16:20:43 [6,784ms] [Warning] [omni.kit.menu.utils.scripts.builder_utils] ********************* MenuItemDescription Action Graph *********************
2023-02-20 16:20:43 [6,784ms] [Warning] [omni.kit.menu.utils.scripts.builder_utils] Action Graph uses onclick_fn and/or unclick_fn which are deprecated. Use onclick_action and unclick_action instead which use omni.kit.actions.core
[6.794s] [ext: omni.kit.window.stats-0.1.2] startup
[6.795s] [ext: omni.isaac.sim.python-2022.2.0] startup
[6.796s] Simulation App Starting
2023-02-20 16:20:44 [7,430ms] [Warning] [omni.client.plugin]  HTTP Client: provider_http: CC-493: Request through cache failed. Retrying without cache for https://omniverse-content-production.s3.us-west-2.amazonaws.com/.cloudfront.toml
2023-02-20 16:20:44 [7,430ms] [Warning] [omni.client.plugin]  HTTP Client: omniclient: CC-873: Bypassing cache until the application is restarted
[10.325s] app ready
[10.560s] RTX ready
[10.560s] RTX ready
[11.030s] Simulation App Startup Complete
URL cardbox:  omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd
Traceback (most recent call last):
  File "/home/mona/omniverse-sdg/floor_color_randomizer.py", line 294, in <module>
    rep.randomizer.randomize_floor_textures()
AttributeError: module 'omni.replicator.core.scripts.randomizer' has no attribute 'randomize_floor_textures'
2023-02-20 16:20:48 [11,986ms] [Warning] [carb.audio.context] 1 contexts were leaked
./python.sh: line 41: 41766 Segmentation fault      (core dumped) $python_exe "$@" $args
There was an error running python

and if I uncomment this line and comment the other one:

    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
    
        rep.randomizer.randomize_lights()
        rep.randomizer.randomize_color()
        rep.randomizer.randomize_floor_textures()

the error is:

back to convexHull approximation: /MyScope/SimulatedCardbox_46/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:22:24 [13,205ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_47/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:22:24 [13,205ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_48/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
2023-02-20 16:22:24 [13,205ms] [Warning] [omni.physx.plugin] PhysicsUSD: Parse collision - triangle mesh collision (approximation None/MeshSimplifixation) without SDF cannot be a part of a dynamic body, falling back to convexHull approximation: /MyScope/SimulatedCardbox_49/SM_CardBoxD_04. To enable SDF collisions, sdfResolution should be > 0.
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
-------------------------------------------------------------
inspect.signature(rep.create.material_omnipbr):  (diffuse: Tuple[float] = None, diffuse_texture: str = None, roughness: float = None, roughness_texture: str = None, metallic: float = None, metallic_texture: str = None, specular: float = None, emissive_color: Tuple[float] = None, emissive_texture: str = None, emissive_intensity: float = 0.0, project_uvw: bool = False, semantics: List[Tuple[str, str]] = None, count: int = 1)
-------------------------------------------------------------
dir(rep.create):  ['Callable', 'Dict', 'LOOKS_PATH', 'List', 'REPLICATOR_SCOPE', 'ReplicatorItem', 'ReplicatorWrapper', 'Sdf', 'Tuple', 'Union', 'Usd', 'UsdGeom', 'UsdShade', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__license__', '__loader__', '__name__', '__package__', '__spec__', '_create_prim', '_set_attributes', '_set_targets', 'asyncio', 'camera', 'carb', 'cone', 'create_node', 'cube', 'cylinder', 'disk', 'from_dir', 'from_usd', 'get_node_targets', 'get_usd_files', 'group', 'light', 'material_omnipbr', 'modify', 'og', 'omni', 'os', 'plane', 'register', 'render_product', 'sphere', 'stereo_camera', 'sys', 'torus', 'utils', 'viewport_manager']
-------------------------------------------------------------
list(rep.create.__dict__.keys()):  ['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', '__copyright__', '__license__', 'asyncio', 'os', 'sys', 'Callable', 'Dict', 'List', 'Tuple', 'Union', 'carb', 'og', 'omni', 'Sdf', 'Usd', 'UsdGeom', 'UsdShade', 'modify', 'ReplicatorItem', 'ReplicatorWrapper', 'create_node', 'get_node_targets', 'get_usd_files', 'utils', 'viewport_manager', 'REPLICATOR_SCOPE', 'LOOKS_PATH', '_set_targets', '_create_prim', '_set_attributes', 'register', 'sphere', 'torus', 'disk', 'plane', 'cube', 'cylinder', 'cone', 'camera', 'stereo_camera', 'light', 'render_product', 'from_usd', 'group', 'from_dir', 'material_omnipbr']
-------------------------------------------------------------
2023-02-20 16:22:25 [14,529ms] [Warning] [carb.flatcache.plugin] UsdRelationship /Replicator/SDGPipeline/OgnGroup_06.inputs:prims has multiple targets, which is not supported

Traceback (most recent call last):
  File "/home/mona/omniverse-sdg/floor_color_randomizer.py", line 390, in <module>
    rep.randomizer.randomize_floor_textures()
AttributeError: module 'omni.replicator.core.scripts.randomizer' has no attribute 'randomize_floor_textures'
2023-02-20 16:22:33 [22,325ms] [Warning] [carb.audio.context] 1 contexts were leaked
./python.sh: line 41: 42120 Segmentation fault      (core dumped) $python_exe "$@" $args
There was an error running python

Also, is

        position=(random.uniform(-20, -2), random.uniform(-1, 3), 0),

wrong? I thought changing it to -20,-2 would assure it stays in the warehouse.

I also keept getting this error the beginning of running the script (however, it moves forward).

Outputting data to  /home/mona/.local/share/ov/pkg/isaac_sim-2022.2.0/_output_headless
2023-02-20 16:27:24 [22,593ms] [Warning] [carb.flatcache.plugin] PathToAttributesMap (0x1a835b60) contains attributes with duplicate name "camera" with different types but same per-element size. Data may become corrupted during request to move elements between buckets!
2023-02-20 16:27:27 [25,577ms] [Error] [omni.graph.core.plugin] /Replicator/SDGPipeline/OgnScatter2D: Assertion raised in compute - Randomization timed out, cannot find a configuration to randomize prim locations and prevent collisions.
  File "/home/mona/.local/share/ov/pkg/isaac_sim-2022.2.0/extscache/omni.replicator.core-1.6.4+104.1.lx64.r.cp37/omni/replicator/core/ogn/python/_impl/nodes/OgnScatter2D.py", line 247, in compute
    "Randomization timed out, cannot find a configuration to randomize prim locations and prevent collisions."

The script does many things however, it also contains files I do not have access to, so I cannot really test it.

Can you briefly mention what exactly you are trying to achieve and try keeping only those parts of the script in the file?

Maybe just one by one filling out parts into this template script:

from omni.isaac.kit import SimulationApp

simulation_app = SimulationApp()

import omni
from omni.isaac.core import World

simulation_app.update()
omni.usd.get_context().new_stage()
simulation_app.update()


world = World()
world.step(render=True, step_sim=True)


simulation_app.close()

I removed those stuff,

Will you please be able to run this?

# Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

"""Generate offline synthetic dataset
"""
from omni.isaac.kit import SimulationApp
import os
import glob
import shutil
import traceback

# Set rendering parameters and create an instance of kit
CONFIG = {"renderer": "RayTracedLighting", "headless": True, "width": 1024, "height": 1024, "num_frames": 5}
simulation_app = SimulationApp(launch_config=CONFIG)

ENV_URL = "/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"
FORKLIFT_URL = "/Isaac/Props/Forklift/forklift.usd"
PALLET_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_01.usd"
PALLET_2_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_02.usd"
CARDBOX_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd"
CONE_URL = "/Isaac/Environments/Simple_Warehouse/Props/S_TrafficCone.usd"
SCOPE_NAME = "/MyScope"


import carb
import random
import math
import numpy as np
from pxr import UsdGeom, Usd, Gf, UsdPhysics, PhysxSchema

import inspect

import omni.usd
from omni.isaac.core import World
from omni.isaac.core.utils import prims
from omni.isaac.core.prims import RigidPrim
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.utils.stage import get_current_stage, open_stage
from omni.isaac.core.utils.rotations import euler_angles_to_quat, quat_to_euler_angles, lookat_to_quatf
from omni.isaac.core.utils.bounds import compute_combined_aabb, create_bbox_cache
from omni.isaac.core.utils.random import get_random_world_pose_in_view
from omni.replicator.isaac.scripts.writers import DOPEWriter
from omni.syntheticdata import SyntheticData
from omni.isaac.core.prims import XFormPrim


from flying_distractors.collision_box import CollisionBox
from flying_distractors.dynamic_shape_set import DynamicShapeSet
from flying_distractors.dynamic_object import DynamicObject
from flying_distractors.dynamic_object_set import DynamicObjectSet
from flying_distractors.flying_distractors import FlyingDistractors


import omni.replicator.core as rep





# Helper function to find the assets server
def prefix_with_isaac_asset_server(relative_path):
    assets_root_path = get_assets_root_path()
    if assets_root_path is None:
        raise Exception("Nucleus server not found, could not access Isaac Sim assets folder")
    return assets_root_path + relative_path


# Increase subframes if shadows/ghosting appears of moving objects
# See known issues: https://docs.omniverse.nvidia.com/prod_extensions/prod_extensions/ext_replicator.html#known-issues
rep.settings.carb_settings("/omni/replicator/RTSubframes", 2)


world = World()
world.reset()


print("URL cardbox: ", prefix_with_isaac_asset_server(CARDBOX_URL))



# Randomize boxes materials and their location on the surface of the given prim
def register_scatter_boxes(prim):
    # Calculate the bounds of the prim to create a scatter plane of its size
    bb_cache = create_bbox_cache()
    bbox3d_gf = bb_cache.ComputeLocalBound(prim)
    prim_tf_gf = omni.usd.get_world_transform_matrix(prim)

    # Calculate the bounds of the prim
    bbox3d_gf.Transform(prim_tf_gf)
    range_size = bbox3d_gf.GetRange().GetSize()

    # Get the quaterion of the prim in xyzw format from usd
    prim_quat_gf = prim_tf_gf.ExtractRotation().GetQuaternion()
    prim_quat_xyzw = (prim_quat_gf.GetReal(), *prim_quat_gf.GetImaginary())

    # Create a plane on the pallet to scatter the boxes on
    plane_scale = (range_size[0] * 0.8, range_size[1] * 0.8, 1)
    plane_pos_gf = prim_tf_gf.ExtractTranslation() + Gf.Vec3d(0, 0, range_size[2])
    plane_rot_euler_deg = quat_to_euler_angles(np.array(prim_quat_xyzw), degrees=True)
    scatter_plane = rep.create.plane(
        scale=plane_scale, position=plane_pos_gf, rotation=plane_rot_euler_deg, visible=False
    )

    cardbox_mats = [
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_PaperNotes_01.mdl"),
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_CardBoxB_05.mdl"),
    ]

    def scatter_boxes():
        cardboxes = rep.create.from_usd(
            prefix_with_isaac_asset_server(CARDBOX_URL), semantics=[("class", "Cardbox")], count=30
        )
        # type of cardboxes:  <class 'omni.replicator.core.scripts.utils.utils.ReplicatorItem'>
        with cardboxes:
            rep.randomizer.scatter_2d(scatter_plane, check_for_collisions=True)
            rep.randomizer.materials(cardbox_mats)
        return cardboxes.node

    rep.randomizer.register(scatter_boxes)
    


# Randomize lights around the scene
def register_lights_placement(forklift_prim, pallet_prim):
    bb_cache = create_bbox_cache()
    combined_range_arr = compute_combined_aabb(bb_cache, [forklift_prim.GetPrimPath(), pallet_prim.GetPrimPath()])
    pos_min = (combined_range_arr[0], combined_range_arr[1], 6)
    pos_max = (combined_range_arr[3], combined_range_arr[4], 7)

    def randomize_lights():
        lights = rep.create.light(
            light_type="Sphere",
            color=rep.distribution.uniform((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)),
            intensity=rep.distribution.uniform(500, 3000),
            position=rep.distribution.uniform(pos_min, pos_max),
            scale=rep.distribution.uniform(1, 20),
            count=5,
        )
        return lights.node

    rep.randomizer.register(randomize_lights)


def simulate_falling_objects(prim, num_sim_steps=250, num_boxes=50):
    # Create a simulation ready world
    world = World(physics_dt=1.0 / 90.0, stage_units_in_meters=1.0)

    # Choose a random spawn offset relative to the given prim
    prim_tf = omni.usd.get_world_transform_matrix(prim)
    spawn_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(random.uniform(-0.5, 0.5), random.uniform(3, 3.5), 0))
    spawn_pos_gf = (spawn_offset_tf * prim_tf).ExtractTranslation()

    # Spawn pallet prim
    pallet_prim_name = "SimulatedPallet"
    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/{pallet_prim_name}",
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Get the height of the pallet
    bb_cache = create_bbox_cache()
    curr_spawn_height = bb_cache.ComputeLocalBound(pallet_prim).GetRange().GetSize()[2] * 1.1

    # Wrap the pallet prim into a rigid prim to be able to simulate it
    pallet_rigid_prim = RigidPrim(
        prim_path=str(pallet_prim.GetPrimPath()),
        name=pallet_prim_name,
        position=spawn_pos_gf + Gf.Vec3d(0, 0, curr_spawn_height),
    )

    # Make sure physics are enabled on the rigid prim
    pallet_rigid_prim.enable_rigid_body_physics()


    # Register rigid prim with the scene
    world.scene.add(pallet_rigid_prim)

    # Spawn boxes falling on the pallet
    for i in range(num_boxes):
        # Spawn box prim
        cardbox_prim_name = f"SimulatedCardbox_{i}"
        box_prim = prims.create_prim(
            prim_path=f"{SCOPE_NAME}/{cardbox_prim_name}",
            usd_path=prefix_with_isaac_asset_server(CARDBOX_URL),
            semantic_label="Cardbox",
        )

        # Add the height of the box to the current spawn height
        curr_spawn_height += bb_cache.ComputeLocalBound(box_prim).GetRange().GetSize()[2] * 1.1

        # Wrap the cardbox prim into a rigid prim to be able to simulate it
        box_rigid_prim = RigidPrim(
            prim_path=str(box_prim.GetPrimPath()),
            name=cardbox_prim_name,
            position=spawn_pos_gf + Gf.Vec3d(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2), curr_spawn_height),
            orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        )

        # Make sure physics are enabled on the rigid prim
        box_rigid_prim.enable_rigid_body_physics()

        # Register rigid prim with the scene
        world.scene.add(box_rigid_prim)

    # Reset world after adding simulated assets for physics handles to be propagated properly
    world.reset()

    # Simulate the world for the given number of steps or until the highest box stops moving
    last_box = world.scene.get_object(f"SimulatedCardbox_{num_boxes - 1}")
    for i in range(num_sim_steps):
        world.step(render=False)
        if last_box and np.linalg.norm(last_box.get_linear_velocity()) < 0.001:
            print(f"Simulation stopped after {i} steps")
            break


# Starts replicator and waits until all data was successfully written
def run_orchestrator():
    rep.orchestrator.run()

    # Wait until started
    while not rep.orchestrator.get_is_started():
        simulation_app.update()

    # Wait until stopped
    while rep.orchestrator.get_is_started():
        simulation_app.update()

    rep.BackendDispatch.wait_until_done()
    rep.orchestrator.stop()





def register_color_randomizer(prim_path):
    prim = rep.get.prims(semantics=[('class', 'Forklift'), ('class', 'Pallet'), ('class', 'Cardbox')])
    print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
    print("-------------------------------------------------------------")
    print("inspect.signature(rep.create.material_omnipbr): ", inspect.signature(rep.create.material_omnipbr))
    print("-------------------------------------------------------------")
    print("dir(rep.create): ", dir(rep.create))
    print("-------------------------------------------------------------")
    print("list(rep.create.__dict__.keys()): ", list(rep.create.__dict__.keys()))
    print("-------------------------------------------------------------")
    def randomize_color():
        mats = rep.create.material_omnipbr(
            metallic=rep.distribution.uniform(0.0, 1.0),
            roughness=rep.distribution.uniform(0.0, 1.0),
            diffuse=rep.distribution.uniform((0, 0, 0), (1, 1, 1)),
            specular=rep.distribution.uniform(0.0, 1.0), 
            count=1000,
        )
        with prim:
            rep.randomizer.materials(mats)
        #rep.randomizer.materials(mats)
        # return prims.node
        return prim.node

    rep.randomizer.register(randomize_color)

def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)



with rep.trigger.on_frame(interval=2, rt_subframes=16):
    #rep.randomizer.randomize_floor_textures()
    # Spawn a new forklift at a random pose
    forklift_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Forklift",
        position=(random.uniform(-20, -2), random.uniform(-1, 3), 0),
        orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        usd_path=prefix_with_isaac_asset_server(FORKLIFT_URL),
        semantic_label="Forklift",
    )
    
    # forklift_prim type:  <class 'pxr.Usd.Prim'>
    
    
    # forklift_rep = rep.get.prims(forklift_prim)
    # with forklift_rep:
    #     rep.randomizer.texture(textures=forklift_textures)


    print("forklift prim: ", forklift_prim)
    # # Spawn a new cone at a random pose
    
   

    # Spawn the pallet in front of the forklift with a random offset on the Y axis
    forklift_tf = omni.usd.get_world_transform_matrix(forklift_prim)
    pallet_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(0, random.uniform(-1.2, -2.4), 0))
    pallet_pos_gf = (pallet_offset_tf * forklift_tf).ExtractTranslation()
    forklift_quat_gf = forklift_tf.ExtractRotation().GetQuaternion()
    forklift_quat_xyzw = (forklift_quat_gf.GetReal(), *forklift_quat_gf.GetImaginary())

    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Pallet",
        position=pallet_pos_gf,
        orientation=forklift_quat_xyzw,
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Simulate dropping objects on a pile behind the forklift
    simulate_falling_objects(forklift_prim)

    # Register randomizers

    register_scatter_boxes(pallet_prim)

    #register_cone_placement(forklift_prim, pallet_prim)
    #register_pallet2_placement(forklift_prim, pallet_prim)
    register_lights_placement(forklift_prim, pallet_prim)
    register_color_randomizer(pallet_prim)


    # Spawn a camera in the driver's location looking at the pallet
    foklift_pos_gf = forklift_tf.ExtractTranslation()
    driver_cam_pos_gf = foklift_pos_gf + Gf.Vec3d(0.0, 0.0, 1.9)
    rotate_180_on_y_quat_gf = Gf.Quatf(0, 0, 1, 0)
    look_at_pallet_quat_gf = lookat_to_quatf(driver_cam_pos_gf, pallet_pos_gf, (0, 0, 1)) * rotate_180_on_y_quat_gf
    look_at_pallet_xyzw = (look_at_pallet_quat_gf.GetReal(), *look_at_pallet_quat_gf.GetImaginary())

    driver_cam_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/DriverCamera",
        prim_type="Camera",
        position=driver_cam_pos_gf,
        orientation=look_at_pallet_xyzw,
        attributes={"focusDistance": 400, "focalLength": 24, "clippingRange": (0.1, 10000000)},
    )

    # Camera looking at the pallet
    pallet_cam = rep.create.camera()


    # Top View Camera 
    # Camera looking at the forklift from a top view with large min clipping to see the scene through the ceiling
    top_view_cam = rep.create.camera(clipping_range=(6.0, 1000000.0))

    # TODO: access the current frame number 
    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
    
        rep.randomizer.randomize_lights()
        rep.randomizer.randomize_color()
        # rep.randomizer.randomize_floor_textures()
        pos_min = (pallet_pos_gf[0] - 2, pallet_pos_gf[1] - 2, 2)
        pos_max = (pallet_pos_gf[0] + 2, pallet_pos_gf[1] + 2, 4)
        with pallet_cam:
            rep.modify.pose(position=rep.distribution.uniform(pos_min, pos_max), look_at=str(pallet_prim.GetPrimPath()))
        
        with top_view_cam:
            rep.modify.pose(
                position=rep.distribution.uniform(
                    (foklift_pos_gf[0], foklift_pos_gf[1], 9), (foklift_pos_gf[0], foklift_pos_gf[1], 11)
                ),
                rotation=rep.distribution.uniform((0, -90, 0), (0, -90, 180)),
            )


    if os.path.exists(os.getcwd() + '/_output_headless'):
        shutil.rmtree(os.getcwd() + '/_output_headless', ignore_errors=False, onerror=None)
    


    

    #Basic Writer
    # Initialize and attach writer
    writer = rep.WriterRegistry.get("BasicWriter")
    print("***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************")
    output_directory = os.getcwd() + "/_output_headless"
    print("Outputting data to ", output_directory)
    writer.initialize(
        output_dir=output_directory,
        rgb=True,
        bounding_box_2d_tight=True,
        semantic_segmentation=True,
        instance_segmentation=True,
        distance_to_image_plane=True,
        bounding_box_3d=True,
        occlusion=True,
        normals=True,
    )
  
    RESOLUTION = (CONFIG["width"], CONFIG["height"])
    driver_rp = rep.create.render_product(str(driver_cam_prim.GetPrimPath()), RESOLUTION)
    pallet_rp = rep.create.render_product(pallet_cam, RESOLUTION)
    forklift_rp = rep.create.render_product(top_view_cam, RESOLUTION)
    writer.attach([driver_rp, forklift_rp, pallet_rp])

    run_orchestrator()
    simulation_app.update()


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        carb.log_error(f"Exception: {e}")
        traceback.print_exc()
    finally:
        simulation_app.close()


Getting:

ModuleNotFoundError: No module named 'flying_distractors'

It seems you importing the flying_distractors from another tutorial. Can you go over a repro on how you are running the script?
Can you also explain what you are trying to solve, there might be an easier solution than mixing multiple demos together.

The offline generation tutorial is also meant to provide various useful snippets, it is doing the same thing in different ways in some cases. So it does not really make sense to use it as a starting point.

My bad. Sorry about that. Created a new folder and put the code inside it and removed libs too.

# Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

"""Generate offline synthetic dataset
"""
from omni.isaac.kit import SimulationApp
import os
import glob
import shutil
import traceback

# Set rendering parameters and create an instance of kit
CONFIG = {"renderer": "RayTracedLighting", "headless": True, "width": 1024, "height": 1024, "num_frames": 5}
simulation_app = SimulationApp(launch_config=CONFIG)

ENV_URL = "/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"
FORKLIFT_URL = "/Isaac/Props/Forklift/forklift.usd"
PALLET_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_01.usd"
PALLET_2_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_02.usd"
CARDBOX_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd"
CONE_URL = "/Isaac/Environments/Simple_Warehouse/Props/S_TrafficCone.usd"
SCOPE_NAME = "/MyScope"


import carb
import random
import math
import numpy as np
from pxr import UsdGeom, Usd, Gf, UsdPhysics, PhysxSchema

import inspect

import omni.usd
from omni.isaac.core import World
from omni.isaac.core.utils import prims
from omni.isaac.core.prims import RigidPrim
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.utils.stage import get_current_stage, open_stage
from omni.isaac.core.utils.rotations import euler_angles_to_quat, quat_to_euler_angles, lookat_to_quatf
from omni.isaac.core.utils.bounds import compute_combined_aabb, create_bbox_cache
from omni.isaac.core.utils.random import get_random_world_pose_in_view
from omni.replicator.isaac.scripts.writers import DOPEWriter
from omni.syntheticdata import SyntheticData
from omni.isaac.core.prims import XFormPrim



import omni.replicator.core as rep





# Helper function to find the assets server
def prefix_with_isaac_asset_server(relative_path):
    assets_root_path = get_assets_root_path()
    if assets_root_path is None:
        raise Exception("Nucleus server not found, could not access Isaac Sim assets folder")
    return assets_root_path + relative_path


# Increase subframes if shadows/ghosting appears of moving objects
# See known issues: https://docs.omniverse.nvidia.com/prod_extensions/prod_extensions/ext_replicator.html#known-issues
rep.settings.carb_settings("/omni/replicator/RTSubframes", 2)


world = World()
world.reset()


print("URL cardbox: ", prefix_with_isaac_asset_server(CARDBOX_URL))



# Randomize boxes materials and their location on the surface of the given prim
def register_scatter_boxes(prim):
    # Calculate the bounds of the prim to create a scatter plane of its size
    bb_cache = create_bbox_cache()
    bbox3d_gf = bb_cache.ComputeLocalBound(prim)
    prim_tf_gf = omni.usd.get_world_transform_matrix(prim)

    # Calculate the bounds of the prim
    bbox3d_gf.Transform(prim_tf_gf)
    range_size = bbox3d_gf.GetRange().GetSize()

    # Get the quaterion of the prim in xyzw format from usd
    prim_quat_gf = prim_tf_gf.ExtractRotation().GetQuaternion()
    prim_quat_xyzw = (prim_quat_gf.GetReal(), *prim_quat_gf.GetImaginary())

    # Create a plane on the pallet to scatter the boxes on
    plane_scale = (range_size[0] * 0.8, range_size[1] * 0.8, 1)
    plane_pos_gf = prim_tf_gf.ExtractTranslation() + Gf.Vec3d(0, 0, range_size[2])
    plane_rot_euler_deg = quat_to_euler_angles(np.array(prim_quat_xyzw), degrees=True)
    scatter_plane = rep.create.plane(
        scale=plane_scale, position=plane_pos_gf, rotation=plane_rot_euler_deg, visible=False
    )

    cardbox_mats = [
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_PaperNotes_01.mdl"),
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_CardBoxB_05.mdl"),
    ]

    def scatter_boxes():
        cardboxes = rep.create.from_usd(
            prefix_with_isaac_asset_server(CARDBOX_URL), semantics=[("class", "Cardbox")], count=30
        )
        # type of cardboxes:  <class 'omni.replicator.core.scripts.utils.utils.ReplicatorItem'>
        with cardboxes:
            rep.randomizer.scatter_2d(scatter_plane, check_for_collisions=True)
            rep.randomizer.materials(cardbox_mats)
        return cardboxes.node

    rep.randomizer.register(scatter_boxes)
    


# Randomize lights around the scene
def register_lights_placement(forklift_prim, pallet_prim):
    bb_cache = create_bbox_cache()
    combined_range_arr = compute_combined_aabb(bb_cache, [forklift_prim.GetPrimPath(), pallet_prim.GetPrimPath()])
    pos_min = (combined_range_arr[0], combined_range_arr[1], 6)
    pos_max = (combined_range_arr[3], combined_range_arr[4], 7)

    def randomize_lights():
        lights = rep.create.light(
            light_type="Sphere",
            color=rep.distribution.uniform((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)),
            intensity=rep.distribution.uniform(500, 3000),
            position=rep.distribution.uniform(pos_min, pos_max),
            scale=rep.distribution.uniform(1, 20),
            count=5,
        )
        return lights.node

    rep.randomizer.register(randomize_lights)


def simulate_falling_objects(prim, num_sim_steps=250, num_boxes=50):
    # Create a simulation ready world
    world = World(physics_dt=1.0 / 90.0, stage_units_in_meters=1.0)

    # Choose a random spawn offset relative to the given prim
    prim_tf = omni.usd.get_world_transform_matrix(prim)
    spawn_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(random.uniform(-0.5, 0.5), random.uniform(3, 3.5), 0))
    spawn_pos_gf = (spawn_offset_tf * prim_tf).ExtractTranslation()

    # Spawn pallet prim
    pallet_prim_name = "SimulatedPallet"
    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/{pallet_prim_name}",
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Get the height of the pallet
    bb_cache = create_bbox_cache()
    curr_spawn_height = bb_cache.ComputeLocalBound(pallet_prim).GetRange().GetSize()[2] * 1.1

    # Wrap the pallet prim into a rigid prim to be able to simulate it
    pallet_rigid_prim = RigidPrim(
        prim_path=str(pallet_prim.GetPrimPath()),
        name=pallet_prim_name,
        position=spawn_pos_gf + Gf.Vec3d(0, 0, curr_spawn_height),
    )

    # Make sure physics are enabled on the rigid prim
    pallet_rigid_prim.enable_rigid_body_physics()


    # Register rigid prim with the scene
    world.scene.add(pallet_rigid_prim)

    # Spawn boxes falling on the pallet
    for i in range(num_boxes):
        # Spawn box prim
        cardbox_prim_name = f"SimulatedCardbox_{i}"
        box_prim = prims.create_prim(
            prim_path=f"{SCOPE_NAME}/{cardbox_prim_name}",
            usd_path=prefix_with_isaac_asset_server(CARDBOX_URL),
            semantic_label="Cardbox",
        )

        # Add the height of the box to the current spawn height
        curr_spawn_height += bb_cache.ComputeLocalBound(box_prim).GetRange().GetSize()[2] * 1.1

        # Wrap the cardbox prim into a rigid prim to be able to simulate it
        box_rigid_prim = RigidPrim(
            prim_path=str(box_prim.GetPrimPath()),
            name=cardbox_prim_name,
            position=spawn_pos_gf + Gf.Vec3d(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2), curr_spawn_height),
            orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        )

        # Make sure physics are enabled on the rigid prim
        box_rigid_prim.enable_rigid_body_physics()

        # Register rigid prim with the scene
        world.scene.add(box_rigid_prim)

    # Reset world after adding simulated assets for physics handles to be propagated properly
    world.reset()

    # Simulate the world for the given number of steps or until the highest box stops moving
    last_box = world.scene.get_object(f"SimulatedCardbox_{num_boxes - 1}")
    for i in range(num_sim_steps):
        world.step(render=False)
        if last_box and np.linalg.norm(last_box.get_linear_velocity()) < 0.001:
            print(f"Simulation stopped after {i} steps")
            break


# Starts replicator and waits until all data was successfully written
def run_orchestrator():
    rep.orchestrator.run()

    # Wait until started
    while not rep.orchestrator.get_is_started():
        simulation_app.update()

    # Wait until stopped
    while rep.orchestrator.get_is_started():
        simulation_app.update()

    rep.BackendDispatch.wait_until_done()
    rep.orchestrator.stop()





def register_color_randomizer(prim_path):
    prim = rep.get.prims(semantics=[('class', 'Forklift'), ('class', 'Pallet'), ('class', 'Cardbox')])
    print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
    print("-------------------------------------------------------------")
    print("inspect.signature(rep.create.material_omnipbr): ", inspect.signature(rep.create.material_omnipbr))
    print("-------------------------------------------------------------")
    print("dir(rep.create): ", dir(rep.create))
    print("-------------------------------------------------------------")
    print("list(rep.create.__dict__.keys()): ", list(rep.create.__dict__.keys()))
    print("-------------------------------------------------------------")
    def randomize_color():
        mats = rep.create.material_omnipbr(
            metallic=rep.distribution.uniform(0.0, 1.0),
            roughness=rep.distribution.uniform(0.0, 1.0),
            diffuse=rep.distribution.uniform((0, 0, 0), (1, 1, 1)),
            specular=rep.distribution.uniform(0.0, 1.0), 
            count=1000,
        )
        with prim:
            rep.randomizer.materials(mats)
        #rep.randomizer.materials(mats)
        # return prims.node
        return prim.node

    rep.randomizer.register(randomize_color)

def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)



with rep.trigger.on_frame(interval=2, rt_subframes=16):
    #rep.randomizer.randomize_floor_textures()
    # Spawn a new forklift at a random pose
    forklift_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Forklift",
        position=(random.uniform(-20, -2), random.uniform(-1, 3), 0),
        orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        usd_path=prefix_with_isaac_asset_server(FORKLIFT_URL),
        semantic_label="Forklift",
    )
    
    # forklift_prim type:  <class 'pxr.Usd.Prim'>
    
    
    # forklift_rep = rep.get.prims(forklift_prim)
    # with forklift_rep:
    #     rep.randomizer.texture(textures=forklift_textures)


    print("forklift prim: ", forklift_prim)
    # # Spawn a new cone at a random pose
    
   

    # Spawn the pallet in front of the forklift with a random offset on the Y axis
    forklift_tf = omni.usd.get_world_transform_matrix(forklift_prim)
    pallet_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(0, random.uniform(-1.2, -2.4), 0))
    pallet_pos_gf = (pallet_offset_tf * forklift_tf).ExtractTranslation()
    forklift_quat_gf = forklift_tf.ExtractRotation().GetQuaternion()
    forklift_quat_xyzw = (forklift_quat_gf.GetReal(), *forklift_quat_gf.GetImaginary())

    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Pallet",
        position=pallet_pos_gf,
        orientation=forklift_quat_xyzw,
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Simulate dropping objects on a pile behind the forklift
    simulate_falling_objects(forklift_prim)

    # Register randomizers

    register_scatter_boxes(pallet_prim)

    #register_cone_placement(forklift_prim, pallet_prim)
    #register_pallet2_placement(forklift_prim, pallet_prim)
    register_lights_placement(forklift_prim, pallet_prim)
    register_color_randomizer(pallet_prim)


    # Spawn a camera in the driver's location looking at the pallet
    foklift_pos_gf = forklift_tf.ExtractTranslation()
    driver_cam_pos_gf = foklift_pos_gf + Gf.Vec3d(0.0, 0.0, 1.9)
    rotate_180_on_y_quat_gf = Gf.Quatf(0, 0, 1, 0)
    look_at_pallet_quat_gf = lookat_to_quatf(driver_cam_pos_gf, pallet_pos_gf, (0, 0, 1)) * rotate_180_on_y_quat_gf
    look_at_pallet_xyzw = (look_at_pallet_quat_gf.GetReal(), *look_at_pallet_quat_gf.GetImaginary())

    driver_cam_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/DriverCamera",
        prim_type="Camera",
        position=driver_cam_pos_gf,
        orientation=look_at_pallet_xyzw,
        attributes={"focusDistance": 400, "focalLength": 24, "clippingRange": (0.1, 10000000)},
    )

    # Camera looking at the pallet
    pallet_cam = rep.create.camera()


    # Top View Camera 
    # Camera looking at the forklift from a top view with large min clipping to see the scene through the ceiling
    top_view_cam = rep.create.camera(clipping_range=(6.0, 1000000.0))

    # TODO: access the current frame number 
    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
    
        rep.randomizer.randomize_lights()
        rep.randomizer.randomize_color()
        # rep.randomizer.randomize_floor_textures()
        pos_min = (pallet_pos_gf[0] - 2, pallet_pos_gf[1] - 2, 2)
        pos_max = (pallet_pos_gf[0] + 2, pallet_pos_gf[1] + 2, 4)
        with pallet_cam:
            rep.modify.pose(position=rep.distribution.uniform(pos_min, pos_max), look_at=str(pallet_prim.GetPrimPath()))
        
        with top_view_cam:
            rep.modify.pose(
                position=rep.distribution.uniform(
                    (foklift_pos_gf[0], foklift_pos_gf[1], 9), (foklift_pos_gf[0], foklift_pos_gf[1], 11)
                ),
                rotation=rep.distribution.uniform((0, -90, 0), (0, -90, 180)),
            )


    if os.path.exists(os.getcwd() + '/_output_headless'):
        shutil.rmtree(os.getcwd() + '/_output_headless', ignore_errors=False, onerror=None)
    


    

    #Basic Writer
    # Initialize and attach writer
    writer = rep.WriterRegistry.get("BasicWriter")
    print("***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************")
    output_directory = os.getcwd() + "/_output_headless"
    print("Outputting data to ", output_directory)
    writer.initialize(
        output_dir=output_directory,
        rgb=True,
        bounding_box_2d_tight=True,
        semantic_segmentation=True,
        instance_segmentation=True,
        distance_to_image_plane=True,
        bounding_box_3d=True,
        occlusion=True,
        normals=True,
    )
  
    RESOLUTION = (CONFIG["width"], CONFIG["height"])
    driver_rp = rep.create.render_product(str(driver_cam_prim.GetPrimPath()), RESOLUTION)
    pallet_rp = rep.create.render_product(pallet_cam, RESOLUTION)
    forklift_rp = rep.create.render_product(top_view_cam, RESOLUTION)
    writer.attach([driver_rp, forklift_rp, pallet_rp])

    run_orchestrator()
    simulation_app.update()


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        carb.log_error(f"Exception: {e}")
        traceback.print_exc()
    finally:
        simulation_app.close()


Please let me know if you are not able to run it?

This is how I run it:

(isaac-sim) mona@ard-gpu-01:~/.local/share/ov/pkg/isaac_sim-2022.2.0$ ./python.sh ~/floor_randomizer/floor_color_randomizer.py 

Fixed Randomizing the color of a prim without using a registered function - #2 by mona.jalal

Thanks a lot @ahaidu and @toni.sm

Here is the script which should be working after some minor changes (too many boxes to scatter without avoiding self collision, wrong indentation, loop running forver, etc.):

# Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

"""Generate offline synthetic dataset
"""
from omni.isaac.kit import SimulationApp
import os
import glob
import shutil
import traceback

# Set rendering parameters and create an instance of kit
CONFIG = {"renderer": "RayTracedLighting", "headless": True, "width": 1024, "height": 1024, "num_frames": 5}
simulation_app = SimulationApp(launch_config=CONFIG)

ENV_URL = "/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"
FORKLIFT_URL = "/Isaac/Props/Forklift/forklift.usd"
PALLET_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_01.usd"
PALLET_2_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_PaletteA_02.usd"
CARDBOX_URL = "/Isaac/Environments/Simple_Warehouse/Props/SM_CardBoxD_04.usd"
CONE_URL = "/Isaac/Environments/Simple_Warehouse/Props/S_TrafficCone.usd"
SCOPE_NAME = "/MyScope"


import carb
import random
import math
import numpy as np
from pxr import UsdGeom, Usd, Gf, UsdPhysics, PhysxSchema

import inspect

import omni.usd
from omni.isaac.core import World
from omni.isaac.core.utils import prims
from omni.isaac.core.prims import RigidPrim
from omni.isaac.core.utils.nucleus import get_assets_root_path
from omni.isaac.core.utils.stage import get_current_stage, open_stage
from omni.isaac.core.utils.rotations import euler_angles_to_quat, quat_to_euler_angles, lookat_to_quatf
from omni.isaac.core.utils.bounds import compute_combined_aabb, create_bbox_cache
from omni.isaac.core.utils.random import get_random_world_pose_in_view
from omni.replicator.isaac.scripts.writers import DOPEWriter
from omni.syntheticdata import SyntheticData
from omni.isaac.core.prims import XFormPrim



import omni.replicator.core as rep





# Helper function to find the assets server
def prefix_with_isaac_asset_server(relative_path):
    assets_root_path = get_assets_root_path()
    if assets_root_path is None:
        raise Exception("Nucleus server not found, could not access Isaac Sim assets folder")
    return assets_root_path + relative_path


# Increase subframes if shadows/ghosting appears of moving objects
# See known issues: https://docs.omniverse.nvidia.com/prod_extensions/prod_extensions/ext_replicator.html#known-issues
rep.settings.carb_settings("/omni/replicator/RTSubframes", 2)


world = World()
world.reset()


print("URL cardbox: ", prefix_with_isaac_asset_server(CARDBOX_URL))



# Randomize boxes materials and their location on the surface of the given prim
def register_scatter_boxes(prim):
    # Calculate the bounds of the prim to create a scatter plane of its size
    bb_cache = create_bbox_cache()
    bbox3d_gf = bb_cache.ComputeLocalBound(prim)
    prim_tf_gf = omni.usd.get_world_transform_matrix(prim)

    # Calculate the bounds of the prim
    bbox3d_gf.Transform(prim_tf_gf)
    range_size = bbox3d_gf.GetRange().GetSize()

    # Get the quaterion of the prim in xyzw format from usd
    prim_quat_gf = prim_tf_gf.ExtractRotation().GetQuaternion()
    prim_quat_xyzw = (prim_quat_gf.GetReal(), *prim_quat_gf.GetImaginary())

    # Create a plane on the pallet to scatter the boxes on
    plane_scale = (range_size[0] * 0.8, range_size[1] * 0.8, 1)
    plane_pos_gf = prim_tf_gf.ExtractTranslation() + Gf.Vec3d(0, 0, range_size[2])
    plane_rot_euler_deg = quat_to_euler_angles(np.array(prim_quat_xyzw), degrees=True)
    scatter_plane = rep.create.plane(
        scale=plane_scale, position=plane_pos_gf, rotation=plane_rot_euler_deg, visible=False
    )

    cardbox_mats = [
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_PaperNotes_01.mdl"),
        prefix_with_isaac_asset_server("/Isaac/Environments/Simple_Warehouse/Materials/MI_CardBoxB_05.mdl"),
    ]

    def scatter_boxes():
        cardboxes = rep.create.from_usd(
            prefix_with_isaac_asset_server(CARDBOX_URL), semantics=[("class", "Cardbox")], count=3
        )
        # type of cardboxes:  <class 'omni.replicator.core.scripts.utils.utils.ReplicatorItem'>
        with cardboxes:
            rep.randomizer.scatter_2d(scatter_plane, check_for_collisions=True)
            rep.randomizer.materials(cardbox_mats)
        return cardboxes.node

    rep.randomizer.register(scatter_boxes)
    


# Randomize lights around the scene
def register_lights_placement(forklift_prim, pallet_prim):
    bb_cache = create_bbox_cache()
    combined_range_arr = compute_combined_aabb(bb_cache, [forklift_prim.GetPrimPath(), pallet_prim.GetPrimPath()])
    pos_min = (combined_range_arr[0], combined_range_arr[1], 6)
    pos_max = (combined_range_arr[3], combined_range_arr[4], 7)

    def randomize_lights():
        lights = rep.create.light(
            light_type="Sphere",
            color=rep.distribution.uniform((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)),
            intensity=rep.distribution.uniform(500, 3000),
            position=rep.distribution.uniform(pos_min, pos_max),
            scale=rep.distribution.uniform(1, 20),
            count=3,
        )
        return lights.node

    rep.randomizer.register(randomize_lights)


def simulate_falling_objects(prim, num_sim_steps=250, num_boxes=50):
    # Create a simulation ready world
    world = World(physics_dt=1.0 / 90.0, stage_units_in_meters=1.0)

    # Choose a random spawn offset relative to the given prim
    prim_tf = omni.usd.get_world_transform_matrix(prim)
    spawn_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(random.uniform(-0.5, 0.5), random.uniform(3, 3.5), 0))
    spawn_pos_gf = (spawn_offset_tf * prim_tf).ExtractTranslation()

    # Spawn pallet prim
    pallet_prim_name = "SimulatedPallet"
    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/{pallet_prim_name}",
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Get the height of the pallet
    bb_cache = create_bbox_cache()
    curr_spawn_height = bb_cache.ComputeLocalBound(pallet_prim).GetRange().GetSize()[2] * 1.1

    # Wrap the pallet prim into a rigid prim to be able to simulate it
    pallet_rigid_prim = RigidPrim(
        prim_path=str(pallet_prim.GetPrimPath()),
        name=pallet_prim_name,
        position=spawn_pos_gf + Gf.Vec3d(0, 0, curr_spawn_height),
    )

    # Make sure physics are enabled on the rigid prim
    pallet_rigid_prim.enable_rigid_body_physics()


    # Register rigid prim with the scene
    world.scene.add(pallet_rigid_prim)

    # Spawn boxes falling on the pallet
    for i in range(num_boxes):
        # Spawn box prim
        cardbox_prim_name = f"SimulatedCardbox_{i}"
        box_prim = prims.create_prim(
            prim_path=f"{SCOPE_NAME}/{cardbox_prim_name}",
            usd_path=prefix_with_isaac_asset_server(CARDBOX_URL),
            semantic_label="Cardbox",
        )

        # Add the height of the box to the current spawn height
        curr_spawn_height += bb_cache.ComputeLocalBound(box_prim).GetRange().GetSize()[2] * 1.1

        # Wrap the cardbox prim into a rigid prim to be able to simulate it
        box_rigid_prim = RigidPrim(
            prim_path=str(box_prim.GetPrimPath()),
            name=cardbox_prim_name,
            position=spawn_pos_gf + Gf.Vec3d(random.uniform(-0.2, 0.2), random.uniform(-0.2, 0.2), curr_spawn_height),
            orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        )

        # Make sure physics are enabled on the rigid prim
        box_rigid_prim.enable_rigid_body_physics()

        # Register rigid prim with the scene
        world.scene.add(box_rigid_prim)

    # Reset world after adding simulated assets for physics handles to be propagated properly
    world.reset()

    # Simulate the world for the given number of steps or until the highest box stops moving
    last_box = world.scene.get_object(f"SimulatedCardbox_{num_boxes - 1}")
    for i in range(num_sim_steps):
        world.step(render=False)
        if last_box and np.linalg.norm(last_box.get_linear_velocity()) < 0.001:
            print(f"Simulation stopped after {i} steps")
            break


# Starts replicator and waits until all data was successfully written
def run_orchestrator():
    rep.orchestrator.run()

    # Wait until started
    while not rep.orchestrator.get_is_started():
        simulation_app.update()

    # Wait until stopped
    while rep.orchestrator.get_is_started():
        simulation_app.update()

    rep.BackendDispatch.wait_until_done()
    rep.orchestrator.stop()





def register_color_randomizer(prim_path):
    prim = rep.get.prims(semantics=[('class', 'Forklift'), ('class', 'Pallet'), ('class', 'Cardbox')])
    print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
    print("-------------------------------------------------------------")
    print("inspect.signature(rep.create.material_omnipbr): ", inspect.signature(rep.create.material_omnipbr))
    print("-------------------------------------------------------------")
    print("dir(rep.create): ", dir(rep.create))
    print("-------------------------------------------------------------")
    print("list(rep.create.__dict__.keys()): ", list(rep.create.__dict__.keys()))
    print("-------------------------------------------------------------")
    def randomize_color():
        mats = rep.create.material_omnipbr(
            metallic=rep.distribution.uniform(0.0, 1.0),
            roughness=rep.distribution.uniform(0.0, 1.0),
            diffuse=rep.distribution.uniform((0, 0, 0), (1, 1, 1)),
            specular=rep.distribution.uniform(0.0, 1.0), 
            count=1000,
        )
        with prim:
            rep.randomizer.materials(mats)
        #rep.randomizer.materials(mats)
        # return prims.node
        return prim.node

    rep.randomizer.register(randomize_color)

def main():
    # Open the environment in a new stage
    print(f"Loading Stage {ENV_URL}")
    open_stage(prefix_with_isaac_asset_server(ENV_URL))

    # Create a custom scope for newly added prims
    stage = get_current_stage()
    scope = UsdGeom.Scope.Define(stage, SCOPE_NAME)
    floor_prim = stage.GetPrimAtPath('/Root/SM_floor30/SM_floor02')
    # wrap your prim to a OG node for OG randomization
    floor_node = rep.get.prim_at_path(str(floor_prim.GetPath()))
    def randomize_floor_textures():
        with floor_node:
            rep.randomizer.texture(
                textures=[
                    prefix_with_isaac_asset_server("/Isaac/Samples/DR/Materials/Textures/checkered_color.png")
                    # "omniverse://localhost/NVIDIA/Materials/Base/Wood/Oak/Oak_BaseColor.png",
                    # "omniverse://localhost/NVIDIA/Materials/Base/Wood/Ash/Ash_BaseColor.png",
                ],
                texture_rotate=rep.distribution.uniform(80, 95),
            )
        return floor_node.node
    rep.randomizer.register(randomize_floor_textures)



    with rep.trigger.on_frame(interval=2, num_frames=CONFIG["num_frames"], rt_subframes=16):
        rep.randomizer.randomize_floor_textures()
    
    # Spawn a new forklift at a random pose
    forklift_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Forklift",
        position=(random.uniform(-20, -2), random.uniform(-1, 3), 0),
        orientation=euler_angles_to_quat([0, 0, random.uniform(0, math.pi)]),
        usd_path=prefix_with_isaac_asset_server(FORKLIFT_URL),
        semantic_label="Forklift",
    )
    
    # forklift_prim type:  <class 'pxr.Usd.Prim'>
    
    
    # forklift_rep = rep.get.prims(forklift_prim)
    # with forklift_rep:
    #     rep.randomizer.texture(textures=forklift_textures)


    print("forklift prim: ", forklift_prim)
    # # Spawn a new cone at a random pose
    
   

    # Spawn the pallet in front of the forklift with a random offset on the Y axis
    forklift_tf = omni.usd.get_world_transform_matrix(forklift_prim)
    pallet_offset_tf = Gf.Matrix4d().SetTranslate(Gf.Vec3d(0, random.uniform(-1.2, -2.4), 0))
    pallet_pos_gf = (pallet_offset_tf * forklift_tf).ExtractTranslation()
    forklift_quat_gf = forklift_tf.ExtractRotation().GetQuaternion()
    forklift_quat_xyzw = (forklift_quat_gf.GetReal(), *forklift_quat_gf.GetImaginary())

    pallet_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/Pallet",
        position=pallet_pos_gf,
        orientation=forklift_quat_xyzw,
        usd_path=prefix_with_isaac_asset_server(PALLET_URL),
        semantic_label="Pallet",
    )

    # Simulate dropping objects on a pile behind the forklift
    simulate_falling_objects(forklift_prim)

    # Register randomizers

    register_scatter_boxes(pallet_prim)

    #register_cone_placement(forklift_prim, pallet_prim)
    #register_pallet2_placement(forklift_prim, pallet_prim)
    register_lights_placement(forklift_prim, pallet_prim)
    register_color_randomizer(pallet_prim)


    # Spawn a camera in the driver's location looking at the pallet
    foklift_pos_gf = forklift_tf.ExtractTranslation()
    driver_cam_pos_gf = foklift_pos_gf + Gf.Vec3d(0.0, 0.0, 1.9)
    rotate_180_on_y_quat_gf = Gf.Quatf(0, 0, 1, 0)
    look_at_pallet_quat_gf = lookat_to_quatf(driver_cam_pos_gf, pallet_pos_gf, (0, 0, 1)) * rotate_180_on_y_quat_gf
    look_at_pallet_xyzw = (look_at_pallet_quat_gf.GetReal(), *look_at_pallet_quat_gf.GetImaginary())

    driver_cam_prim = prims.create_prim(
        prim_path=f"{SCOPE_NAME}/DriverCamera",
        prim_type="Camera",
        position=driver_cam_pos_gf,
        orientation=look_at_pallet_xyzw,
        attributes={"focusDistance": 400, "focalLength": 24, "clippingRange": (0.1, 10000000)},
    )

    # Camera looking at the pallet
    pallet_cam = rep.create.camera()


    # Top View Camera 
    # Camera looking at the forklift from a top view with large min clipping to see the scene through the ceiling
    top_view_cam = rep.create.camera(clipping_range=(6.0, 1000000.0))

    # TODO: access the current frame number 
    with rep.trigger.on_frame(num_frames=CONFIG["num_frames"]):
        rep.randomizer.scatter_boxes()
    
        rep.randomizer.randomize_lights()
        rep.randomizer.randomize_color()
        # rep.randomizer.randomize_floor_textures()
        pos_min = (pallet_pos_gf[0] - 2, pallet_pos_gf[1] - 2, 2)
        pos_max = (pallet_pos_gf[0] + 2, pallet_pos_gf[1] + 2, 4)
        with pallet_cam:
            rep.modify.pose(position=rep.distribution.uniform(pos_min, pos_max), look_at=str(pallet_prim.GetPrimPath()))
        
        with top_view_cam:
            rep.modify.pose(
                position=rep.distribution.uniform(
                    (foklift_pos_gf[0], foklift_pos_gf[1], 9), (foklift_pos_gf[0], foklift_pos_gf[1], 11)
                ),
                rotation=rep.distribution.uniform((0, -90, 0), (0, -90, 180)),
            )


    if os.path.exists(os.getcwd() + '/_output_headless'):
        shutil.rmtree(os.getcwd() + '/_output_headless', ignore_errors=False, onerror=None)
    


    

    #Basic Writer
    # Initialize and attach writer
    writer = rep.WriterRegistry.get("BasicWriter")
    print("***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************")
    output_directory = os.getcwd() + "/_output_headless"
    print("Outputting data to ", output_directory)
    writer.initialize(
        output_dir=output_directory,
        rgb=True,
        bounding_box_2d_tight=True,
        semantic_segmentation=True,
        instance_segmentation=True,
        distance_to_image_plane=True,
        bounding_box_3d=True,
        occlusion=True,
        normals=True,
    )
  
    RESOLUTION = (CONFIG["width"], CONFIG["height"])
    driver_rp = rep.create.render_product(str(driver_cam_prim.GetPrimPath()), RESOLUTION)
    pallet_rp = rep.create.render_product(pallet_cam, RESOLUTION)
    forklift_rp = rep.create.render_product(top_view_cam, RESOLUTION)
    writer.attach([driver_rp, forklift_rp, pallet_rp])

    # TODO: access the current frame number 
    # Run this instead of run_orchestrator():
    # for i in range(CONFIG["num_frames"]):
    #     rep.orchestrator.step()
    #     print("Frame: ", i)
    run_orchestrator()       

    simulation_app.update()


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        carb.log_error(f"Exception: {e}")
        traceback.print_exc()
    finally:
        simulation_app.close()
1 Like

Thank you so much @ahaidu for showing how to get the current frame ID

Module omni.replicator.core.ogn.python._impl.nodes.OgnSemanticSegmentation load on device 'cuda:0' took 3.09 ms
Frame:  0
Frame:  1
Frame:  2
Frame:  3
Frame:  4
Frame:  5
Frame:  6
Frame:  7
Frame:  8
Frame:  9
2023-02-21 15:44:58 [98,823ms] [Warning] [carb] Plugin interface for a client: omni.hydratexture.plugin was already released.
2023-02-21 15:44:58 [98,823ms] [Warning] [carb] Plugin interface for a client: omni.hydratexture.plugin was already released.
[98.839s] Simulation App Shutting Down

When you say collision, do you mean this?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.