Isaac Sim Replicator doesn't work with custom numpy randomization function

Hi I’m trying to create a script which uses the replicator to generate a set of images where the camera is stationary and pointing in random directions. The main body of this script is shown below:

import numpy as np
from isaacsim import SimulationApp

simulation_app = SimulationApp(launch_config={"headless": True})

import omni.replicator.core as rep
# more imports...

rep.settings.carb_settings("/omni/replicator/RTSubframes", 10)

# Setting up scene...

with rep.new_layer():
    camera_position = np.array([1, 2, 3])
    camera = rep.create.camera(position=tuple(camera_position))
    render_product = rep.create.render_product(camera, (1440, 1440))
    with rep.trigger.on_frame(max_execs=10):
        with camera:
            rep.modify.pose(
                look_at=tuple(camera_position + get_random_unit_sphere_vec())
            )
    writer = rep.WriterRegistry.get("BasicWriter")
    writer.initialize(output_dir="_output", rgb=True)
    writer.attach([render_product])

    rep.orchestrator.run()
    while not rep.orchestrator.get_is_started():
        simulation_app.update()
    while rep.orchestrator.get_is_started():
        simulation_app.update()
    rep.BackendDispatch.wait_until_done()
    rep.orchestrator.stop()
    simulation_app.close()

The randomization function looks like this and just finds a unit vec in a random direction to make the look_at direction random:

def get_random_unit_sphere_vec():
    rng = np.random.default_rng()
    vec = rng.standard_normal(3)
    # To avoid floating point error, make sure vec is not too short
    while np.linalg.norm(vec) < 0.0001:
        vec = rng.standard_normal(3)
    return vec / np.linalg.norm(vec)

When I run this script, it works as expected for the first generated image but from then on, all the other nine images are in the exact same orientation as the first one instead of each image being in a new random direction.

I suspect that the get_random_unit_sphere_vec function is only being called once and the result of that is being sent to the randomizer but I have no idea how this all works under the hood so an explanation of what is going wrong would be much appreciated.

Hi there,

the replicator graph is lazily generated once, then at runtime the graph will execute and generate the randomizations. Meaning get_random_unit_sphere_vec will only get called once and used as a constant in the graph.

We have a tutorial on how to wrap a custom randomizer as replicator omnigraph node:

Best,
Andrei

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