Keeping cardboard Box on the ground

Hello friends, i was trying to create Synthetic data for 3d detection of cardboard boxes. when i randomize, the bottom point of the box is going under the ground or pallet. It does not stay on the pallet or on the ground all the time. how can i fix this? Please help. Thanks in advance. Code is below

import omni.replicator.core as rep
import omni.usd
import random
from pxr import Usd, UsdGeom, Gf, Sdf
import asyncio

Load your scene

output_dir = r"C:\Users\shaji\Downloads\output_data"
usd_path = r"C:\Users\shaji\Downloads\try.usd"
omni.usd.get_context().open_stage(usd_path)
stage = omni.usd.get_context().get_stage()

def check_prim(path):
prim = stage.GetPrimAtPath(path)
if not prim.IsValid():
print(f"Error: Prim at path {path} is invalid.“)
else:
print(f"Prim at path {path} is valid.”)
return prim

Object references (box, lights, cameras)

box_prim_path = Sdf.Path(“/Cardbox_C1”)
box_prim = check_prim(box_prim_path)

dome_light_path = Sdf.Path(“/World/DomeLight”)
dome_light = check_prim(dome_light_path)

dist_light_path = Sdf.Path(“/World/DistantLight”)
dist_light = check_prim(dist_light_path)

camera_paths = [
Sdf.Path(“/Camera_01”), # north
Sdf.Path(“/Camera_02”), # east
Sdf.Path(“/Camera_03”), # west
Sdf.Path(“/Camera_04”), # south
Sdf.Path(“/Camera_05”) # top
]
cameras = [check_prim(path) for path in camera_paths]

def get_bounding_box(prim):
if not prim.IsValid():
raise ValueError(f"Invalid prim: {prim.GetPath()}")
bbox_cache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_])
bbox = bbox_cache.ComputeWorldBound(prim)
return bbox

def get_bounding_box_center(prim):
bbox = get_bounding_box(prim)
center = bbox.GetRange().GetMidpoint()
print(f"Bounding box center for {prim.GetPath()} is {center}")
return center

def get_bounding_box_size(prim):
bbox = get_bounding_box(prim)
size = bbox.GetRange().GetSize()
print(f"Bounding box size for {prim.GetPath()} is {size}")
return size

def randomize_scene():
box_size = get_bounding_box_size(box_prim)

# Randomize box size keeping the typical logistic box ratio
scale_factor = random.uniform(0.5, 1.5)
scale_value = (scale_factor, scale_factor, scale_factor)
print(f"Scale value: {scale_value}")

# Randomize box orientation
rotation_x = random.uniform(-180, 180)
rotation_y = random.uniform(-180, 180)
rotation_z = random.uniform(-180, 180)
rotation_value = (rotation_x, rotation_y, rotation_z)
print(f"Rotation value: {rotation_value}")

# Apply new size and orientation to the box
rep.modify.pose(input_prims=box_prim, scale=scale_value, rotation=rotation_value)

# Randomize dome light
dome_light_intensity = random.uniform(500, 1500)
dome_light_temperature = random.uniform(3000, 6500)
print(f"Dome light - intensity: {dome_light_intensity}, temperature: {dome_light_temperature}")

rep.modify.attribute(name='inputs:intensity', value=dome_light_intensity, input_prims=dome_light)
rep.modify.attribute(name='inputs:temperature', value=dome_light_temperature, input_prims=dome_light)

# Randomize distant light
dist_light_intensity = random.uniform(2000, 4000)
dist_light_temperature = random.uniform(3000, 6500)
print(f"Distant light - intensity: {dist_light_intensity}, temperature: {dist_light_temperature}")

rep.modify.attribute(name='inputs:intensity', value=dist_light_intensity, input_prims=dist_light)
rep.modify.attribute(name='inputs:temperature', value=dist_light_temperature, input_prims=dist_light)

render_product_dict = {}
render_products =
for idx, camera_path in enumerate(camera_paths):
pos_name = f"camera_{idx+1}"
render_product = rep.create.render_product(camera_path, resolution=(1280, 720))
render_product_dict[pos_name] = render_product
render_products.append(render_product)

Create a basic writer

writer = rep.WriterRegistry.get(“BasicWriter”)
writer.initialize(output_dir=output_dir, rgb=True, bounding_box_2d_tight=True, bounding_box_2d_loose=True, bounding_box_3d=True, camera_params=True)
writer.attach(render_products)

Attach the necessary annotators

rep.AnnotatorRegistry.get_annotator(“bounding_box_2d_tight”).attach(render_products)
rep.AnnotatorRegistry.get_annotator(“bounding_box_2d_loose”).attach(render_products)
rep.AnnotatorRegistry.get_annotator(“bounding_box_3d”).attach(render_products)
rep.AnnotatorRegistry.get_annotator(“camera_params”).attach(render_products)
rep.AnnotatorRegistry.get_annotator(“DepthLinearized”).attach(render_products)

async def preview_scene(num_previews=1):
for _ in range(num_previews):
for pos_name, render_product in render_product_dict.items():
randomize_scene()
await rep.orchestrator.step_async()

Preview the scene

await preview_scene(num_previews=1)

Once satisfied with the preview, proceed to create the dataset

with rep.trigger.on_frame(num_frames=100): # Capture 100 frames
for pos_name, render_product in render_product_dict.items():
randomize_scene()

rep.orchestrator.run()