Hi,
I have been trying for sometime to generate a simple cube on a plane in a trivial scene in a headless setup, basically a “Hello World” to help me better understand the platform… A jumping off point to learn more… I have followed several tutorials and can now generate images, but they are always all WHITE, GRAY, or BLACK (depending on my lighting) but I never can see the cube. I am def. doing something wrong, but I can’t figure out what. It would be greatly appreciated if someone could take a look at this code, and even run it on their system, to see help me rule-out environment issues. Or failing that, point me to a better tutorial than the one’s I have been attempting to follow :)
Info: I am running headless on an RTX3060, by no means is this system a beast but it’s more than enough for this exercise. I am attempting to generate a few images (not 10’s or 100’s of thousands… the demo code generates 10). I am using the NVIDIA-supplied Docker base image (nvcr.io/nvidia/isaac-sim:2023.1.1) with the “docker run -it --gpus all --privileged” correctly configured to allow access to the GPU etc… Below is the code, any pointers would be much appreciated as I have spent WAY to long on this and need a second set of eyes.
Thank you!
from omni.isaac.kit import SimulationApp
import math
import os
# I have tried both RayTracedLighting and HydraRender"
#
#simulation_app = SimulationApp({
# "headless": True,
# "renderer": "RayTracedLighting",
# "useExtension": True,
#})
simulation_app = SimulationApp({
"headless": True,
"renderer": "HydraRenderer",
"useExtension": True,
})
import omni.kit.app
import omni.replicator.core as rep
kit = omni.kit.app.get_app()
kit.get_extension_manager().set_extension_enabled_immediate("omni.replicator.core", True)
def main():
OUTPUT_DIR = "/workspace/reach_ws/outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)
rep.new_layer()
# Create cube
cube = rep.create.cube(position=(0, 0, 0.05), scale=(0.5, 0.5, 0.5))
print(f"Cube: {cube}, type: {type(cube)}")
# Create material
material = rep.create.material_omnipbr(diffuse=(1.0, 0.0, 0.0)) # Red
# Bind material to cube using known path
with cube:
rep.modify.attribute("material:binding", material)
# Add ground plane
rep.create.plane(scale=(1, 1, 1), position=(0, 0, 0))
# Add lights (Dome and distant)
rep.create.light(
light_type="dome", # dome is good for soft environment light
intensity=10000, # increase intensity a lot to start
rotation=(45, 0, 0) # tilt so light comes from above
)
rep.create.light(
light_type="distant",
intensity=15000,
rotation=(-45, 0, 0)
)
# Add camera
camera = rep.create.camera(position=(0, -0.3, 0.25), rotation=(-33, 0, 0))
# Render product
render_product = rep.create.render_product(camera, (640, 480))
# Writer setup
writer = rep.WriterRegistry.get("BasicWriter")
writer.initialize(output_dir=OUTPUT_DIR, rgb=True)
writer.attach([render_product])
# Let it warm up and render
rep.orchestrator.run()
for _ in range(10):
rep.orchestrator.step()
print(f"Image saved to {OUTPUT_DIR}/replicator_0/RenderProduct_0/rgb_00{_}.png")
writer.detach()
print(f"Render complete")
simulation_app.close()
if __name__ == "__main__":
main()